From 9cedb8bb69b89b0f0c529937247a6a80cabdbaec Mon Sep 17 00:00:00 2001 From: dim Date: Fri, 21 Mar 2014 17:53:59 +0000 Subject: MFC 261991: Upgrade our copy of llvm/clang to 3.4 release. This version supports all of the features in the current working draft of the upcoming C++ standard, provisionally named C++1y. The code generator's performance is greatly increased, and the loop auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The PowerPC backend has made several major improvements to code generation quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ backends have all seen major feature work. Release notes for llvm and clang can be found here: MFC 262121 (by emaste): Update lldb for clang/llvm 3.4 import This commit largely restores the lldb source to the upstream r196259 snapshot with the addition of threaded inferior support and a few bug fixes. Specific upstream lldb revisions restored include: SVN git 181387 779e6ac 181703 7bef4e2 182099 b31044e 182650 f2dcf35 182683 0d91b80 183862 15c1774 183929 99447a6 184177 0b2934b 184948 4dc3761 184954 007e7bc 186990 eebd175 Sponsored by: DARPA, AFRL MFC 262186 (by emaste): Fix mismerge in r262121 A break statement was lost in the merge. The error had no functional impact, but restore it to reduce the diff against upstream. MFC 262303: Pull in r197521 from upstream clang trunk (by rdivacky): Use the integrated assembler by default on FreeBSD/ppc and ppc64. Requested by: jhibbits MFC 262611: Pull in r196874 from upstream llvm trunk: Fix a crash that occurs when PWD is invalid. MCJIT needs to be able to run in hostile environments, even when PWD is invalid. There's no need to crash MCJIT in this case. The obvious fix is to simply leave MCContext's CompilationDir empty when PWD can't be determined. This way, MCJIT clients, and other clients that link with LLVM don't need a valid working directory. If we do want to guarantee valid CompilationDir, that should be done only for clients of getCompilationDir(). This is as simple as checking for an empty string. The only current use of getCompilationDir is EmitGenDwarfInfo, which won't conceivably run with an invalid working dir. However, in the purely hypothetically and untestable case that this happens, the AT_comp_dir will be omitted from the compilation_unit DIE. This should help fix assertions occurring with ports-mgmt/tinderbox, when it is using jails, and sometimes invalidates clang's current working directory. Reported by: decke MFC 262809: Pull in r203007 from upstream clang trunk: Don't produce an alias between destructors with different calling conventions. Fixes pr19007. (Please note that is an LLVM PR identifier, not a FreeBSD one.) This should fix Firefox and/or libxul crashes (due to problems with regparm/stdcall calling conventions) on i386. Reported by: multiple users on freebsd-current PR: bin/187103 MFC 263048: Repair recognition of "CC" as an alias for the C++ compiler, since it was silently broken by upstream for a Windows-specific use-case. Apparently some versions of CMake still rely on this archaic feature... Reported by: rakuco MFC 263049: Garbage collect the old way of adding the libstdc++ include directories in clang's InitHeaderSearch.cpp. This has been superseded by David Chisnall's commit in r255321. Moreover, if libc++ is used, the libstdc++ include directories should not be in the search path at all. These directories are now only used if you pass -stdlib=libstdc++. --- contrib/llvm/tools/bugpoint/BugDriver.cpp | 4 +- contrib/llvm/tools/bugpoint/BugDriver.h | 4 +- contrib/llvm/tools/bugpoint/CrashDebugger.cpp | 20 +- contrib/llvm/tools/bugpoint/ExecutionDriver.cpp | 63 +- contrib/llvm/tools/bugpoint/ExtractFunction.cpp | 30 +- contrib/llvm/tools/bugpoint/FindBugs.cpp | 3 +- contrib/llvm/tools/bugpoint/Miscompilation.cpp | 101 +- contrib/llvm/tools/bugpoint/OptimizerDriver.cpp | 99 +- contrib/llvm/tools/bugpoint/ToolRunner.cpp | 201 +- contrib/llvm/tools/bugpoint/ToolRunner.h | 60 +- contrib/llvm/tools/bugpoint/bugpoint.cpp | 6 +- .../clang/include/clang-c/CXCompilationDatabase.h | 20 +- .../llvm/tools/clang/include/clang-c/CXString.h | 2 +- contrib/llvm/tools/clang/include/clang-c/Index.h | 70 +- .../tools/clang/include/clang/ARCMigrate/ARCMT.h | 2 + .../clang/include/clang/ARCMigrate/ARCMTActions.h | 6 +- .../clang/include/clang/ARCMigrate/FileRemapper.h | 1 - .../llvm/tools/clang/include/clang/AST/APValue.h | 7 + .../tools/clang/include/clang/AST/ASTConsumer.h | 21 + .../tools/clang/include/clang/AST/ASTContext.h | 310 ++- .../tools/clang/include/clang/AST/ASTDiagnostic.h | 2 +- .../llvm/tools/clang/include/clang/AST/ASTFwd.h | 28 + .../tools/clang/include/clang/AST/ASTImporter.h | 8 + .../llvm/tools/clang/include/clang/AST/ASTLambda.h | 80 + .../clang/include/clang/AST/ASTMutationListener.h | 17 + .../tools/clang/include/clang/AST/ASTTypeTraits.h | 387 ++- .../clang/include/clang/AST/ASTUnresolvedSet.h | 42 +- .../llvm/tools/clang/include/clang/AST/ASTVector.h | 55 +- contrib/llvm/tools/clang/include/clang/AST/Attr.h | 3 +- .../tools/clang/include/clang/AST/CXXInheritance.h | 4 +- .../tools/clang/include/clang/AST/CanonicalType.h | 2 +- .../llvm/tools/clang/include/clang/AST/CharUnits.h | 21 +- .../llvm/tools/clang/include/clang/AST/Comment.h | 20 +- .../clang/include/clang/AST/CommentCommandTraits.h | 5 + .../clang/include/clang/AST/CommentCommands.td | 11 + .../clang/include/clang/AST/CommentDiagnostic.h | 2 +- .../tools/clang/include/clang/AST/CommentParser.h | 6 +- .../tools/clang/include/clang/AST/CommentSema.h | 9 +- contrib/llvm/tools/clang/include/clang/AST/Decl.h | 367 ++- .../tools/clang/include/clang/AST/DeclAccessPair.h | 9 +- .../llvm/tools/clang/include/clang/AST/DeclBase.h | 163 +- .../llvm/tools/clang/include/clang/AST/DeclCXX.h | 1014 ++++---- .../clang/include/clang/AST/DeclContextInternals.h | 48 +- .../tools/clang/include/clang/AST/DeclFriend.h | 4 +- .../tools/clang/include/clang/AST/DeclLookups.h | 22 +- .../llvm/tools/clang/include/clang/AST/DeclObjC.h | 47 +- .../tools/clang/include/clang/AST/DeclOpenMP.h | 26 +- .../tools/clang/include/clang/AST/DeclTemplate.h | 691 +++++- .../clang/include/clang/AST/DeclarationName.h | 12 +- .../clang/include/clang/AST/EvaluatedExprVisitor.h | 2 +- contrib/llvm/tools/clang/include/clang/AST/Expr.h | 245 +- .../llvm/tools/clang/include/clang/AST/ExprCXX.h | 688 +++--- .../llvm/tools/clang/include/clang/AST/ExprObjC.h | 23 +- .../clang/include/clang/AST/ExternalASTSource.h | 7 +- .../tools/clang/include/clang/AST/GlobalDecl.h | 1 + .../clang/include/clang/AST/LambdaMangleContext.h | 38 - .../llvm/tools/clang/include/clang/AST/Mangle.h | 117 +- .../include/clang/AST/MangleNumberingContext.h | 59 + .../clang/include/clang/AST/NestedNameSpecifier.h | 6 +- .../llvm/tools/clang/include/clang/AST/ParentMap.h | 5 + .../tools/clang/include/clang/AST/PrettyPrinter.h | 13 +- .../tools/clang/include/clang/AST/RawCommentList.h | 31 +- .../tools/clang/include/clang/AST/RecordLayout.h | 55 +- .../clang/include/clang/AST/RecursiveASTVisitor.h | 330 ++- .../tools/clang/include/clang/AST/Redeclarable.h | 52 +- contrib/llvm/tools/clang/include/clang/AST/Stmt.h | 104 +- .../llvm/tools/clang/include/clang/AST/StmtCXX.h | 4 +- .../tools/clang/include/clang/AST/StmtIterator.h | 32 +- .../llvm/tools/clang/include/clang/AST/StmtObjC.h | 9 +- .../tools/clang/include/clang/AST/StmtOpenMP.h | 528 ++++ .../tools/clang/include/clang/AST/StmtVisitor.h | 36 + .../tools/clang/include/clang/AST/TemplateBase.h | 108 +- contrib/llvm/tools/clang/include/clang/AST/Type.h | 111 +- .../llvm/tools/clang/include/clang/AST/TypeLoc.h | 142 +- .../tools/clang/include/clang/AST/TypeNodes.def | 3 +- .../tools/clang/include/clang/AST/TypeOrdering.h | 16 +- .../tools/clang/include/clang/AST/TypeVisitor.h | 44 +- .../tools/clang/include/clang/AST/UnresolvedSet.h | 15 +- .../tools/clang/include/clang/AST/VTTBuilder.h | 49 +- .../tools/clang/include/clang/AST/VTableBuilder.h | 301 ++- .../include/clang/ASTMatchers/ASTMatchFinder.h | 21 +- .../clang/include/clang/ASTMatchers/ASTMatchers.h | 718 +++--- .../clang/ASTMatchers/ASTMatchersInternal.h | 786 ++++-- .../include/clang/ASTMatchers/ASTMatchersMacros.h | 189 +- .../clang/ASTMatchers/Dynamic/Diagnostics.h | 185 ++ .../include/clang/ASTMatchers/Dynamic/Parser.h | 151 ++ .../include/clang/ASTMatchers/Dynamic/Registry.h | 75 + .../clang/ASTMatchers/Dynamic/VariantValue.h | 261 ++ .../include/clang/Analysis/Analyses/Consumed.h | 264 ++ .../include/clang/Analysis/Analyses/FormatString.h | 8 +- .../include/clang/Analysis/Analyses/ThreadSafety.h | 4 +- .../clang/Analysis/Analyses/UninitializedValues.h | 22 +- .../clang/include/clang/Analysis/AnalysisContext.h | 6 +- .../include/clang/Analysis/AnalysisDiagnostic.h | 2 +- .../llvm/tools/clang/include/clang/Analysis/CFG.h | 90 +- .../tools/clang/include/clang/Analysis/CallGraph.h | 4 +- .../clang/Analysis/FlowSensitive/DataflowSolver.h | 3 +- .../clang/Analysis/Support/BlkExprDeclBitVector.h | 307 --- .../Analysis/Visitors/CFGRecStmtDeclVisitor.h | 107 - .../clang/Analysis/Visitors/CFGRecStmtVisitor.h | 59 - .../clang/Analysis/Visitors/CFGStmtVisitor.h | 175 -- contrib/llvm/tools/clang/include/clang/Basic/ABI.h | 142 +- .../llvm/tools/clang/include/clang/Basic/Attr.td | 268 +- .../tools/clang/include/clang/Basic/AttrKinds.h | 2 +- .../tools/clang/include/clang/Basic/Builtins.def | 469 +++- .../tools/clang/include/clang/Basic/Builtins.h | 21 +- .../clang/include/clang/Basic/BuiltinsAArch64.def | 7 + .../clang/include/clang/Basic/BuiltinsARM.def | 25 +- .../clang/include/clang/Basic/BuiltinsMips.def | 712 ++++++ .../clang/include/clang/Basic/BuiltinsNVPTX.def | 744 ++++-- .../clang/include/clang/Basic/BuiltinsX86.def | 16 +- .../clang/include/clang/Basic/BuiltinsXCore.def | 22 + .../tools/clang/include/clang/Basic/CapturedStmt.h | 3 +- .../tools/clang/include/clang/Basic/DeclNodes.td | 4 + .../tools/clang/include/clang/Basic/Diagnostic.h | 16 +- .../tools/clang/include/clang/Basic/Diagnostic.td | 43 +- .../include/clang/Basic/DiagnosticASTKinds.td | 16 + .../include/clang/Basic/DiagnosticCommentKinds.td | 4 + .../include/clang/Basic/DiagnosticCommonKinds.td | 20 +- .../include/clang/Basic/DiagnosticDriverKinds.td | 24 +- .../include/clang/Basic/DiagnosticFrontendKinds.td | 7 +- .../clang/include/clang/Basic/DiagnosticGroups.td | 102 +- .../clang/include/clang/Basic/DiagnosticIDs.h | 34 +- .../include/clang/Basic/DiagnosticLexKinds.td | 66 +- .../include/clang/Basic/DiagnosticOptions.def | 1 + .../include/clang/Basic/DiagnosticParseKinds.td | 81 +- .../include/clang/Basic/DiagnosticSemaKinds.td | 760 ++++-- .../clang/Basic/DiagnosticSerializationKinds.td | 13 +- .../tools/clang/include/clang/Basic/FileManager.h | 36 +- .../include/clang/Basic/FileSystemStatCache.h | 47 +- .../clang/include/clang/Basic/IdentifierTable.h | 82 +- .../llvm/tools/clang/include/clang/Basic/Lambda.h | 15 +- .../clang/include/clang/Basic/LangOptions.def | 33 +- .../tools/clang/include/clang/Basic/LangOptions.h | 7 + .../llvm/tools/clang/include/clang/Basic/Linkage.h | 40 +- .../llvm/tools/clang/include/clang/Basic/Module.h | 57 +- .../tools/clang/include/clang/Basic/ObjCRuntime.h | 7 +- .../clang/include/clang/Basic/OpenMPKinds.def | 31 +- .../tools/clang/include/clang/Basic/OpenMPKinds.h | 28 + .../clang/include/clang/Basic/OperatorKinds.h | 2 +- .../clang/include/clang/Basic/PartialDiagnostic.h | 21 + .../tools/clang/include/clang/Basic/Sanitizers.def | 23 +- .../clang/include/clang/Basic/SourceLocation.h | 2 +- .../clang/include/clang/Basic/SourceManager.h | 58 +- .../tools/clang/include/clang/Basic/Specifiers.h | 33 +- .../tools/clang/include/clang/Basic/StmtNodes.td | 6 + .../clang/include/clang/Basic/TargetBuiltins.h | 14 +- .../tools/clang/include/clang/Basic/TargetCXXABI.h | 24 +- .../tools/clang/include/clang/Basic/TargetInfo.h | 47 +- .../clang/include/clang/Basic/TargetOptions.h | 3 + .../clang/include/clang/Basic/TemplateKinds.h | 3 + .../tools/clang/include/clang/Basic/TokenKinds.def | 17 +- .../tools/clang/include/clang/Basic/TypeTraits.h | 1 + .../tools/clang/include/clang/Basic/Visibility.h | 16 +- .../tools/clang/include/clang/Basic/arm_neon.td | 888 ++++++- .../clang/include/clang/CodeGen/CGFunctionInfo.h | 361 +++ .../clang/include/clang/CodeGen/CodeGenABITypes.h | 80 + .../llvm/tools/clang/include/clang/Driver/Action.h | 14 +- .../llvm/tools/clang/include/clang/Driver/Arg.h | 133 - .../tools/clang/include/clang/Driver/ArgList.h | 442 ---- .../clang/include/clang/Driver/CC1AsOptions.h | 13 +- .../clang/include/clang/Driver/CC1AsOptions.td | 11 +- .../tools/clang/include/clang/Driver/CC1Options.td | 43 +- .../clang/include/clang/Driver/CLCompatOptions.td | 255 ++ .../tools/clang/include/clang/Driver/Compilation.h | 55 +- .../llvm/tools/clang/include/clang/Driver/Driver.h | 77 +- .../clang/include/clang/Driver/DriverDiagnostic.h | 2 +- .../llvm/tools/clang/include/clang/Driver/Job.h | 71 +- .../tools/clang/include/clang/Driver/OptParser.td | 152 -- .../clang/include/clang/Driver/OptSpecifier.h | 41 - .../tools/clang/include/clang/Driver/OptTable.h | 161 -- .../llvm/tools/clang/include/clang/Driver/Option.h | 204 -- .../tools/clang/include/clang/Driver/Options.h | 28 +- .../tools/clang/include/clang/Driver/Options.td | 535 +++- .../clang/include/clang/Driver/SanitizerArgs.h | 147 ++ .../llvm/tools/clang/include/clang/Driver/Tool.h | 13 +- .../tools/clang/include/clang/Driver/ToolChain.h | 102 +- .../tools/clang/include/clang/Driver/Types.def | 2 +- .../llvm/tools/clang/include/clang/Driver/Types.h | 4 +- .../llvm/tools/clang/include/clang/Driver/Util.h | 5 +- .../llvm/tools/clang/include/clang/Edit/Commit.h | 16 +- .../tools/clang/include/clang/Edit/EditedSource.h | 9 +- .../tools/clang/include/clang/Edit/Rewriters.h | 8 +- .../llvm/tools/clang/include/clang/Format/Format.h | 286 ++- .../clang/include/clang/Frontend/ASTConsumers.h | 9 +- .../tools/clang/include/clang/Frontend/ASTUnit.h | 14 +- .../include/clang/Frontend/CodeGenOptions.def | 14 +- .../clang/include/clang/Frontend/CodeGenOptions.h | 12 + .../include/clang/Frontend/CompilerInstance.h | 36 +- .../include/clang/Frontend/CompilerInvocation.h | 15 +- .../clang/Frontend/DependencyOutputOptions.h | 2 + .../clang/include/clang/Frontend/FrontendAction.h | 10 +- .../clang/include/clang/Frontend/FrontendActions.h | 10 +- .../include/clang/Frontend/FrontendDiagnostic.h | 2 +- .../clang/include/clang/Frontend/FrontendOptions.h | 33 +- .../clang/include/clang/Frontend/TextDiagnostic.h | 3 +- .../tools/clang/include/clang/Frontend/Utils.h | 23 +- .../tools/clang/include/clang/Index/CommentToXML.h | 50 + .../clang/include/clang/Index/USRGeneration.h | 54 + .../clang/include/clang/Lex/DirectoryLookup.h | 10 +- .../tools/clang/include/clang/Lex/HeaderSearch.h | 65 +- .../clang/include/clang/Lex/HeaderSearchOptions.h | 8 +- .../tools/clang/include/clang/Lex/LexDiagnostic.h | 2 +- contrib/llvm/tools/clang/include/clang/Lex/Lexer.h | 69 +- .../tools/clang/include/clang/Lex/LiteralSupport.h | 20 +- .../llvm/tools/clang/include/clang/Lex/MacroInfo.h | 4 +- .../tools/clang/include/clang/Lex/ModuleLoader.h | 4 + .../llvm/tools/clang/include/clang/Lex/ModuleMap.h | 86 +- .../clang/include/clang/Lex/MultipleIncludeOpt.h | 56 +- .../tools/clang/include/clang/Lex/PPCallbacks.h | 95 +- .../clang/Lex/PPConditionalDirectiveRecord.h | 5 +- .../llvm/tools/clang/include/clang/Lex/PTHLexer.h | 2 +- .../clang/include/clang/Lex/PreprocessingRecord.h | 3 +- .../tools/clang/include/clang/Lex/Preprocessor.h | 79 +- .../clang/include/clang/Lex/PreprocessorLexer.h | 6 +- contrib/llvm/tools/clang/include/clang/Lex/Token.h | 9 +- .../tools/clang/include/clang/Lex/TokenLexer.h | 4 +- .../clang/include/clang/Parse/ParseDiagnostic.h | 2 +- .../llvm/tools/clang/include/clang/Parse/Parser.h | 185 +- .../clang/include/clang/Rewrite/Core/HTMLRewrite.h | 2 +- .../clang/include/clang/Rewrite/Core/Rewriter.h | 17 +- .../include/clang/Sema/AnalysisBasedWarnings.h | 1 + .../tools/clang/include/clang/Sema/AttributeList.h | 233 +- .../include/clang/Sema/CodeCompleteConsumer.h | 20 +- .../llvm/tools/clang/include/clang/Sema/DeclSpec.h | 120 +- .../clang/include/clang/Sema/DelayedDiagnostic.h | 24 +- .../clang/include/clang/Sema/ExternalSemaSource.h | 44 +- .../clang/include/clang/Sema/IdentifierResolver.h | 10 - .../clang/include/clang/Sema/Initialization.h | 117 +- .../llvm/tools/clang/include/clang/Sema/Lookup.h | 119 +- .../clang/Sema/MultiplexExternalSemaSource.h | 30 + .../llvm/tools/clang/include/clang/Sema/Overload.h | 77 +- .../tools/clang/include/clang/Sema/Ownership.h | 24 +- .../llvm/tools/clang/include/clang/Sema/Scope.h | 23 +- .../tools/clang/include/clang/Sema/ScopeInfo.h | 269 +- contrib/llvm/tools/clang/include/clang/Sema/Sema.h | 970 ++++++-- .../clang/include/clang/Sema/SemaDiagnostic.h | 2 +- .../tools/clang/include/clang/Sema/SemaInternal.h | 39 +- .../tools/clang/include/clang/Sema/SemaLambda.h | 39 + .../llvm/tools/clang/include/clang/Sema/Template.h | 123 +- .../clang/include/clang/Sema/TemplateDeduction.h | 122 +- .../clang/include/clang/Sema/TypoCorrection.h | 105 +- .../include/clang/Serialization/ASTBitCodes.h | 30 +- .../clang/include/clang/Serialization/ASTReader.h | 61 +- .../clang/include/clang/Serialization/ASTWriter.h | 23 +- .../clang/Serialization/GlobalModuleIndex.h | 1 + .../include/clang/Serialization/ModuleManager.h | 6 +- .../clang/Serialization/SerializationDiagnostic.h | 2 +- .../StaticAnalyzer/Checkers/CommonBugCategories.h | 24 - .../StaticAnalyzer/Checkers/ObjCRetainCount.h | 223 ++ .../include/clang/StaticAnalyzer/Core/Analyses.def | 12 +- .../clang/StaticAnalyzer/Core/AnalyzerOptions.h | 25 +- .../StaticAnalyzer/Core/BugReporter/BugReporter.h | 19 +- .../StaticAnalyzer/Core/BugReporter/BugType.h | 11 +- .../Core/BugReporter/CommonBugCategories.h | 25 + .../Core/BugReporter/PathDiagnostic.h | 56 +- .../include/clang/StaticAnalyzer/Core/Checker.h | 63 +- .../clang/StaticAnalyzer/Core/CheckerManager.h | 64 +- .../clang/StaticAnalyzer/Core/CheckerRegistry.h | 7 +- .../StaticAnalyzer/Core/PathDiagnosticConsumers.h | 18 +- .../Core/PathSensitive/AnalysisManager.h | 4 + .../StaticAnalyzer/Core/PathSensitive/CallEvent.h | 33 +- .../Core/PathSensitive/ExplodedGraph.h | 2 +- .../StaticAnalyzer/Core/PathSensitive/ExprEngine.h | 6 +- .../StaticAnalyzer/Core/PathSensitive/MemRegion.h | 48 +- .../Core/PathSensitive/ProgramState.h | 22 +- .../Core/PathSensitive/SValBuilder.h | 3 +- .../StaticAnalyzer/Core/PathSensitive/SVals.h | 2 +- .../StaticAnalyzer/Core/PathSensitive/Store.h | 19 +- .../StaticAnalyzer/Core/PathSensitive/SubEngine.h | 2 +- .../include/clang/Tooling/ArgumentsAdjusters.h | 6 + .../include/clang/Tooling/CommonOptionsParser.h | 2 +- .../include/clang/Tooling/CompilationDatabase.h | 14 + .../clang/include/clang/Tooling/Refactoring.h | 103 +- .../clang/include/clang/Tooling/ReplacementsYaml.h | 88 + .../tools/clang/include/clang/Tooling/Tooling.h | 170 +- contrib/llvm/tools/clang/lib/ARCMigrate/ARCMT.cpp | 13 +- .../tools/clang/lib/ARCMigrate/FileRemapper.cpp | 57 +- contrib/llvm/tools/clang/lib/ARCMigrate/ObjCMT.cpp | 1572 +++++++++++- .../clang/lib/ARCMigrate/TransUnbridgedCasts.cpp | 11 +- .../llvm/tools/clang/lib/ARCMigrate/Transforms.cpp | 22 +- .../llvm/tools/clang/lib/ARCMigrate/Transforms.h | 6 +- contrib/llvm/tools/clang/lib/AST/APValue.cpp | 34 + contrib/llvm/tools/clang/lib/AST/ASTContext.cpp | 816 ++++--- contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp | 83 +- contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp | 219 +- contrib/llvm/tools/clang/lib/AST/ASTImporter.cpp | 291 ++- contrib/llvm/tools/clang/lib/AST/ASTTypeTraits.cpp | 105 + contrib/llvm/tools/clang/lib/AST/AttrImpl.cpp | 1 + contrib/llvm/tools/clang/lib/AST/CXXABI.h | 8 +- .../llvm/tools/clang/lib/AST/CXXInheritance.cpp | 14 +- contrib/llvm/tools/clang/lib/AST/Comment.cpp | 15 +- .../tools/clang/lib/AST/CommentCommandTraits.cpp | 43 + contrib/llvm/tools/clang/lib/AST/CommentLexer.cpp | 21 +- contrib/llvm/tools/clang/lib/AST/CommentParser.cpp | 21 + contrib/llvm/tools/clang/lib/AST/CommentSema.cpp | 145 +- contrib/llvm/tools/clang/lib/AST/Decl.cpp | 800 ++++-- contrib/llvm/tools/clang/lib/AST/DeclBase.cpp | 195 +- contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp | 198 +- contrib/llvm/tools/clang/lib/AST/DeclFriend.cpp | 5 + contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp | 86 +- contrib/llvm/tools/clang/lib/AST/DeclOpenMP.cpp | 11 +- contrib/llvm/tools/clang/lib/AST/DeclPrinter.cpp | 29 +- contrib/llvm/tools/clang/lib/AST/DeclTemplate.cpp | 357 ++- .../llvm/tools/clang/lib/AST/DeclarationName.cpp | 142 +- contrib/llvm/tools/clang/lib/AST/DumpXML.cpp | 1055 -------- contrib/llvm/tools/clang/lib/AST/Expr.cpp | 462 ++-- contrib/llvm/tools/clang/lib/AST/ExprCXX.cpp | 268 +- .../tools/clang/lib/AST/ExprClassification.cpp | 13 +- contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp | 1981 +++++++++++---- contrib/llvm/tools/clang/lib/AST/InheritViz.cpp | 38 +- contrib/llvm/tools/clang/lib/AST/ItaniumCXXABI.cpp | 18 + contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp | 577 +++-- .../tools/clang/lib/AST/LambdaMangleContext.cpp | 33 - contrib/llvm/tools/clang/lib/AST/Mangle.cpp | 153 +- .../tools/clang/lib/AST/MangleNumberingContext.cpp | 43 + .../llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp | 21 + .../llvm/tools/clang/lib/AST/MicrosoftMangle.cpp | 990 +++++--- .../tools/clang/lib/AST/NestedNameSpecifier.cpp | 3 +- contrib/llvm/tools/clang/lib/AST/ParentMap.cpp | 30 +- .../llvm/tools/clang/lib/AST/RawCommentList.cpp | 106 +- contrib/llvm/tools/clang/lib/AST/RecordLayout.cpp | 9 +- .../tools/clang/lib/AST/RecordLayoutBuilder.cpp | 1484 +++++++----- contrib/llvm/tools/clang/lib/AST/Stmt.cpp | 266 +- contrib/llvm/tools/clang/lib/AST/StmtIterator.cpp | 63 +- contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp | 112 +- contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp | 75 +- contrib/llvm/tools/clang/lib/AST/TemplateBase.cpp | 81 +- contrib/llvm/tools/clang/lib/AST/Type.cpp | 126 +- contrib/llvm/tools/clang/lib/AST/TypeLoc.cpp | 53 +- contrib/llvm/tools/clang/lib/AST/TypePrinter.cpp | 134 +- contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp | 1662 ++++++++++--- .../tools/clang/lib/ASTMatchers/ASTMatchFinder.cpp | 425 ++-- .../clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 95 +- .../clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp | 220 ++ .../clang/lib/ASTMatchers/Dynamic/Marshallers.h | 453 ++++ .../tools/clang/lib/ASTMatchers/Dynamic/Parser.cpp | 420 ++++ .../clang/lib/ASTMatchers/Dynamic/Registry.cpp | 345 +++ .../clang/lib/ASTMatchers/Dynamic/VariantValue.cpp | 256 ++ .../clang/lib/Analysis/AnalysisDeclContext.cpp | 39 +- contrib/llvm/tools/clang/lib/Analysis/CFG.cpp | 330 ++- .../clang/lib/Analysis/CFGReachabilityAnalysis.cpp | 9 +- contrib/llvm/tools/clang/lib/Analysis/Consumed.cpp | 1521 ++++++++++++ .../llvm/tools/clang/lib/Analysis/FormatString.cpp | 50 +- .../tools/clang/lib/Analysis/LiveVariables.cpp | 3 +- .../clang/lib/Analysis/PrintfFormatString.cpp | 31 +- .../tools/clang/lib/Analysis/ReachableCode.cpp | 13 +- .../tools/clang/lib/Analysis/ScanfFormatString.cpp | 18 +- .../llvm/tools/clang/lib/Analysis/ThreadSafety.cpp | 160 +- .../clang/lib/Analysis/UninitializedValues.cpp | 30 +- contrib/llvm/tools/clang/lib/Basic/Builtins.cpp | 32 +- .../llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp | 104 +- contrib/llvm/tools/clang/lib/Basic/FileManager.cpp | 149 +- .../tools/clang/lib/Basic/FileSystemStatCache.cpp | 60 +- .../llvm/tools/clang/lib/Basic/IdentifierTable.cpp | 52 +- contrib/llvm/tools/clang/lib/Basic/Module.cpp | 84 +- contrib/llvm/tools/clang/lib/Basic/ObjCRuntime.cpp | 8 +- contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp | 94 +- .../tools/clang/lib/Basic/OperatorPrecedence.cpp | 2 +- .../llvm/tools/clang/lib/Basic/SourceManager.cpp | 216 +- contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp | 79 +- contrib/llvm/tools/clang/lib/Basic/Targets.cpp | 2173 ++++++++++------- contrib/llvm/tools/clang/lib/Basic/Version.cpp | 2 +- contrib/llvm/tools/clang/lib/CodeGen/ABIInfo.h | 147 +- .../llvm/tools/clang/lib/CodeGen/BackendUtil.cpp | 40 +- contrib/llvm/tools/clang/lib/CodeGen/CGAtomic.cpp | 127 +- contrib/llvm/tools/clang/lib/CodeGen/CGBlocks.cpp | 40 +- contrib/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp | 2556 +++++++++++++++++++- .../llvm/tools/clang/lib/CodeGen/CGCUDARuntime.cpp | 4 +- contrib/llvm/tools/clang/lib/CodeGen/CGCXX.cpp | 255 +- contrib/llvm/tools/clang/lib/CodeGen/CGCXXABI.cpp | 42 +- contrib/llvm/tools/clang/lib/CodeGen/CGCXXABI.h | 157 +- contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp | 235 +- contrib/llvm/tools/clang/lib/CodeGen/CGCall.h | 200 +- contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp | 393 ++- contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.cpp | 39 +- contrib/llvm/tools/clang/lib/CodeGen/CGCleanup.h | 12 +- .../llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp | 1355 +++++++---- contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.h | 176 +- contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp | 119 +- contrib/llvm/tools/clang/lib/CodeGen/CGDeclCXX.cpp | 80 +- .../llvm/tools/clang/lib/CodeGen/CGException.cpp | 33 +- contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp | 939 ++++--- contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp | 285 +-- contrib/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp | 235 +- .../llvm/tools/clang/lib/CodeGen/CGExprComplex.cpp | 167 +- .../tools/clang/lib/CodeGen/CGExprConstant.cpp | 95 +- .../llvm/tools/clang/lib/CodeGen/CGExprScalar.cpp | 402 +-- contrib/llvm/tools/clang/lib/CodeGen/CGObjC.cpp | 30 +- contrib/llvm/tools/clang/lib/CodeGen/CGObjCGNU.cpp | 59 +- contrib/llvm/tools/clang/lib/CodeGen/CGObjCMac.cpp | 29 +- .../llvm/tools/clang/lib/CodeGen/CGObjCRuntime.cpp | 1 + contrib/llvm/tools/clang/lib/CodeGen/CGRTTI.cpp | 62 +- .../clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 54 +- contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp | 184 +- contrib/llvm/tools/clang/lib/CodeGen/CGVTT.cpp | 34 +- contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp | 362 +-- contrib/llvm/tools/clang/lib/CodeGen/CGVTables.h | 40 +- contrib/llvm/tools/clang/lib/CodeGen/CGValue.h | 30 +- .../tools/clang/lib/CodeGen/CodeGenABITypes.cpp | 69 + .../llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp | 17 + .../tools/clang/lib/CodeGen/CodeGenFunction.cpp | 152 +- .../llvm/tools/clang/lib/CodeGen/CodeGenFunction.h | 714 ++---- .../llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp | 723 +++--- .../llvm/tools/clang/lib/CodeGen/CodeGenModule.h | 120 +- .../llvm/tools/clang/lib/CodeGen/CodeGenTBAA.cpp | 73 +- contrib/llvm/tools/clang/lib/CodeGen/CodeGenTBAA.h | 2 +- .../llvm/tools/clang/lib/CodeGen/CodeGenTypes.cpp | 7 +- .../llvm/tools/clang/lib/CodeGen/CodeGenTypes.h | 7 +- .../llvm/tools/clang/lib/CodeGen/EHScopeStack.h | 489 ++++ .../llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp | 514 +++- .../tools/clang/lib/CodeGen/MicrosoftCXXABI.cpp | 1289 +++++++++- .../tools/clang/lib/CodeGen/MicrosoftVBTables.cpp | 233 ++ .../tools/clang/lib/CodeGen/MicrosoftVBTables.h | 129 + .../llvm/tools/clang/lib/CodeGen/ModuleBuilder.cpp | 36 + .../llvm/tools/clang/lib/CodeGen/TargetInfo.cpp | 842 +++++-- contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.h | 34 +- contrib/llvm/tools/clang/lib/Driver/Action.cpp | 1 + contrib/llvm/tools/clang/lib/Driver/Arg.cpp | 123 - contrib/llvm/tools/clang/lib/Driver/ArgList.cpp | 423 ---- .../llvm/tools/clang/lib/Driver/CC1AsOptions.cpp | 21 +- .../llvm/tools/clang/lib/Driver/Compilation.cpp | 199 +- contrib/llvm/tools/clang/lib/Driver/Driver.cpp | 512 ++-- .../llvm/tools/clang/lib/Driver/DriverOptions.cpp | 19 +- contrib/llvm/tools/clang/lib/Driver/InputInfo.h | 11 +- contrib/llvm/tools/clang/lib/Driver/Job.cpp | 163 +- contrib/llvm/tools/clang/lib/Driver/OptTable.cpp | 388 --- contrib/llvm/tools/clang/lib/Driver/Option.cpp | 200 -- .../llvm/tools/clang/lib/Driver/SanitizerArgs.cpp | 389 +++ .../llvm/tools/clang/lib/Driver/SanitizerArgs.h | 220 -- contrib/llvm/tools/clang/lib/Driver/ToolChain.cpp | 64 +- contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp | 1227 ++++++---- contrib/llvm/tools/clang/lib/Driver/ToolChains.h | 303 ++- contrib/llvm/tools/clang/lib/Driver/Tools.cpp | 2242 +++++++++++------ contrib/llvm/tools/clang/lib/Driver/Tools.h | 188 +- contrib/llvm/tools/clang/lib/Driver/Types.cpp | 17 +- .../tools/clang/lib/Driver/WindowsToolChain.cpp | 55 +- contrib/llvm/tools/clang/lib/Edit/Commit.cpp | 14 +- .../llvm/tools/clang/lib/Format/BreakableToken.cpp | 504 +++- .../llvm/tools/clang/lib/Format/BreakableToken.h | 349 +-- .../clang/lib/Format/ContinuationIndenter.cpp | 884 +++++++ .../tools/clang/lib/Format/ContinuationIndenter.h | 327 +++ contrib/llvm/tools/clang/lib/Format/Encoding.h | 144 ++ contrib/llvm/tools/clang/lib/Format/Format.cpp | 2231 ++++++++--------- .../llvm/tools/clang/lib/Format/FormatToken.cpp | 204 ++ contrib/llvm/tools/clang/lib/Format/FormatToken.h | 452 ++++ .../llvm/tools/clang/lib/Format/TokenAnnotator.cpp | 1096 ++++++--- .../llvm/tools/clang/lib/Format/TokenAnnotator.h | 257 +- .../tools/clang/lib/Format/UnwrappedLineParser.cpp | 862 +++++-- .../tools/clang/lib/Format/UnwrappedLineParser.h | 163 +- .../tools/clang/lib/Format/WhitespaceManager.cpp | 413 ++-- .../tools/clang/lib/Format/WhitespaceManager.h | 182 +- .../llvm/tools/clang/lib/Frontend/ASTConsumers.cpp | 54 +- contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp | 294 +-- .../llvm/tools/clang/lib/Frontend/CacheTokens.cpp | 45 +- .../clang/lib/Frontend/ChainedIncludesSource.cpp | 6 +- .../tools/clang/lib/Frontend/CompilerInstance.cpp | 219 +- .../clang/lib/Frontend/CompilerInvocation.cpp | 281 ++- .../Frontend/CreateInvocationFromCommandLine.cpp | 9 +- .../tools/clang/lib/Frontend/DependencyFile.cpp | 4 +- .../tools/clang/lib/Frontend/FrontendAction.cpp | 12 +- .../tools/clang/lib/Frontend/FrontendActions.cpp | 27 +- .../tools/clang/lib/Frontend/FrontendOptions.cpp | 1 - .../tools/clang/lib/Frontend/HeaderIncludeGen.cpp | 24 +- .../tools/clang/lib/Frontend/InitHeaderSearch.cpp | 55 +- .../tools/clang/lib/Frontend/InitPreprocessor.cpp | 76 +- .../tools/clang/lib/Frontend/MultiplexConsumer.cpp | 20 + .../clang/lib/Frontend/PrintPreprocessedOutput.cpp | 97 +- .../tools/clang/lib/Frontend/TextDiagnostic.cpp | 64 +- .../clang/lib/Frontend/TextDiagnosticPrinter.cpp | 3 +- .../lib/Frontend/VerifyDiagnosticConsumer.cpp | 8 +- .../lib/FrontendTool/ExecuteCompilerInvocation.cpp | 60 +- contrib/llvm/tools/clang/lib/Headers/Intrin.h | 784 ++++++ contrib/llvm/tools/clang/lib/Headers/avx2intrin.h | 25 +- contrib/llvm/tools/clang/lib/Headers/avxintrin.h | 22 +- contrib/llvm/tools/clang/lib/Headers/emmintrin.h | 34 +- contrib/llvm/tools/clang/lib/Headers/f16cintrin.h | 4 +- contrib/llvm/tools/clang/lib/Headers/immintrin.h | 4 + contrib/llvm/tools/clang/lib/Headers/limits.h | 6 +- contrib/llvm/tools/clang/lib/Headers/module.map | 11 + .../llvm/tools/clang/lib/Headers/prfchwintrin.h | 5 + .../llvm/tools/clang/lib/Headers/rdseedintrin.h | 4 + contrib/llvm/tools/clang/lib/Headers/rtmintrin.h | 5 + contrib/llvm/tools/clang/lib/Headers/shaintrin.h | 74 + contrib/llvm/tools/clang/lib/Headers/smmintrin.h | 15 +- contrib/llvm/tools/clang/lib/Headers/tbmintrin.h | 158 ++ contrib/llvm/tools/clang/lib/Headers/tgmath.h | 6 +- contrib/llvm/tools/clang/lib/Headers/unwind.h | 159 +- contrib/llvm/tools/clang/lib/Headers/x86intrin.h | 4 + contrib/llvm/tools/clang/lib/Headers/xmmintrin.h | 18 +- contrib/llvm/tools/clang/lib/Headers/xopintrin.h | 393 +++ .../llvm/tools/clang/lib/Index/CommentToXML.cpp | 1136 +++++++++ .../tools/clang/lib/Index/SimpleFormatContext.h | 77 + .../llvm/tools/clang/lib/Index/USRGeneration.cpp | 803 ++++++ contrib/llvm/tools/clang/lib/Lex/HeaderMap.cpp | 2 +- contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp | 125 +- contrib/llvm/tools/clang/lib/Lex/Lexer.cpp | 470 ++-- .../llvm/tools/clang/lib/Lex/LiteralSupport.cpp | 156 +- contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp | 392 ++- .../clang/lib/Lex/PPConditionalDirectiveRecord.cpp | 4 +- contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp | 219 +- contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp | 29 +- contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp | 86 +- .../llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp | 280 ++- contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp | 89 +- contrib/llvm/tools/clang/lib/Lex/Pragma.cpp | 206 +- .../tools/clang/lib/Lex/PreprocessingRecord.cpp | 3 +- contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp | 48 +- .../llvm/tools/clang/lib/Lex/PreprocessorLexer.cpp | 5 +- contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp | 61 +- contrib/llvm/tools/clang/lib/Lex/UnicodeCharSets.h | 102 +- contrib/llvm/tools/clang/lib/Parse/ParseAST.cpp | 2 +- .../clang/lib/Parse/ParseCXXInlineMethods.cpp | 548 ++++- contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp | 723 ++++-- .../llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp | 427 ++-- contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp | 172 +- .../llvm/tools/clang/lib/Parse/ParseExprCXX.cpp | 252 +- contrib/llvm/tools/clang/lib/Parse/ParseInit.cpp | 10 +- contrib/llvm/tools/clang/lib/Parse/ParseObjc.cpp | 109 +- contrib/llvm/tools/clang/lib/Parse/ParseOpenMP.cpp | 347 ++- contrib/llvm/tools/clang/lib/Parse/ParsePragma.cpp | 85 +- contrib/llvm/tools/clang/lib/Parse/ParsePragma.h | 15 +- contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp | 209 +- .../llvm/tools/clang/lib/Parse/ParseTemplate.cpp | 115 +- .../llvm/tools/clang/lib/Parse/ParseTentative.cpp | 418 +++- contrib/llvm/tools/clang/lib/Parse/Parser.cpp | 184 +- .../tools/clang/lib/Parse/RAIIObjectsForParser.h | 7 +- .../tools/clang/lib/Rewrite/Core/HTMLRewrite.cpp | 5 +- .../llvm/tools/clang/lib/Rewrite/Core/Rewriter.cpp | 5 +- .../clang/lib/Rewrite/Frontend/FixItRewriter.cpp | 2 +- .../clang/lib/Rewrite/Frontend/FrontendActions.cpp | 10 +- .../lib/Rewrite/Frontend/InclusionRewriter.cpp | 71 +- .../clang/lib/Rewrite/Frontend/RewriteMacros.cpp | 2 +- .../lib/Rewrite/Frontend/RewriteModernObjC.cpp | 208 +- .../clang/lib/Rewrite/Frontend/RewriteObjC.cpp | 66 +- .../tools/clang/lib/Sema/AnalysisBasedWarnings.cpp | 213 +- .../llvm/tools/clang/lib/Sema/AttributeList.cpp | 40 +- contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp | 100 +- .../tools/clang/lib/Sema/IdentifierResolver.cpp | 40 +- .../llvm/tools/clang/lib/Sema/JumpDiagnostics.cpp | 9 +- .../clang/lib/Sema/MultiplexExternalSemaSource.cpp | 31 + contrib/llvm/tools/clang/lib/Sema/ScopeInfo.cpp | 15 + contrib/llvm/tools/clang/lib/Sema/Sema.cpp | 188 +- contrib/llvm/tools/clang/lib/Sema/SemaAccess.cpp | 30 +- contrib/llvm/tools/clang/lib/Sema/SemaAttr.cpp | 42 +- .../llvm/tools/clang/lib/Sema/SemaCXXScopeSpec.cpp | 50 +- contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp | 142 +- contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp | 844 +++++-- .../llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp | 218 +- contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp | 2400 ++++++++++++------ contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp | 1947 +++++++-------- contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp | 2110 ++++++++++------ contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp | 408 +++- .../tools/clang/lib/Sema/SemaExceptionSpec.cpp | 204 +- contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp | 2490 ++++++++++++------- contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp | 972 +++++--- .../llvm/tools/clang/lib/Sema/SemaExprMember.cpp | 175 +- contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp | 296 ++- .../llvm/tools/clang/lib/Sema/SemaFixItUtils.cpp | 28 +- contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp | 1166 ++++++--- contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp | 948 ++++++-- contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp | 924 +++++-- .../llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp | 444 ++-- contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp | 1207 ++++++++- contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp | 1531 +++++++----- .../llvm/tools/clang/lib/Sema/SemaPseudoObject.cpp | 39 +- contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp | 573 +++-- contrib/llvm/tools/clang/lib/Sema/SemaStmtAsm.cpp | 11 +- contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp | 1386 ++++++++--- .../tools/clang/lib/Sema/SemaTemplateDeduction.cpp | 699 ++++-- .../clang/lib/Sema/SemaTemplateInstantiate.cpp | 295 ++- .../clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 1403 ++++++++--- .../tools/clang/lib/Sema/SemaTemplateVariadic.cpp | 97 +- contrib/llvm/tools/clang/lib/Sema/SemaType.cpp | 804 ++++-- .../tools/clang/lib/Sema/TargetAttributesSema.cpp | 136 +- contrib/llvm/tools/clang/lib/Sema/TreeTransform.h | 691 ++++-- .../llvm/tools/clang/lib/Sema/TypeLocBuilder.cpp | 136 ++ contrib/llvm/tools/clang/lib/Sema/TypeLocBuilder.h | 86 +- .../tools/clang/lib/Serialization/ASTCommon.cpp | 5 +- .../llvm/tools/clang/lib/Serialization/ASTCommon.h | 4 +- .../tools/clang/lib/Serialization/ASTReader.cpp | 293 ++- .../clang/lib/Serialization/ASTReaderDecl.cpp | 772 ++++-- .../clang/lib/Serialization/ASTReaderStmt.cpp | 145 +- .../tools/clang/lib/Serialization/ASTWriter.cpp | 229 +- .../clang/lib/Serialization/ASTWriterDecl.cpp | 170 +- .../clang/lib/Serialization/ASTWriterStmt.cpp | 110 +- .../tools/clang/lib/Serialization/GeneratePCH.cpp | 17 +- .../clang/lib/Serialization/GlobalModuleIndex.cpp | 8 +- .../clang/lib/Serialization/ModuleManager.cpp | 13 +- .../Checkers/BasicObjCFoundationChecks.cpp | 365 ++- .../Checkers/BuiltinFunctionChecker.cpp | 30 +- .../lib/StaticAnalyzer/Checkers/CStringChecker.cpp | 84 +- .../Checkers/CStringSyntaxChecker.cpp | 3 +- .../Checkers/CallAndMessageChecker.cpp | 59 +- .../Checkers/CheckSecuritySyntaxOnly.cpp | 63 +- .../StaticAnalyzer/Checkers/CheckSizeofPointer.cpp | 5 +- .../Checkers/CheckerDocumentation.cpp | 2 +- .../clang/lib/StaticAnalyzer/Checkers/Checkers.td | 8 + .../lib/StaticAnalyzer/Checkers/ClangSACheckers.h | 2 +- .../Checkers/CommonBugCategories.cpp | 18 - .../StaticAnalyzer/Checkers/DeadStoresChecker.cpp | 42 +- .../lib/StaticAnalyzer/Checkers/DebugCheckers.cpp | 49 +- .../Checkers/DirectIvarAssignment.cpp | 50 +- .../Checkers/DynamicTypePropagation.cpp | 4 +- .../Checkers/ExprInspectionChecker.cpp | 20 + .../Checkers/GenericTaintChecker.cpp | 3 +- .../Checkers/IdempotentOperationChecker.cpp | 19 +- .../Checkers/IdenticalExprChecker.cpp | 226 ++ .../lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 120 +- .../Checkers/MallocOverflowSecurityChecker.cpp | 4 +- .../Checkers/MallocSizeofChecker.cpp | 2 +- .../Checkers/NoReturnFunctionChecker.cpp | 27 +- .../Checkers/ObjCContainersASTChecker.cpp | 3 +- .../StaticAnalyzer/Checkers/RetainCountChecker.cpp | 220 +- .../Checkers/SimpleStreamChecker.cpp | 8 +- .../StaticAnalyzer/Checkers/UndefResultChecker.cpp | 9 + .../Checkers/UndefinedArraySubscriptChecker.cpp | 3 +- .../Checkers/UndefinedAssignmentChecker.cpp | 8 + .../Checkers/UnreachableCodeChecker.cpp | 3 + .../StaticAnalyzer/Checkers/VirtualCallChecker.cpp | 4 +- .../lib/StaticAnalyzer/Core/AnalyzerOptions.cpp | 12 + .../clang/lib/StaticAnalyzer/Core/BugReporter.cpp | 1194 +++++++-- .../StaticAnalyzer/Core/BugReporterVisitors.cpp | 90 +- .../clang/lib/StaticAnalyzer/Core/CallEvent.cpp | 61 +- .../lib/StaticAnalyzer/Core/CheckerContext.cpp | 2 +- .../lib/StaticAnalyzer/Core/CheckerManager.cpp | 42 +- .../StaticAnalyzer/Core/CommonBugCategories.cpp | 20 + .../lib/StaticAnalyzer/Core/ExplodedGraph.cpp | 6 +- .../clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 143 +- .../clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 79 +- .../lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 92 +- .../Core/ExprEngineCallAndReturn.cpp | 45 +- .../lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp | 59 +- .../clang/lib/StaticAnalyzer/Core/MemRegion.cpp | 85 +- .../lib/StaticAnalyzer/Core/PathDiagnostic.cpp | 83 +- .../lib/StaticAnalyzer/Core/PlistDiagnostics.cpp | 28 +- .../Core/PrettyStackTraceLocationContext.h | 45 + .../clang/lib/StaticAnalyzer/Core/ProgramState.cpp | 126 +- .../clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 139 +- .../clang/lib/StaticAnalyzer/Core/SValBuilder.cpp | 36 +- .../Core/SimpleConstraintManager.cpp | 59 +- .../StaticAnalyzer/Core/SimpleConstraintManager.h | 6 - .../lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 212 +- .../tools/clang/lib/StaticAnalyzer/Core/Store.cpp | 5 +- .../lib/StaticAnalyzer/Core/SymbolManager.cpp | 6 +- .../StaticAnalyzer/Core/TextPathDiagnostics.cpp | 72 - .../StaticAnalyzer/Frontend/AnalysisConsumer.cpp | 120 +- .../tools/clang/lib/Tooling/ArgumentsAdjusters.cpp | 29 +- .../clang/lib/Tooling/CommonOptionsParser.cpp | 5 +- .../clang/lib/Tooling/CompilationDatabase.cpp | 185 +- .../llvm/tools/clang/lib/Tooling/FileMatchTrie.cpp | 2 +- .../clang/lib/Tooling/JSONCompilationDatabase.cpp | 4 +- .../llvm/tools/clang/lib/Tooling/Refactoring.cpp | 190 +- contrib/llvm/tools/clang/lib/Tooling/Tooling.cpp | 232 +- contrib/llvm/tools/clang/tools/driver/cc1_main.cpp | 7 +- .../llvm/tools/clang/tools/driver/cc1as_main.cpp | 46 +- contrib/llvm/tools/clang/tools/driver/driver.cpp | 208 +- .../clang/utils/TableGen/ClangAttrEmitter.cpp | 395 ++- .../TableGen/ClangCommentCommandInfoEmitter.cpp | 1 + .../utils/TableGen/ClangDiagnosticsEmitter.cpp | 172 +- .../tools/clang/utils/TableGen/NeonEmitter.cpp | 1508 ++++++++++-- .../clang/utils/TableGen/OptParserEmitter.cpp | 275 --- .../llvm/tools/clang/utils/TableGen/TableGen.cpp | 191 +- .../tools/clang/utils/TableGen/TableGenBackends.h | 6 +- contrib/llvm/tools/llc/llc.cpp | 9 +- .../lldb/include/lldb/Expression/IRExecutionUnit.h | 50 +- contrib/llvm/tools/lldb/source/Core/ArchSpec.cpp | 106 +- .../source/Expression/ClangExpressionParser.cpp | 23 +- .../lldb/source/Expression/IRExecutionUnit.cpp | 30 +- .../tools/lldb/source/Expression/IRForTarget.cpp | 14 + .../tools/lldb/source/Host/common/FileSpec.cpp | 5 +- .../Disassembler/llvm/DisassemblerLLVMC.cpp | 23 +- .../Instruction/ARM/EmulateInstructionARM.cpp | 4 +- .../llvm/tools/lldb/source/Symbol/ClangASTType.cpp | 14 + contrib/llvm/tools/lli/ChildTarget/ChildTarget.cpp | 242 ++ .../tools/lli/ChildTarget/Unix/ChildTarget.inc | 166 ++ .../tools/lli/ChildTarget/Windows/ChildTarget.inc | 44 + contrib/llvm/tools/lli/RecordingMemoryManager.cpp | 128 - contrib/llvm/tools/lli/RecordingMemoryManager.h | 87 - contrib/llvm/tools/lli/RemoteMemoryManager.cpp | 206 ++ contrib/llvm/tools/lli/RemoteMemoryManager.h | 114 + contrib/llvm/tools/lli/RemoteTarget.cpp | 31 + contrib/llvm/tools/lli/RemoteTarget.h | 27 +- contrib/llvm/tools/lli/RemoteTargetExternal.cpp | 162 ++ contrib/llvm/tools/lli/RemoteTargetExternal.h | 118 + contrib/llvm/tools/lli/RemoteTargetMessage.h | 45 + .../llvm/tools/lli/Unix/RemoteTargetExternal.inc | 96 + .../tools/lli/Windows/RemoteTargetExternal.inc | 35 + contrib/llvm/tools/lli/lli.cpp | 322 +-- contrib/llvm/tools/llvm-ar/llvm-ar.cpp | 1146 +++++---- contrib/llvm/tools/llvm-as/llvm-as.cpp | 5 +- .../llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp | 3 +- contrib/llvm/tools/llvm-diff/DifferenceEngine.cpp | 10 +- contrib/llvm/tools/llvm-diff/llvm-diff.cpp | 2 +- contrib/llvm/tools/llvm-dis/llvm-dis.cpp | 5 +- contrib/llvm/tools/llvm-extract/llvm-extract.cpp | 5 +- contrib/llvm/tools/llvm-link/llvm-link.cpp | 18 +- contrib/llvm/tools/llvm-mc/Disassembler.cpp | 72 +- contrib/llvm/tools/llvm-mc/llvm-mc.cpp | 22 +- contrib/llvm/tools/llvm-nm/llvm-nm.cpp | 279 ++- contrib/llvm/tools/llvm-objdump/COFFDump.cpp | 50 +- contrib/llvm/tools/llvm-objdump/ELFDump.cpp | 30 +- contrib/llvm/tools/llvm-objdump/MCFunction.cpp | 138 -- contrib/llvm/tools/llvm-objdump/MCFunction.h | 100 - contrib/llvm/tools/llvm-objdump/MachODump.cpp | 456 ++-- contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp | 246 +- contrib/llvm/tools/llvm-objdump/llvm-objdump.h | 22 +- contrib/llvm/tools/llvm-prof/llvm-prof.cpp | 293 --- contrib/llvm/tools/llvm-ranlib/llvm-ranlib.cpp | 98 - contrib/llvm/tools/llvm-readobj/COFFDumper.cpp | 126 +- contrib/llvm/tools/llvm-readobj/ELFDumper.cpp | 427 ++-- contrib/llvm/tools/llvm-readobj/MachODumper.cpp | 75 +- contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp | 7 +- contrib/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp | 30 +- contrib/llvm/tools/llvm-stress/llvm-stress.cpp | 9 +- .../llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp | 254 +- contrib/llvm/tools/llvm-symbolizer/LLVMSymbolize.h | 40 +- .../llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp | 6 +- contrib/llvm/tools/macho-dump/macho-dump.cpp | 245 +- contrib/llvm/tools/opt/opt.cpp | 55 +- 720 files changed, 89216 insertions(+), 39522 deletions(-) create mode 100644 contrib/llvm/tools/clang/include/clang/AST/ASTFwd.h create mode 100644 contrib/llvm/tools/clang/include/clang/AST/ASTLambda.h delete mode 100644 contrib/llvm/tools/clang/include/clang/AST/LambdaMangleContext.h create mode 100644 contrib/llvm/tools/clang/include/clang/AST/MangleNumberingContext.h create mode 100644 contrib/llvm/tools/clang/include/clang/AST/StmtOpenMP.h create mode 100644 contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h create mode 100644 contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Parser.h create mode 100644 contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Registry.h create mode 100644 contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h create mode 100644 contrib/llvm/tools/clang/include/clang/Analysis/Analyses/Consumed.h delete mode 100644 contrib/llvm/tools/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h delete mode 100644 contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h delete mode 100644 contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h delete mode 100644 contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h create mode 100644 contrib/llvm/tools/clang/include/clang/Basic/BuiltinsXCore.def create mode 100644 contrib/llvm/tools/clang/include/clang/CodeGen/CGFunctionInfo.h create mode 100644 contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenABITypes.h delete mode 100644 contrib/llvm/tools/clang/include/clang/Driver/Arg.h delete mode 100644 contrib/llvm/tools/clang/include/clang/Driver/ArgList.h create mode 100644 contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td delete mode 100644 contrib/llvm/tools/clang/include/clang/Driver/OptParser.td delete mode 100644 contrib/llvm/tools/clang/include/clang/Driver/OptSpecifier.h delete mode 100644 contrib/llvm/tools/clang/include/clang/Driver/OptTable.h delete mode 100644 contrib/llvm/tools/clang/include/clang/Driver/Option.h create mode 100644 contrib/llvm/tools/clang/include/clang/Driver/SanitizerArgs.h create mode 100644 contrib/llvm/tools/clang/include/clang/Index/CommentToXML.h create mode 100644 contrib/llvm/tools/clang/include/clang/Index/USRGeneration.h create mode 100644 contrib/llvm/tools/clang/include/clang/Sema/SemaLambda.h delete mode 100644 contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/CommonBugCategories.h create mode 100644 contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h create mode 100644 contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h create mode 100644 contrib/llvm/tools/clang/include/clang/Tooling/ReplacementsYaml.h create mode 100644 contrib/llvm/tools/clang/lib/AST/ASTTypeTraits.cpp delete mode 100644 contrib/llvm/tools/clang/lib/AST/DumpXML.cpp delete mode 100644 contrib/llvm/tools/clang/lib/AST/LambdaMangleContext.cpp create mode 100644 contrib/llvm/tools/clang/lib/AST/MangleNumberingContext.cpp create mode 100644 contrib/llvm/tools/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp create mode 100644 contrib/llvm/tools/clang/lib/ASTMatchers/Dynamic/Marshallers.h create mode 100644 contrib/llvm/tools/clang/lib/ASTMatchers/Dynamic/Parser.cpp create mode 100644 contrib/llvm/tools/clang/lib/ASTMatchers/Dynamic/Registry.cpp create mode 100644 contrib/llvm/tools/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp create mode 100644 contrib/llvm/tools/clang/lib/Analysis/Consumed.cpp create mode 100644 contrib/llvm/tools/clang/lib/CodeGen/CodeGenABITypes.cpp create mode 100644 contrib/llvm/tools/clang/lib/CodeGen/EHScopeStack.h create mode 100644 contrib/llvm/tools/clang/lib/CodeGen/MicrosoftVBTables.cpp create mode 100644 contrib/llvm/tools/clang/lib/CodeGen/MicrosoftVBTables.h delete mode 100644 contrib/llvm/tools/clang/lib/Driver/Arg.cpp delete mode 100644 contrib/llvm/tools/clang/lib/Driver/ArgList.cpp delete mode 100644 contrib/llvm/tools/clang/lib/Driver/OptTable.cpp delete mode 100644 contrib/llvm/tools/clang/lib/Driver/Option.cpp create mode 100644 contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.cpp delete mode 100644 contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h create mode 100644 contrib/llvm/tools/clang/lib/Format/ContinuationIndenter.cpp create mode 100644 contrib/llvm/tools/clang/lib/Format/ContinuationIndenter.h create mode 100644 contrib/llvm/tools/clang/lib/Format/Encoding.h create mode 100644 contrib/llvm/tools/clang/lib/Format/FormatToken.cpp create mode 100644 contrib/llvm/tools/clang/lib/Format/FormatToken.h create mode 100644 contrib/llvm/tools/clang/lib/Headers/Intrin.h create mode 100644 contrib/llvm/tools/clang/lib/Headers/shaintrin.h create mode 100644 contrib/llvm/tools/clang/lib/Headers/tbmintrin.h create mode 100644 contrib/llvm/tools/clang/lib/Index/CommentToXML.cpp create mode 100644 contrib/llvm/tools/clang/lib/Index/SimpleFormatContext.h create mode 100644 contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp create mode 100644 contrib/llvm/tools/clang/lib/Sema/TypeLocBuilder.cpp delete mode 100644 contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/CommonBugCategories.cpp create mode 100644 contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp create mode 100644 contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp create mode 100644 contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h delete mode 100644 contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp delete mode 100644 contrib/llvm/tools/clang/utils/TableGen/OptParserEmitter.cpp create mode 100644 contrib/llvm/tools/lli/ChildTarget/ChildTarget.cpp create mode 100644 contrib/llvm/tools/lli/ChildTarget/Unix/ChildTarget.inc create mode 100644 contrib/llvm/tools/lli/ChildTarget/Windows/ChildTarget.inc delete mode 100644 contrib/llvm/tools/lli/RecordingMemoryManager.cpp delete mode 100644 contrib/llvm/tools/lli/RecordingMemoryManager.h create mode 100644 contrib/llvm/tools/lli/RemoteMemoryManager.cpp create mode 100644 contrib/llvm/tools/lli/RemoteMemoryManager.h create mode 100644 contrib/llvm/tools/lli/RemoteTargetExternal.cpp create mode 100644 contrib/llvm/tools/lli/RemoteTargetExternal.h create mode 100644 contrib/llvm/tools/lli/RemoteTargetMessage.h create mode 100644 contrib/llvm/tools/lli/Unix/RemoteTargetExternal.inc create mode 100644 contrib/llvm/tools/lli/Windows/RemoteTargetExternal.inc delete mode 100644 contrib/llvm/tools/llvm-objdump/MCFunction.cpp delete mode 100644 contrib/llvm/tools/llvm-objdump/MCFunction.h delete mode 100644 contrib/llvm/tools/llvm-prof/llvm-prof.cpp delete mode 100644 contrib/llvm/tools/llvm-ranlib/llvm-ranlib.cpp (limited to 'contrib/llvm/tools') diff --git a/contrib/llvm/tools/bugpoint/BugDriver.cpp b/contrib/llvm/tools/bugpoint/BugDriver.cpp index 937d86a..a5436ba 100644 --- a/contrib/llvm/tools/bugpoint/BugDriver.cpp +++ b/contrib/llvm/tools/bugpoint/BugDriver.cpp @@ -194,8 +194,8 @@ bool BugDriver::run(std::string &ErrMsg) { // Make sure the reference output file gets deleted on exit from this // function, if appropriate. - sys::Path ROF(ReferenceOutputFile); - FileRemover RemoverInstance(ROF.str(), CreatedOutput && !SaveTemps); + std::string ROF(ReferenceOutputFile); + FileRemover RemoverInstance(ROF, CreatedOutput && !SaveTemps); // Diff the output of the raw program against the reference output. If it // matches, then we assume there is a miscompilation bug and try to diff --git a/contrib/llvm/tools/bugpoint/BugDriver.h b/contrib/llvm/tools/bugpoint/BugDriver.h index 2b621ec..27b37f4 100644 --- a/contrib/llvm/tools/bugpoint/BugDriver.h +++ b/contrib/llvm/tools/bugpoint/BugDriver.h @@ -191,7 +191,7 @@ public: /// this function. /// bool createReferenceFile(Module *M, const std::string &Filename - = "bugpoint.reference.out"); + = "bugpoint.reference.out-%%%%%%%"); /// diffProgram - This method executes the specified module and diffs the /// output against the file specified by ReferenceOutputFile. If the output @@ -275,6 +275,8 @@ public: /// bitcode file. If an error occurs, true is returned. /// bool writeProgramToFile(const std::string &Filename, const Module *M) const; + bool writeProgramToFile(const std::string &Filename, int FD, + const Module *M) const; private: /// runPasses - Just like the method above, but this just returns true or diff --git a/contrib/llvm/tools/bugpoint/CrashDebugger.cpp b/contrib/llvm/tools/bugpoint/CrashDebugger.cpp index ed211a6..b90fc61 100644 --- a/contrib/llvm/tools/bugpoint/CrashDebugger.cpp +++ b/contrib/llvm/tools/bugpoint/CrashDebugger.cpp @@ -62,25 +62,23 @@ ReducePassList::TestResult ReducePassList::doTest(std::vector &Prefix, std::vector &Suffix, std::string &Error) { - sys::Path PrefixOutput; + std::string PrefixOutput; Module *OrigProgram = 0; if (!Prefix.empty()) { outs() << "Checking to see if these passes crash: " << getPassesString(Prefix) << ": "; - std::string PfxOutput; - if (BD.runPasses(BD.getProgram(), Prefix, PfxOutput)) + if (BD.runPasses(BD.getProgram(), Prefix, PrefixOutput)) return KeepPrefix; - PrefixOutput.set(PfxOutput); OrigProgram = BD.Program; - BD.Program = ParseInputFile(PrefixOutput.str(), BD.getContext()); + BD.Program = ParseInputFile(PrefixOutput, BD.getContext()); if (BD.Program == 0) { errs() << BD.getToolName() << ": Error reading bitcode file '" - << PrefixOutput.str() << "'!\n"; + << PrefixOutput << "'!\n"; exit(1); } - PrefixOutput.eraseFromDisk(); + sys::fs::remove(PrefixOutput); } outs() << "Checking to see if these passes crash: " @@ -197,10 +195,10 @@ namespace { } bool ReduceCrashingFunctions::TestFuncs(std::vector &Funcs) { - - //if main isn't present, claim there is no problem - if (KeepMain && find(Funcs.begin(), Funcs.end(), - BD.getProgram()->getFunction("main")) == Funcs.end()) + // If main isn't present, claim there is no problem. + if (KeepMain && std::find(Funcs.begin(), Funcs.end(), + BD.getProgram()->getFunction("main")) == + Funcs.end()) return false; // Clone the program to try hacking it apart... diff --git a/contrib/llvm/tools/bugpoint/ExecutionDriver.cpp b/contrib/llvm/tools/bugpoint/ExecutionDriver.cpp index da36045..c05c8d7 100644 --- a/contrib/llvm/tools/bugpoint/ExecutionDriver.cpp +++ b/contrib/llvm/tools/bugpoint/ExecutionDriver.cpp @@ -265,16 +265,18 @@ bool BugDriver::initializeExecutionEnvironment() { /// void BugDriver::compileProgram(Module *M, std::string *Error) const { // Emit the program to a bitcode file... - sys::Path BitcodeFile (OutputPrefix + "-test-program.bc"); - std::string ErrMsg; - if (BitcodeFile.makeUnique(true, &ErrMsg)) { - errs() << ToolName << ": Error making unique filename: " << ErrMsg + SmallString<128> BitcodeFile; + int BitcodeFD; + error_code EC = sys::fs::createUniqueFile( + OutputPrefix + "-test-program-%%%%%%%.bc", BitcodeFD, BitcodeFile); + if (EC) { + errs() << ToolName << ": Error making unique filename: " << EC.message() << "\n"; exit(1); } - if (writeProgramToFile(BitcodeFile.str(), M)) { - errs() << ToolName << ": Error emitting bitcode to file '" - << BitcodeFile.str() << "'!\n"; + if (writeProgramToFile(BitcodeFile.str(), BitcodeFD, M)) { + errs() << ToolName << ": Error emitting bitcode to file '" << BitcodeFile + << "'!\n"; exit(1); } @@ -299,18 +301,20 @@ std::string BugDriver::executeProgram(const Module *Program, if (AI == 0) AI = Interpreter; assert(AI && "Interpreter should have been created already!"); bool CreatedBitcode = false; - std::string ErrMsg; if (BitcodeFile.empty()) { // Emit the program to a bitcode file... - sys::Path uniqueFilename(OutputPrefix + "-test-program.bc"); - if (uniqueFilename.makeUnique(true, &ErrMsg)) { + SmallString<128> UniqueFilename; + int UniqueFD; + error_code EC = sys::fs::createUniqueFile( + OutputPrefix + "-test-program-%%%%%%%.bc", UniqueFD, UniqueFilename); + if (EC) { errs() << ToolName << ": Error making unique filename: " - << ErrMsg << "!\n"; + << EC.message() << "!\n"; exit(1); } - BitcodeFile = uniqueFilename.str(); + BitcodeFile = UniqueFilename.str(); - if (writeProgramToFile(BitcodeFile, Program)) { + if (writeProgramToFile(BitcodeFile, UniqueFD, Program)) { errs() << ToolName << ": Error emitting bitcode to file '" << BitcodeFile << "'!\n"; exit(1); @@ -319,20 +323,21 @@ std::string BugDriver::executeProgram(const Module *Program, } // Remove the temporary bitcode file when we are done. - sys::Path BitcodePath(BitcodeFile); - FileRemover BitcodeFileRemover(BitcodePath.str(), + std::string BitcodePath(BitcodeFile); + FileRemover BitcodeFileRemover(BitcodePath, CreatedBitcode && !SaveTemps); - if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output"; + if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output-%%%%%%%"; // Check to see if this is a valid output filename... - sys::Path uniqueFile(OutputFile); - if (uniqueFile.makeUnique(true, &ErrMsg)) { + SmallString<128> UniqueFile; + error_code EC = sys::fs::createUniqueFile(OutputFile, UniqueFile); + if (EC) { errs() << ToolName << ": Error making unique filename: " - << ErrMsg << "\n"; + << EC.message() << "\n"; exit(1); } - OutputFile = uniqueFile.str(); + OutputFile = UniqueFile.str(); // Figure out which shared objects to run, if any. std::vector SharedObjs(AdditionalSOs); @@ -380,7 +385,7 @@ std::string BugDriver::executeProgramSafely(const Module *Program, std::string BugDriver::compileSharedObject(const std::string &BitcodeFile, std::string &Error) { assert(Interpreter && "Interpreter should have been created already!"); - sys::Path OutputFile; + std::string OutputFile; // Using the known-good backend. GCC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile, @@ -389,7 +394,7 @@ std::string BugDriver::compileSharedObject(const std::string &BitcodeFile, return ""; std::string SharedObjectFile; - bool Failure = gcc->MakeSharedObject(OutputFile.str(), FT, SharedObjectFile, + bool Failure = gcc->MakeSharedObject(OutputFile, FT, SharedObjectFile, AdditionalLinkerArgs, Error); if (!Error.empty()) return ""; @@ -397,7 +402,7 @@ std::string BugDriver::compileSharedObject(const std::string &BitcodeFile, exit(1); // Remove the intermediate C file - OutputFile.eraseFromDisk(); + sys::fs::remove(OutputFile); return "./" + SharedObjectFile; } @@ -439,15 +444,15 @@ bool BugDriver::diffProgram(const Module *Program, bool RemoveBitcode, std::string *ErrMsg) const { // Execute the program, generating an output file... - sys::Path Output(executeProgram(Program, "", BitcodeFile, SharedObject, 0, - ErrMsg)); + std::string Output( + executeProgram(Program, "", BitcodeFile, SharedObject, 0, ErrMsg)); if (!ErrMsg->empty()) return false; std::string Error; bool FilesDifferent = false; - if (int Diff = DiffFilesWithTolerance(sys::Path(ReferenceOutputFile), - sys::Path(Output.str()), + if (int Diff = DiffFilesWithTolerance(ReferenceOutputFile, + Output, AbsTolerance, RelTolerance, &Error)) { if (Diff == 2) { errs() << "While diffing output: " << Error << '\n'; @@ -457,12 +462,12 @@ bool BugDriver::diffProgram(const Module *Program, } else { // Remove the generated output if there are no differences. - Output.eraseFromDisk(); + sys::fs::remove(Output); } // Remove the bitcode file if we are supposed to. if (RemoveBitcode) - sys::Path(BitcodeFile).eraseFromDisk(); + sys::fs::remove(BitcodeFile); return FilesDifferent; } diff --git a/contrib/llvm/tools/bugpoint/ExtractFunction.cpp b/contrib/llvm/tools/bugpoint/ExtractFunction.cpp index bb27767..2098928 100644 --- a/contrib/llvm/tools/bugpoint/ExtractFunction.cpp +++ b/contrib/llvm/tools/bugpoint/ExtractFunction.cpp @@ -363,25 +363,19 @@ llvm::SplitFunctionsOutOfModule(Module *M, Module *BugDriver::ExtractMappedBlocksFromModule(const std::vector &BBs, Module *M) { - sys::Path uniqueFilename(OutputPrefix + "-extractblocks"); - std::string ErrMsg; - if (uniqueFilename.createTemporaryFileOnDisk(true, &ErrMsg)) { + SmallString<128> Filename; + int FD; + error_code EC = sys::fs::createUniqueFile( + OutputPrefix + "-extractblocks%%%%%%%", FD, Filename); + if (EC) { outs() << "*** Basic Block extraction failed!\n"; - errs() << "Error creating temporary file: " << ErrMsg << "\n"; + errs() << "Error creating temporary file: " << EC.message() << "\n"; EmitProgressBitcode(M, "basicblockextractfail", true); return 0; } - sys::RemoveFileOnSignal(uniqueFilename); + sys::RemoveFileOnSignal(Filename); - std::string ErrorInfo; - tool_output_file BlocksToNotExtractFile(uniqueFilename.c_str(), ErrorInfo); - if (!ErrorInfo.empty()) { - outs() << "*** Basic Block extraction failed!\n"; - errs() << "Error writing list of blocks to not extract: " << ErrorInfo - << "\n"; - EmitProgressBitcode(M, "basicblockextractfail", true); - return 0; - } + tool_output_file BlocksToNotExtractFile(Filename.c_str(), FD); for (std::vector::const_iterator I = BBs.begin(), E = BBs.end(); I != E; ++I) { BasicBlock *BB = *I; @@ -393,22 +387,22 @@ Module *BugDriver::ExtractMappedBlocksFromModule(const } BlocksToNotExtractFile.os().close(); if (BlocksToNotExtractFile.os().has_error()) { - errs() << "Error writing list of blocks to not extract: " << ErrorInfo - << "\n"; + errs() << "Error writing list of blocks to not extract\n"; EmitProgressBitcode(M, "basicblockextractfail", true); BlocksToNotExtractFile.os().clear_error(); return 0; } BlocksToNotExtractFile.keep(); - std::string uniqueFN = "--extract-blocks-file=" + uniqueFilename.str(); + std::string uniqueFN = "--extract-blocks-file="; + uniqueFN += Filename.str(); const char *ExtraArg = uniqueFN.c_str(); std::vector PI; PI.push_back("extract-blocks"); Module *Ret = runPassesOn(M, PI, false, 1, &ExtraArg); - uniqueFilename.eraseFromDisk(); // Free disk space + sys::fs::remove(Filename.c_str()); if (Ret == 0) { outs() << "*** Basic Block extraction failed, please report a bug!\n"; diff --git a/contrib/llvm/tools/bugpoint/FindBugs.cpp b/contrib/llvm/tools/bugpoint/FindBugs.cpp index a291f9f..e2941f6 100644 --- a/contrib/llvm/tools/bugpoint/FindBugs.cpp +++ b/contrib/llvm/tools/bugpoint/FindBugs.cpp @@ -17,6 +17,7 @@ #include "BugDriver.h" #include "ToolRunner.h" #include "llvm/Pass.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -103,7 +104,7 @@ bool BugDriver::runManyPasses(const std::vector &AllPasses, } outs() << "\n*** diff'd output matches!\n"; - sys::Path(Filename).eraseFromDisk(); + sys::fs::remove(Filename); outs() << "\n\n"; num++; diff --git a/contrib/llvm/tools/bugpoint/Miscompilation.cpp b/contrib/llvm/tools/bugpoint/Miscompilation.cpp index c676a05..771ec34 100644 --- a/contrib/llvm/tools/bugpoint/Miscompilation.cpp +++ b/contrib/llvm/tools/bugpoint/Miscompilation.cpp @@ -120,7 +120,7 @@ ReduceMiscompilingPasses::doTest(std::vector &Prefix, return InternalError; if (Diff) { outs() << " nope.\n"; - sys::Path(BitcodeResult).eraseFromDisk(); + sys::fs::remove(BitcodeResult); return KeepPrefix; } outs() << " yup.\n"; // No miscompilation! @@ -130,12 +130,12 @@ ReduceMiscompilingPasses::doTest(std::vector &Prefix, // OwningPtr PrefixOutput(ParseInputFile(BitcodeResult, BD.getContext())); - if (PrefixOutput == 0) { + if (!PrefixOutput) { errs() << BD.getToolName() << ": Error reading bitcode file '" << BitcodeResult << "'!\n"; exit(1); } - sys::Path(BitcodeResult).eraseFromDisk(); // No longer need the file on disk + sys::fs::remove(BitcodeResult); // Don't check if there are no passes in the suffix. if (Suffix.empty()) @@ -337,8 +337,13 @@ static bool ExtractLoops(BugDriver &BD, false, Error, Failure); if (!New) return false; + // Delete the original and set the new program. - delete BD.swapProgramIn(New); + Module *Old = BD.swapProgramIn(New); + for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) + MiscompiledFunctions[i] = cast(VMap[MiscompiledFunctions[i]]); + delete Old; + if (Failure) { BD.switchToInterpreter(AI); @@ -366,21 +371,51 @@ static bool ExtractLoops(BugDriver &BD, outs() << " Testing after loop extraction:\n"; // Clone modules, the tester function will free them. - Module *TOLEBackup = CloneModule(ToOptimizeLoopExtracted); - Module *TNOBackup = CloneModule(ToNotOptimize); + Module *TOLEBackup = CloneModule(ToOptimizeLoopExtracted, VMap); + Module *TNOBackup = CloneModule(ToNotOptimize, VMap); + + for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) + MiscompiledFunctions[i] = cast(VMap[MiscompiledFunctions[i]]); + Failure = TestFn(BD, ToOptimizeLoopExtracted, ToNotOptimize, Error); if (!Error.empty()) return false; + + ToOptimizeLoopExtracted = TOLEBackup; + ToNotOptimize = TNOBackup; + if (!Failure) { outs() << "*** Loop extraction masked the problem. Undoing.\n"; // If the program is not still broken, then loop extraction did something // that masked the error. Stop loop extraction now. - delete TOLEBackup; - delete TNOBackup; + + std::vector > MisCompFunctions; + for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) { + Function *F = MiscompiledFunctions[i]; + MisCompFunctions.push_back(std::make_pair(F->getName(), + F->getFunctionType())); + } + + std::string ErrorMsg; + if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted, + Linker::DestroySource, &ErrorMsg)){ + errs() << BD.getToolName() << ": Error linking modules together:" + << ErrorMsg << '\n'; + exit(1); + } + + MiscompiledFunctions.clear(); + for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { + Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first); + + assert(NewF && "Function not found??"); + MiscompiledFunctions.push_back(NewF); + } + + delete ToOptimizeLoopExtracted; + BD.setNewProgram(ToNotOptimize); return MadeChange; } - ToOptimizeLoopExtracted = TOLEBackup; - ToNotOptimize = TNOBackup; outs() << "*** Loop extraction successful!\n"; @@ -926,14 +961,16 @@ static bool TestCodeGenerator(BugDriver &BD, Module *Test, Module *Safe, std::string &Error) { CleanupAndPrepareModules(BD, Test, Safe); - sys::Path TestModuleBC("bugpoint.test.bc"); - std::string ErrMsg; - if (TestModuleBC.makeUnique(true, &ErrMsg)) { + SmallString<128> TestModuleBC; + int TestModuleFD; + error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc", + TestModuleFD, TestModuleBC); + if (EC) { errs() << BD.getToolName() << "Error making unique filename: " - << ErrMsg << "\n"; + << EC.message() << "\n"; exit(1); } - if (BD.writeProgramToFile(TestModuleBC.str(), Test)) { + if (BD.writeProgramToFile(TestModuleBC.str(), TestModuleFD, Test)) { errs() << "Error writing bitcode to `" << TestModuleBC.str() << "'\nExiting."; exit(1); @@ -943,14 +980,17 @@ static bool TestCodeGenerator(BugDriver &BD, Module *Test, Module *Safe, FileRemover TestModuleBCRemover(TestModuleBC.str(), !SaveTemps); // Make the shared library - sys::Path SafeModuleBC("bugpoint.safe.bc"); - if (SafeModuleBC.makeUnique(true, &ErrMsg)) { + SmallString<128> SafeModuleBC; + int SafeModuleFD; + EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD, + SafeModuleBC); + if (EC) { errs() << BD.getToolName() << "Error making unique filename: " - << ErrMsg << "\n"; + << EC.message() << "\n"; exit(1); } - if (BD.writeProgramToFile(SafeModuleBC.str(), Safe)) { + if (BD.writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, Safe)) { errs() << "Error writing bitcode to `" << SafeModuleBC.str() << "'\nExiting."; exit(1); @@ -1015,15 +1055,17 @@ bool BugDriver::debugCodeGenerator(std::string *Error) { // Condition the modules CleanupAndPrepareModules(*this, ToCodeGen, ToNotCodeGen); - sys::Path TestModuleBC("bugpoint.test.bc"); - std::string ErrMsg; - if (TestModuleBC.makeUnique(true, &ErrMsg)) { + SmallString<128> TestModuleBC; + int TestModuleFD; + error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc", + TestModuleFD, TestModuleBC); + if (EC) { errs() << getToolName() << "Error making unique filename: " - << ErrMsg << "\n"; + << EC.message() << "\n"; exit(1); } - if (writeProgramToFile(TestModuleBC.str(), ToCodeGen)) { + if (writeProgramToFile(TestModuleBC.str(), TestModuleFD, ToCodeGen)) { errs() << "Error writing bitcode to `" << TestModuleBC.str() << "'\nExiting."; exit(1); @@ -1031,14 +1073,17 @@ bool BugDriver::debugCodeGenerator(std::string *Error) { delete ToCodeGen; // Make the shared library - sys::Path SafeModuleBC("bugpoint.safe.bc"); - if (SafeModuleBC.makeUnique(true, &ErrMsg)) { + SmallString<128> SafeModuleBC; + int SafeModuleFD; + EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD, + SafeModuleBC); + if (EC) { errs() << getToolName() << "Error making unique filename: " - << ErrMsg << "\n"; + << EC.message() << "\n"; exit(1); } - if (writeProgramToFile(SafeModuleBC.str(), ToNotCodeGen)) { + if (writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, ToNotCodeGen)) { errs() << "Error writing bitcode to `" << SafeModuleBC.str() << "'\nExiting."; exit(1); diff --git a/contrib/llvm/tools/bugpoint/OptimizerDriver.cpp b/contrib/llvm/tools/bugpoint/OptimizerDriver.cpp index 87dc9f3..20c609c 100644 --- a/contrib/llvm/tools/bugpoint/OptimizerDriver.cpp +++ b/contrib/llvm/tools/bugpoint/OptimizerDriver.cpp @@ -33,6 +33,7 @@ #include "llvm/Support/PluginLoader.h" #include + using namespace llvm; namespace llvm { @@ -43,25 +44,36 @@ namespace { // ChildOutput - This option captures the name of the child output file that // is set up by the parent bugpoint process cl::opt ChildOutput("child-output", cl::ReallyHidden); + cl::opt OptCmd("opt-command", cl::init(""), + cl::desc("Path to opt. (default: search path " + "for 'opt'.)")); } /// writeProgramToFile - This writes the current "Program" to the named bitcode /// file. If an error occurs, true is returned. /// +static bool writeProgramToFileAux(tool_output_file &Out, const Module *M) { + WriteBitcodeToFile(M, Out.os()); + Out.os().close(); + if (!Out.os().has_error()) { + Out.keep(); + return false; + } + return true; +} + +bool BugDriver::writeProgramToFile(const std::string &Filename, int FD, + const Module *M) const { + tool_output_file Out(Filename.c_str(), FD); + return writeProgramToFileAux(Out, M); +} + bool BugDriver::writeProgramToFile(const std::string &Filename, const Module *M) const { std::string ErrInfo; - tool_output_file Out(Filename.c_str(), ErrInfo, - raw_fd_ostream::F_Binary); - if (ErrInfo.empty()) { - WriteBitcodeToFile(M, Out.os()); - Out.os().close(); - if (!Out.os().has_error()) { - Out.keep(); - return false; - } - } - Out.os().clear_error(); + tool_output_file Out(Filename.c_str(), ErrInfo, sys::fs::F_Binary); + if (ErrInfo.empty()) + return writeProgramToFileAux(Out, M); return true; } @@ -114,41 +126,38 @@ bool BugDriver::runPasses(Module *Program, const char * const *ExtraArgs) const { // setup the output file name outs().flush(); - sys::Path uniqueFilename(OutputPrefix + "-output.bc"); - std::string ErrMsg; - if (uniqueFilename.makeUnique(true, &ErrMsg)) { + SmallString<128> UniqueFilename; + error_code EC = sys::fs::createUniqueFile( + OutputPrefix + "-output-%%%%%%%.bc", UniqueFilename); + if (EC) { errs() << getToolName() << ": Error making unique filename: " - << ErrMsg << "\n"; - return(1); + << EC.message() << "\n"; + return 1; } - OutputFilename = uniqueFilename.str(); + OutputFilename = UniqueFilename.str(); // set up the input file name - sys::Path inputFilename(OutputPrefix + "-input.bc"); - if (inputFilename.makeUnique(true, &ErrMsg)) { + SmallString<128> InputFilename; + int InputFD; + EC = sys::fs::createUniqueFile(OutputPrefix + "-input-%%%%%%%.bc", InputFD, + InputFilename); + if (EC) { errs() << getToolName() << ": Error making unique filename: " - << ErrMsg << "\n"; - return(1); + << EC.message() << "\n"; + return 1; } - std::string ErrInfo; - tool_output_file InFile(inputFilename.c_str(), ErrInfo, - raw_fd_ostream::F_Binary); - + tool_output_file InFile(InputFilename.c_str(), InputFD); - if (!ErrInfo.empty()) { - errs() << "Error opening bitcode file: " << inputFilename.str() << "\n"; - return 1; - } WriteBitcodeToFile(Program, InFile.os()); InFile.os().close(); if (InFile.os().has_error()) { - errs() << "Error writing bitcode file: " << inputFilename.str() << "\n"; + errs() << "Error writing bitcode file: " << InputFilename << "\n"; InFile.os().clear_error(); return 1; } - sys::Path tool = sys::Program::FindProgramByName("opt"); + std::string tool = OptCmd.empty()? sys::FindProgramByName("opt") : OptCmd; if (tool.empty()) { errs() << "Cannot find `opt' in PATH!\n"; return 1; @@ -159,14 +168,13 @@ bool BugDriver::runPasses(Module *Program, // setup the child process' arguments SmallVector Args; - std::string Opt = tool.str(); if (UseValgrind) { Args.push_back("valgrind"); Args.push_back("--error-exitcode=1"); Args.push_back("-q"); Args.push_back(tool.c_str()); } else - Args.push_back(Opt.c_str()); + Args.push_back(tool.c_str()); Args.push_back("-o"); Args.push_back(OutputFilename.c_str()); @@ -183,7 +191,7 @@ bool BugDriver::runPasses(Module *Program, for (std::vector::const_iterator I = pass_args.begin(), E = pass_args.end(); I != E; ++I ) Args.push_back(I->c_str()); - Args.push_back(inputFilename.c_str()); + Args.push_back(InputFilename.c_str()); for (unsigned i = 0; i < NumExtraArgs; ++i) Args.push_back(*ExtraArgs); Args.push_back(0); @@ -194,27 +202,28 @@ bool BugDriver::runPasses(Module *Program, errs() << "\n"; ); - sys::Path prog; + std::string Prog; if (UseValgrind) - prog = sys::Program::FindProgramByName("valgrind"); + Prog = sys::FindProgramByName("valgrind"); else - prog = tool; + Prog = tool; // Redirect stdout and stderr to nowhere if SilencePasses is given - sys::Path Nowhere; - const sys::Path *Redirects[3] = {0, &Nowhere, &Nowhere}; + StringRef Nowhere; + const StringRef *Redirects[3] = {0, &Nowhere, &Nowhere}; - int result = sys::Program::ExecuteAndWait(prog, Args.data(), 0, - (SilencePasses ? Redirects : 0), - Timeout, MemoryLimit, &ErrMsg); + std::string ErrMsg; + int result = sys::ExecuteAndWait(Prog, Args.data(), 0, + (SilencePasses ? Redirects : 0), Timeout, + MemoryLimit, &ErrMsg); // If we are supposed to delete the bitcode file or if the passes crashed, // remove it now. This may fail if the file was never created, but that's ok. if (DeleteOutput || result != 0) - sys::Path(OutputFilename).eraseFromDisk(); + sys::fs::remove(OutputFilename); // Remove the temporary input file as well - inputFilename.eraseFromDisk(); + sys::fs::remove(InputFilename.c_str()); if (!Quiet) { if (result == 0) @@ -262,6 +271,6 @@ Module *BugDriver::runPassesOn(Module *M, << BitcodeResult << "'!\n"; exit(1); } - sys::Path(BitcodeResult).eraseFromDisk(); // No longer need the file on disk + sys::fs::remove(BitcodeResult); return Ret; } diff --git a/contrib/llvm/tools/bugpoint/ToolRunner.cpp b/contrib/llvm/tools/bugpoint/ToolRunner.cpp index 735061d..254d997 100644 --- a/contrib/llvm/tools/bugpoint/ToolRunner.cpp +++ b/contrib/llvm/tools/bugpoint/ToolRunner.cpp @@ -16,6 +16,7 @@ #include "llvm/Config/config.h" // for HAVE_LINK_R #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Support/Program.h" #include "llvm/Support/raw_ostream.h" @@ -53,18 +54,15 @@ namespace { /// RunProgramWithTimeout - This function provides an alternate interface /// to the sys::Program::ExecuteAndWait interface. /// @see sys::Program::ExecuteAndWait -static int RunProgramWithTimeout(const sys::Path &ProgramPath, +static int RunProgramWithTimeout(StringRef ProgramPath, const char **Args, - const sys::Path &StdInFile, - const sys::Path &StdOutFile, - const sys::Path &StdErrFile, + StringRef StdInFile, + StringRef StdOutFile, + StringRef StdErrFile, unsigned NumSeconds = 0, unsigned MemoryLimit = 0, std::string *ErrMsg = 0) { - const sys::Path* redirects[3]; - redirects[0] = &StdInFile; - redirects[1] = &StdOutFile; - redirects[2] = &StdErrFile; + const StringRef *Redirects[3] = { &StdInFile, &StdOutFile, &StdErrFile }; #if 0 // For debug purposes { @@ -75,9 +73,8 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath, } #endif - return - sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects, - NumSeconds, MemoryLimit, ErrMsg); + return sys::ExecuteAndWait(ProgramPath, Args, 0, Redirects, + NumSeconds, MemoryLimit, ErrMsg); } /// RunProgramRemotelyWithTimeout - This function runs the given program @@ -86,17 +83,14 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath, /// fails. Remote client is required to return 255 if it failed or program exit /// code otherwise. /// @see sys::Program::ExecuteAndWait -static int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath, +static int RunProgramRemotelyWithTimeout(StringRef RemoteClientPath, const char **Args, - const sys::Path &StdInFile, - const sys::Path &StdOutFile, - const sys::Path &StdErrFile, + StringRef StdInFile, + StringRef StdOutFile, + StringRef StdErrFile, unsigned NumSeconds = 0, unsigned MemoryLimit = 0) { - const sys::Path* redirects[3]; - redirects[0] = &StdInFile; - redirects[1] = &StdOutFile; - redirects[2] = &StdErrFile; + const StringRef *Redirects[3] = { &StdInFile, &StdOutFile, &StdErrFile }; #if 0 // For debug purposes { @@ -108,8 +102,8 @@ static int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath, #endif // Run the program remotely with the remote client - int ReturnCode = sys::Program::ExecuteAndWait(RemoteClientPath, Args, - 0, redirects, NumSeconds, MemoryLimit); + int ReturnCode = sys::ExecuteAndWait(RemoteClientPath, Args, 0, + Redirects, NumSeconds, MemoryLimit); // Has the remote client fail? if (255 == ReturnCode) { @@ -120,7 +114,8 @@ static int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath, OS << "\n"; // The error message is in the output file, let's print it out from there. - std::ifstream ErrorFile(StdOutFile.c_str()); + std::string StdOutFileName = StdOutFile.str(); + std::ifstream ErrorFile(StdOutFileName.c_str()); if (ErrorFile) { std::copy(std::istreambuf_iterator(ErrorFile), std::istreambuf_iterator(), @@ -134,7 +129,7 @@ static int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath, return ReturnCode; } -static std::string ProcessFailure(sys::Path ProgPath, const char** Args, +static std::string ProcessFailure(StringRef ProgPath, const char** Args, unsigned Timeout = 0, unsigned MemoryLimit = 0) { std::ostringstream OS; @@ -144,14 +139,16 @@ static std::string ProcessFailure(sys::Path ProgPath, const char** Args, OS << "\n"; // Rerun the compiler, capturing any error messages to print them. - sys::Path ErrorFilename("bugpoint.program_error_messages"); - std::string ErrMsg; - if (ErrorFilename.makeUnique(true, &ErrMsg)) { - errs() << "Error making unique filename: " << ErrMsg << "\n"; + SmallString<128> ErrorFilename; + int ErrorFD; + error_code EC = sys::fs::createTemporaryFile( + "bugpoint.program_error_messages", "", ErrorFD, ErrorFilename); + if (EC) { + errs() << "Error making unique filename: " << EC.message() << "\n"; exit(1); } - RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename, - ErrorFilename, Timeout, MemoryLimit); + RunProgramWithTimeout(ProgPath, Args, "", ErrorFilename.str(), + ErrorFilename.str(), Timeout, MemoryLimit); // FIXME: check return code ? // Print out the error messages generated by GCC if possible... @@ -163,7 +160,7 @@ static std::string ProcessFailure(sys::Path ProgPath, const char** Args, ErrorFile.close(); } - ErrorFilename.eraseFromDisk(); + sys::fs::remove(ErrorFilename.c_str()); return OS.str(); } @@ -229,19 +226,50 @@ int LLI::ExecuteProgram(const std::string &Bitcode, errs() << " " << LLIArgs[i]; errs() << "\n"; ); - return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0], - sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile), + return RunProgramWithTimeout(LLIPath, &LLIArgs[0], + InputFile, OutputFile, OutputFile, Timeout, MemoryLimit, Error); } void AbstractInterpreter::anchor() { } +#if defined(LLVM_ON_UNIX) +const char EXESuffix[] = ""; +#elif defined (LLVM_ON_WIN32) +const char EXESuffix[] = "exe"; +#endif + +/// Prepend the path to the program being executed +/// to \p ExeName, given the value of argv[0] and the address of main() +/// itself. This allows us to find another LLVM tool if it is built in the same +/// directory. An empty string is returned on error; note that this function +/// just mainpulates the path and doesn't check for executability. +/// @brief Find a named executable. +static std::string PrependMainExecutablePath(const std::string &ExeName, + const char *Argv0, + void *MainAddr) { + // Check the directory that the calling program is in. We can do + // this if ProgramPath contains at least one / character, indicating that it + // is a relative path to the executable itself. + std::string Main = sys::fs::getMainExecutable(Argv0, MainAddr); + StringRef Result = sys::path::parent_path(Main); + + if (!Result.empty()) { + SmallString<128> Storage = Result; + sys::path::append(Storage, ExeName); + sys::path::replace_extension(Storage, EXESuffix); + return Storage.str(); + } + + return Result.str(); +} + // LLI create method - Try to find the LLI executable AbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0, std::string &Message, const std::vector *ToolArgs) { std::string LLIPath = - PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createLLI).str(); + PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t) & createLLI); if (!LLIPath.empty()) { Message = "Found lli: " + LLIPath + "\n"; return new LLI(LLIPath, ToolArgs); @@ -305,10 +333,10 @@ void CustomCompiler::compileProgram(const std::string &Bitcode, for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i) ProgramArgs.push_back(CompilerArgs[i].c_str()); - if (RunProgramWithTimeout( sys::Path(CompilerCommand), &ProgramArgs[0], - sys::Path(), sys::Path(), sys::Path(), + if (RunProgramWithTimeout(CompilerCommand, &ProgramArgs[0], + "", "", "", Timeout, MemoryLimit, Error)) - *Error = ProcessFailure(sys::Path(CompilerCommand), &ProgramArgs[0], + *Error = ProcessFailure(CompilerCommand, &ProgramArgs[0], Timeout, MemoryLimit); } @@ -363,9 +391,9 @@ int CustomExecutor::ExecuteProgram(const std::string &Bitcode, ProgramArgs.push_back(Args[i].c_str()); return RunProgramWithTimeout( - sys::Path(ExecutionCommand), - &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile), - sys::Path(OutputFile), Timeout, MemoryLimit, Error); + ExecutionCommand, + &ProgramArgs[0], InputFile, OutputFile, + OutputFile, Timeout, MemoryLimit, Error); } // Tokenize the CommandLine to the command and the args to allow @@ -398,7 +426,7 @@ static void lexCommand(std::string &Message, const std::string &CommandLine, pos = CommandLine.find_first_of(delimiters, lastPos); } - CmdPath = sys::Program::FindProgramByName(Command).str(); + CmdPath = sys::FindProgramByName(Command); if (CmdPath.empty()) { Message = std::string("Cannot find '") + Command + @@ -444,16 +472,18 @@ AbstractInterpreter *AbstractInterpreter::createCustomExecutor( // LLC Implementation of AbstractIntepreter interface // GCC::FileType LLC::OutputCode(const std::string &Bitcode, - sys::Path &OutputAsmFile, std::string &Error, + std::string &OutputAsmFile, std::string &Error, unsigned Timeout, unsigned MemoryLimit) { const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s"); - sys::Path uniqueFile(Bitcode + Suffix); - std::string ErrMsg; - if (uniqueFile.makeUnique(true, &ErrMsg)) { - errs() << "Error making unique filename: " << ErrMsg << "\n"; + + SmallString<128> UniqueFile; + error_code EC = + sys::fs::createUniqueFile(Bitcode + "-%%%%%%%" + Suffix, UniqueFile); + if (EC) { + errs() << "Error making unique filename: " << EC.message() << "\n"; exit(1); } - OutputAsmFile = uniqueFile; + OutputAsmFile = UniqueFile.str(); std::vector LLCArgs; LLCArgs.push_back(LLCPath.c_str()); @@ -477,19 +507,19 @@ GCC::FileType LLC::OutputCode(const std::string &Bitcode, errs() << " " << LLCArgs[i]; errs() << "\n"; ); - if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0], - sys::Path(), sys::Path(), sys::Path(), + if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], + "", "", "", Timeout, MemoryLimit)) - Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0], + Error = ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit); return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile; } void LLC::compileProgram(const std::string &Bitcode, std::string *Error, unsigned Timeout, unsigned MemoryLimit) { - sys::Path OutputAsmFile; + std::string OutputAsmFile; OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, MemoryLimit); - OutputAsmFile.eraseFromDisk(); + sys::fs::remove(OutputAsmFile); } int LLC::ExecuteProgram(const std::string &Bitcode, @@ -502,16 +532,16 @@ int LLC::ExecuteProgram(const std::string &Bitcode, unsigned Timeout, unsigned MemoryLimit) { - sys::Path OutputAsmFile; + std::string OutputAsmFile; GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, MemoryLimit); - FileRemover OutFileRemover(OutputAsmFile.str(), !SaveTemps); + FileRemover OutFileRemover(OutputAsmFile, !SaveTemps); std::vector GCCArgs(ArgsForGCC); GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end()); // Assuming LLC worked, compile the result with GCC and run it. - return gcc->ExecuteProgram(OutputAsmFile.str(), Args, FileKind, + return gcc->ExecuteProgram(OutputAsmFile, Args, FileKind, InputFile, OutputFile, Error, GCCArgs, Timeout, MemoryLimit); } @@ -525,7 +555,7 @@ LLC *AbstractInterpreter::createLLC(const char *Argv0, const std::vector *GCCArgs, bool UseIntegratedAssembler) { std::string LLCPath = - PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC).str(); + PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t) & createLLC); if (LLCPath.empty()) { Message = "Cannot find `llc' in executable directory!\n"; return 0; @@ -603,8 +633,8 @@ int JIT::ExecuteProgram(const std::string &Bitcode, errs() << "\n"; ); DEBUG(errs() << "\nSending output to " << OutputFile << "\n"); - return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0], - sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile), + return RunProgramWithTimeout(LLIPath, &JITArgs[0], + InputFile, OutputFile, OutputFile, Timeout, MemoryLimit, Error); } @@ -613,7 +643,7 @@ int JIT::ExecuteProgram(const std::string &Bitcode, AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0, std::string &Message, const std::vector *Args) { std::string LLIPath = - PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT).str(); + PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t) & createJIT); if (!LLIPath.empty()) { Message = "Found lli: " + LLIPath + "\n"; return new JIT(LLIPath, Args); @@ -632,7 +662,7 @@ static bool IsARMArchitecture(std::vector Args) { I = Args.begin(), E = Args.end(); I != E; ++I) { if (StringRef(*I).equals_lower("-arch")) { ++I; - if (I != E && StringRef(*I).substr(0, strlen("arm")).equals_lower("arm")) + if (I != E && StringRef(*I).startswith_lower("arm")) return true; } } @@ -682,10 +712,12 @@ int GCC::ExecuteProgram(const std::string &ProgramFile, GCCArgs.push_back("-x"); GCCArgs.push_back("none"); GCCArgs.push_back("-o"); - sys::Path OutputBinary (ProgramFile+".gcc.exe"); - std::string ErrMsg; - if (OutputBinary.makeUnique(true, &ErrMsg)) { - errs() << "Error making unique filename: " << ErrMsg << "\n"; + + SmallString<128> OutputBinary; + error_code EC = + sys::fs::createUniqueFile(ProgramFile + "-%%%%%%%.gcc.exe", OutputBinary); + if (EC) { + errs() << "Error making unique filename: " << EC.message() << "\n"; exit(1); } GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file... @@ -712,8 +744,7 @@ int GCC::ExecuteProgram(const std::string &ProgramFile, errs() << " " << GCCArgs[i]; errs() << "\n"; ); - if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(), - sys::Path())) { + if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], "", "", "")) { *Error = ProcessFailure(GCCPath, &GCCArgs[0]); return -1; } @@ -724,7 +755,7 @@ int GCC::ExecuteProgram(const std::string &ProgramFile, // ProgramArgs is used. std::string Exec; - if (RemoteClientPath.isEmpty()) + if (RemoteClientPath.empty()) ProgramArgs.push_back(OutputBinary.c_str()); else { ProgramArgs.push_back(RemoteClientPath.c_str()); @@ -766,11 +797,11 @@ int GCC::ExecuteProgram(const std::string &ProgramFile, FileRemover OutputBinaryRemover(OutputBinary.str(), !SaveTemps); - if (RemoteClientPath.isEmpty()) { + if (RemoteClientPath.empty()) { DEBUG(errs() << ""); - int ExitCode = RunProgramWithTimeout(OutputBinary, &ProgramArgs[0], - sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile), - Timeout, MemoryLimit, Error); + int ExitCode = RunProgramWithTimeout(OutputBinary.str(), &ProgramArgs[0], + InputFile, OutputFile, OutputFile, + Timeout, MemoryLimit, Error); // Treat a signal (usually SIGSEGV) or timeout as part of the program output // so that crash-causing miscompilation is handled seamlessly. if (ExitCode < -1) { @@ -782,9 +813,9 @@ int GCC::ExecuteProgram(const std::string &ProgramFile, return ExitCode; } else { outs() << ""; outs().flush(); - return RunProgramRemotelyWithTimeout(sys::Path(RemoteClientPath), - &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile), - sys::Path(OutputFile), Timeout, MemoryLimit); + return RunProgramRemotelyWithTimeout(RemoteClientPath, + &ProgramArgs[0], InputFile, OutputFile, + OutputFile, Timeout, MemoryLimit); } } @@ -792,13 +823,14 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType, std::string &OutputFile, const std::vector &ArgsForGCC, std::string &Error) { - sys::Path uniqueFilename(InputFile+LTDL_SHLIB_EXT); - std::string ErrMsg; - if (uniqueFilename.makeUnique(true, &ErrMsg)) { - errs() << "Error making unique filename: " << ErrMsg << "\n"; + SmallString<128> UniqueFilename; + error_code EC = sys::fs::createUniqueFile( + InputFile + "-%%%%%%%" + LTDL_SHLIB_EXT, UniqueFilename); + if (EC) { + errs() << "Error making unique filename: " << EC.message() << "\n"; exit(1); } - OutputFile = uniqueFilename.str(); + OutputFile = UniqueFilename.str(); std::vector GCCArgs; @@ -862,8 +894,7 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType, errs() << " " << GCCArgs[i]; errs() << "\n"; ); - if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(), - sys::Path())) { + if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], "", "", "")) { Error = ProcessFailure(GCCPath, &GCCArgs[0]); return 1; } @@ -875,16 +906,16 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType, GCC *GCC::create(std::string &Message, const std::string &GCCBinary, const std::vector *Args) { - sys::Path GCCPath = sys::Program::FindProgramByName(GCCBinary); - if (GCCPath.isEmpty()) { + std::string GCCPath = sys::FindProgramByName(GCCBinary); + if (GCCPath.empty()) { Message = "Cannot find `"+ GCCBinary +"' in PATH!\n"; return 0; } - sys::Path RemoteClientPath; + std::string RemoteClientPath; if (!RemoteClient.empty()) - RemoteClientPath = sys::Program::FindProgramByName(RemoteClient); + RemoteClientPath = sys::FindProgramByName(RemoteClient); - Message = "Found gcc: " + GCCPath.str() + "\n"; + Message = "Found gcc: " + GCCPath + "\n"; return new GCC(GCCPath, RemoteClientPath, Args); } diff --git a/contrib/llvm/tools/bugpoint/ToolRunner.h b/contrib/llvm/tools/bugpoint/ToolRunner.h index bb83ce4..bc2be46 100644 --- a/contrib/llvm/tools/bugpoint/ToolRunner.h +++ b/contrib/llvm/tools/bugpoint/ToolRunner.h @@ -30,17 +30,16 @@ namespace llvm { extern cl::opt SaveTemps; extern Triple TargetTriple; -class CBE; class LLC; //===---------------------------------------------------------------------===// // GCC abstraction // class GCC { - sys::Path GCCPath; // The path to the gcc executable. - sys::Path RemoteClientPath; // The path to the rsh / ssh executable. + std::string GCCPath; // The path to the gcc executable. + std::string RemoteClientPath; // The path to the rsh / ssh executable. std::vector gccArgs; // GCC-specific arguments. - GCC(const sys::Path &gccPath, const sys::Path &RemotePath, + GCC(StringRef gccPath, StringRef RemotePath, const std::vector *GCCArgs) : GCCPath(gccPath), RemoteClientPath(RemotePath) { if (GCCArgs) gccArgs = *GCCArgs; @@ -88,10 +87,6 @@ public: class AbstractInterpreter { virtual void anchor(); public: - static CBE *createCBE(const char *Argv0, std::string &Message, - const std::string &GCCBinary, - const std::vector *Args = 0, - const std::vector *GCCArgs = 0); static LLC *createLLC(const char *Argv0, std::string &Message, const std::string &GCCBinary, const std::vector *Args = 0, @@ -126,7 +121,7 @@ public: /// fails, it sets Error, otherwise, this function returns the type of code /// emitted. virtual GCC::FileType OutputCode(const std::string &Bitcode, - sys::Path &OutFile, std::string &Error, + std::string &OutFile, std::string &Error, unsigned Timeout = 0, unsigned MemoryLimit = 0) { Error = "OutputCode not supported by this AbstractInterpreter!"; @@ -152,51 +147,6 @@ public: }; //===---------------------------------------------------------------------===// -// CBE Implementation of AbstractIntepreter interface -// -class CBE : public AbstractInterpreter { - sys::Path LLCPath; // The path to the `llc' executable. - std::vector ToolArgs; // Extra args to pass to LLC. - GCC *gcc; -public: - CBE(const sys::Path &llcPath, GCC *Gcc, - const std::vector *Args) - : LLCPath(llcPath), gcc(Gcc) { - ToolArgs.clear (); - if (Args) ToolArgs = *Args; - } - ~CBE() { delete gcc; } - - /// compileProgram - Compile the specified program from bitcode to executable - /// code. This does not produce any output, it is only used when debugging - /// the code generator. Returns false if the code generator fails. - virtual void compileProgram(const std::string &Bitcode, std::string *Error, - unsigned Timeout = 0, unsigned MemoryLimit = 0); - - virtual int ExecuteProgram(const std::string &Bitcode, - const std::vector &Args, - const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, - const std::vector &GCCArgs = - std::vector(), - const std::vector &SharedLibs = - std::vector(), - unsigned Timeout = 0, - unsigned MemoryLimit = 0); - - /// OutputCode - Compile the specified program from bitcode to code - /// understood by the GCC driver (either C or asm). If the code generator - /// fails, it sets Error, otherwise, this function returns the type of code - /// emitted. - virtual GCC::FileType OutputCode(const std::string &Bitcode, - sys::Path &OutFile, std::string &Error, - unsigned Timeout = 0, - unsigned MemoryLimit = 0); -}; - - -//===---------------------------------------------------------------------===// // LLC Implementation of AbstractIntepreter interface // class LLC : public AbstractInterpreter { @@ -238,7 +188,7 @@ public: /// fails, it sets Error, otherwise, this function returns the type of code /// emitted. virtual GCC::FileType OutputCode(const std::string &Bitcode, - sys::Path &OutFile, std::string &Error, + std::string &OutFile, std::string &Error, unsigned Timeout = 0, unsigned MemoryLimit = 0); }; diff --git a/contrib/llvm/tools/bugpoint/bugpoint.cpp b/contrib/llvm/tools/bugpoint/bugpoint.cpp index 5e8fdd1..9bc592e 100644 --- a/contrib/llvm/tools/bugpoint/bugpoint.cpp +++ b/contrib/llvm/tools/bugpoint/bugpoint.cpp @@ -49,8 +49,8 @@ TimeoutValue("timeout", cl::init(300), cl::value_desc("seconds"), static cl::opt MemoryLimit("mlimit", cl::init(-1), cl::value_desc("MBytes"), - cl::desc("Maximum amount of memory to use. 0 disables check." - " Defaults to 100MB (800MB under valgrind).")); + cl::desc("Maximum amount of memory to use. 0 disables check." + " Defaults to 300MB (800MB under valgrind).")); static cl::opt UseValgrind("enable-valgrind", @@ -152,7 +152,7 @@ int main(int argc, char **argv) { if (sys::RunningOnValgrind() || UseValgrind) MemoryLimit = 800; else - MemoryLimit = 100; + MemoryLimit = 300; } BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, diff --git a/contrib/llvm/tools/clang/include/clang-c/CXCompilationDatabase.h b/contrib/llvm/tools/clang/include/clang-c/CXCompilationDatabase.h index ff1ec63..fd65418 100644 --- a/contrib/llvm/tools/clang/include/clang-c/CXCompilationDatabase.h +++ b/contrib/llvm/tools/clang/include/clang-c/CXCompilationDatabase.h @@ -58,7 +58,7 @@ typedef void * CXCompileCommand; */ typedef enum { /* - * \brief No error occured + * \brief No error occurred */ CXCompilationDatabase_NoError = 0, @@ -142,6 +142,24 @@ CINDEX_LINKAGE CXString clang_CompileCommand_getArg(CXCompileCommand, unsigned I); /** + * \brief Get the number of source mappings for the compiler invocation. + */ +CINDEX_LINKAGE unsigned +clang_CompileCommand_getNumMappedSources(CXCompileCommand); + +/** + * \brief Get the I'th mapped source path for the compiler invocation. + */ +CINDEX_LINKAGE CXString +clang_CompileCommand_getMappedSourcePath(CXCompileCommand, unsigned I); + +/** + * \brief Get the I'th mapped source content for the compiler invocation. + */ +CINDEX_LINKAGE CXString +clang_CompileCommand_getMappedSourceContent(CXCompileCommand, unsigned I); + +/** * @} */ diff --git a/contrib/llvm/tools/clang/include/clang-c/CXString.h b/contrib/llvm/tools/clang/include/clang-c/CXString.h index 34cab5e..592c4dc 100644 --- a/contrib/llvm/tools/clang/include/clang-c/CXString.h +++ b/contrib/llvm/tools/clang/include/clang-c/CXString.h @@ -46,7 +46,7 @@ typedef struct { CINDEX_LINKAGE const char *clang_getCString(CXString string); /** - * \brief Free the given string, + * \brief Free the given string. */ CINDEX_LINKAGE void clang_disposeString(CXString string); diff --git a/contrib/llvm/tools/clang/include/clang-c/Index.h b/contrib/llvm/tools/clang/include/clang-c/Index.h index 4d08e3b..95d54c2 100644 --- a/contrib/llvm/tools/clang/include/clang-c/Index.h +++ b/contrib/llvm/tools/clang/include/clang-c/Index.h @@ -16,9 +16,7 @@ #ifndef CLANG_C_INDEX_H #define CLANG_C_INDEX_H -#include #include -#include #include "clang-c/Platform.h" #include "clang-c/CXString.h" @@ -32,7 +30,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 19 +#define CINDEX_VERSION_MINOR 20 #define CINDEX_VERSION_ENCODE(major, minor) ( \ ((major) * 10000) \ @@ -414,6 +412,12 @@ CINDEX_LINKAGE CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu, CINDEX_LINKAGE int clang_Location_isInSystemHeader(CXSourceLocation location); /** + * \brief Returns non-zero if the given source location is in the main file of + * the corresponding translation unit. + */ +CINDEX_LINKAGE int clang_Location_isFromMainFile(CXSourceLocation location); + +/** * \brief Retrieve a NULL (invalid) source range. */ CINDEX_LINKAGE CXSourceRange clang_getNullRange(void); @@ -723,7 +727,7 @@ 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. + * clang_disposeDiagnosticSet. */ CINDEX_LINKAGE CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic D); @@ -763,7 +767,7 @@ 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(). + * behavior of \c clang_formatDiagnostic(). */ enum CXDiagnosticDisplayOptions { /** @@ -850,7 +854,7 @@ CINDEX_LINKAGE CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, * default behavior of the clang compiler. * * \returns A set of display options suitable for use with \c - * clang_displayDiagnostic(). + * clang_formatDiagnostic(). */ CINDEX_LINKAGE unsigned clang_defaultDiagnosticDisplayOptions(void); @@ -1942,7 +1946,7 @@ enum CXCursorKind { */ CXCursor_CompoundStmt = 202, - /** \brief A case statment. + /** \brief A case statement. */ CXCursor_CaseStmt = 203, @@ -2062,7 +2066,11 @@ enum CXCursorKind { */ CXCursor_DeclStmt = 231, - CXCursor_LastStmt = CXCursor_DeclStmt, + /** \brief OpenMP parallel directive. + */ + CXCursor_OMPParallelDirective = 232, + + CXCursor_LastStmt = CXCursor_OMPParallelDirective, /** * \brief Cursor that represents the translation unit itself. @@ -2087,7 +2095,8 @@ enum CXCursorKind { CXCursor_CXXOverrideAttr = 405, CXCursor_AnnotateAttr = 406, CXCursor_AsmLabelAttr = 407, - CXCursor_LastAttr = CXCursor_AsmLabelAttr, + CXCursor_PackedAttr = 408, + CXCursor_LastAttr = CXCursor_PackedAttr, /* Preprocessing */ CXCursor_PreprocessingDirective = 500, @@ -2666,7 +2675,11 @@ enum CXTypeKind { CXType_FunctionNoProto = 110, CXType_FunctionProto = 111, CXType_ConstantArray = 112, - CXType_Vector = 113 + CXType_Vector = 113, + CXType_IncompleteArray = 114, + CXType_VariableArray = 115, + CXType_DependentSizedArray = 116, + CXType_MemberPointer = 117 }; /** @@ -2957,6 +2970,13 @@ enum CXTypeLayoutError { CINDEX_LINKAGE long long clang_Type_getAlignOf(CXType T); /** + * \brief Return the class type of an member pointer type. + * + * If a non-member-pointer type is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getClassType(CXType T); + +/** * \brief Return the size of a type in bytes as per C++[expr.sizeof] standard. * * If the type declaration is invalid, CXTypeLayoutError_Invalid is returned. @@ -2982,6 +3002,23 @@ CINDEX_LINKAGE long long clang_Type_getSizeOf(CXType T); */ CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S); +enum CXRefQualifierKind { + /** \brief No ref-qualifier was provided. */ + CXRefQualifier_None = 0, + /** \brief An lvalue ref-qualifier was provided (\c &). */ + CXRefQualifier_LValue, + /** \brief An rvalue ref-qualifier was provided (\c &&). */ + CXRefQualifier_RValue +}; + +/** + * \brief Retrieve the ref-qualifier kind of a function or method. + * + * The ref-qualifier is returned for C++ functions or methods. For other types + * or non-C++ declarations, CXRefQualifier_None is returned. + */ +CINDEX_LINKAGE enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T); + /** * \brief Returns non-zero if the cursor specifies a Record member that is a * bitfield. @@ -3416,6 +3453,13 @@ typedef enum { CINDEX_LINKAGE unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C); /** + * \brief Given a cursor that represents an ObjC method or property declaration, + * return non-zero if the declaration was affected by "@optional". + * Returns zero if the cursor is not such a declaration or it is "@required". + */ +CINDEX_LINKAGE unsigned clang_Cursor_isObjCOptional(CXCursor C); + +/** * \brief Returns non-zero if the given cursor is a variadic function or method. */ CINDEX_LINKAGE unsigned clang_Cursor_isVariadic(CXCursor C); @@ -4037,6 +4081,12 @@ CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment); */ /** + * \brief Determine if a C++ member function or member function template is + * pure virtual. + */ +CINDEX_LINKAGE unsigned clang_CXXMethod_isPureVirtual(CXCursor C); + +/** * \brief Determine if a C++ member function or member function template is * declared 'static'. */ diff --git a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h index c167d3c..196f6c0 100644 --- a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h +++ b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h @@ -97,6 +97,8 @@ class MigrationProcess { FileRemapper Remapper; public: + bool HadARCErrors; + MigrationProcess(const CompilerInvocation &CI, DiagnosticConsumer *diagClient, StringRef outputDir = StringRef()); diff --git a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMTActions.h b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMTActions.h index 2daaf73..45c8b4e 100644 --- a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMTActions.h +++ b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMTActions.h @@ -57,14 +57,12 @@ public: /// \brief Migrates to modern ObjC syntax. class ObjCMigrateAction : public WrapperFrontendAction { std::string MigrateDir; - bool MigrateLiterals; - bool MigrateSubscripting; + unsigned ObjCMigAction; FileRemapper Remapper; CompilerInstance *CompInst; public: ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir, - bool migrateLiterals, - bool migrateSubscripting); + unsigned migrateAction); protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,StringRef InFile); diff --git a/contrib/llvm/tools/clang/include/clang/ARCMigrate/FileRemapper.h b/contrib/llvm/tools/clang/include/clang/ARCMigrate/FileRemapper.h index 94c9e8f..f7677cc 100644 --- a/contrib/llvm/tools/clang/include/clang/ARCMigrate/FileRemapper.h +++ b/contrib/llvm/tools/clang/include/clang/ARCMigrate/FileRemapper.h @@ -53,7 +53,6 @@ public: StringRef outputDir = StringRef()); void remap(StringRef filePath, llvm::MemoryBuffer *memBuf); - void remap(StringRef filePath, StringRef newPath); void applyMappings(PreprocessorOptions &PPOpts) const; diff --git a/contrib/llvm/tools/clang/include/clang/AST/APValue.h b/contrib/llvm/tools/clang/include/clang/AST/APValue.h index ec8faa4..b4fd2af 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/APValue.h +++ b/contrib/llvm/tools/clang/include/clang/AST/APValue.h @@ -168,6 +168,13 @@ public: MakeUninit(); } + /// \brief Returns whether the object performed allocations. + /// + /// If APValues are constructed via placement new, \c needsCleanup() + /// indicates whether the destructor must be called in order to correctly + /// free all allocated memory. + bool needsCleanup() const; + /// \brief Swaps the contents of this and the given APValue. void swap(APValue &RHS); diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h b/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h index ae77943..7b6fa94 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h @@ -14,6 +14,8 @@ #ifndef LLVM_CLANG_AST_ASTCONSUMER_H #define LLVM_CLANG_AST_ASTCONSUMER_H +#include "llvm/ADT/StringRef.h" + namespace clang { class ASTContext; class CXXRecordDecl; @@ -70,6 +72,10 @@ public: /// can be defined in declspecs). virtual void HandleTagDeclDefinition(TagDecl *D) {} + /// \brief This callback is invoked the first time each TagDecl is required to + /// be complete. + virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {} + /// \brief Invoked when a function is implicitly instantiated. /// Note that at this point point it does not have a body, its body is /// instantiated at the end of the translation unit and passed to @@ -86,6 +92,21 @@ public: /// The default implementation passes it to HandleTopLevelDecl. virtual void HandleImplicitImportDecl(ImportDecl *D); + /// \brief Handle a pragma that appends to Linker Options. Currently this + /// only exists to support Microsoft's #pragma comment(linker, "/foo"). + virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {} + + /// \brief Handle a pragma that emits a mismatch identifier and value to the + /// object file for the linker to work with. Currently, this only exists to + /// support Microsoft's #pragma detect_mismatch. + virtual void HandleDetectMismatch(llvm::StringRef Name, + llvm::StringRef Value) {} + + /// \brief Handle a dependent library created by a pragma in the source. + /// Currently this only exists to support Microsoft's + /// #pragma comment(lib, "/foo"). + virtual void HandleDependentLibrary(llvm::StringRef Lib) {} + /// CompleteTentativeDefinition - Callback invoked at the end of a translation /// unit to notify the consumer that the given tentative definition should be /// completed. diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h b/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h index c5d3337..f420e85 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h @@ -19,11 +19,9 @@ #include "clang/AST/CanonicalType.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/Decl.h" -#include "clang/AST/LambdaMangleContext.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/RawCommentList.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" #include "clang/Basic/AddressSpaces.h" @@ -47,6 +45,7 @@ namespace llvm { namespace clang { class FileManager; + class AtomicExpr; class ASTRecordLayout; class BlockExpr; class CharUnits; @@ -55,9 +54,11 @@ namespace clang { class ExternalASTSource; class ASTMutationListener; class IdentifierTable; + class MaterializeTemporaryExpr; class SelectorTable; class TargetInfo; class CXXABI; + class MangleNumberingContext; // Decls class MangleContext; class ObjCIvarDecl; @@ -81,6 +82,7 @@ class ASTContext : public RefCountedBase { mutable llvm::FoldingSet ExtQualNodes; mutable llvm::FoldingSet ComplexTypes; mutable llvm::FoldingSet PointerTypes; + mutable llvm::FoldingSet DecayedTypes; mutable llvm::FoldingSet BlockPointerTypes; mutable llvm::FoldingSet LValueReferenceTypes; mutable llvm::FoldingSet RValueReferenceTypes; @@ -146,7 +148,7 @@ class ASTContext : public RefCountedBase { mutable TypeInfoMap MemoizedTypeInfo; /// \brief A cache mapping from CXXRecordDecls to key functions. - llvm::DenseMap KeyFunctions; + llvm::DenseMap KeyFunctions; /// \brief Mapping from ObjCContainers to their ObjCImplementations. llvm::DenseMap ObjCImpls; @@ -163,6 +165,11 @@ class ASTContext : public RefCountedBase { llvm::DenseMap ClassScopeSpecializationPattern; + /// \brief Mapping from materialized temporaries with static storage duration + /// that appear in constant initializers to their evaluated values. + llvm::DenseMap + MaterializedTemporaryValues; + /// \brief Representation of a "canonical" template template parameter that /// is used in canonical template names. class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode { @@ -190,6 +197,9 @@ class ASTContext : public RefCountedBase { /// \brief The typedef for the __uint128_t type. mutable TypedefDecl *UInt128Decl; + + /// \brief The typedef for the __float128 stub type. + mutable TypeDecl *Float128StubDecl; /// \brief The typedef for the target specific predefined /// __builtin_va_list type. @@ -261,13 +271,30 @@ class ASTContext : public RefCountedBase { /// 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. + /// \brief A mapping from non-redeclarable declarations in modules that were + /// merged with other declarations to the canonical declaration that they were + /// merged into. + llvm::DenseMap MergedDecls; + +public: + /// \brief A type synonym for the TemplateOrInstantiation mapping. + typedef llvm::PointerUnion + TemplateOrSpecializationInfo; + +private: + + /// \brief A mapping to contain the template or declaration that + /// a variable declaration describes or was instantiated from, + /// respectively. /// - /// 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). + /// For non-templates, this value will be NULL. For variable + /// declarations that describe a variable template, this will be a + /// pointer to a VarTemplateDecl. For static data members + /// of class template specializations, this will be the + /// MemberSpecializationInfo referring to the member variable that was + /// instantiated or specialized. Thus, the mapping will keep track of + /// the static data member templates from which static data members of + /// class template specializations were instantiated. /// /// Given the following example: /// @@ -286,8 +313,8 @@ class ASTContext : public RefCountedBase { /// 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; + llvm::DenseMap + TemplateOrInstantiation; /// \brief Keeps track of the declaration from which a UsingDecl was /// created during instantiation. @@ -328,12 +355,15 @@ class ASTContext : public RefCountedBase { typedef llvm::TinyPtrVector CXXMethodVector; llvm::DenseMap OverriddenMethods; - /// \brief Mapping from each declaration context to its corresponding lambda - /// mangling context. - llvm::DenseMap LambdaMangleContexts; + /// \brief Mapping from each declaration context to its corresponding + /// mangling numbering context (used for constructs like lambdas which + /// need to be consistently numbered for the mangler). + llvm::DenseMap + MangleNumberingContexts; - llvm::DenseMap UnnamedMangleContexts; - llvm::DenseMap UnnamedMangleNumbers; + /// \brief Side-table of mangling numbers for declarations which rarely + /// need them (like static local vars). + llvm::DenseMap MangleNumbers; /// \brief Mapping that stores parameterIndex values for ParmVarDecls when /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex. @@ -368,6 +398,10 @@ class ASTContext : public RefCountedBase { /// \brief The logical -> physical address space map. const LangAS::Map *AddrSpaceMap; + /// \brief Address space map mangling must be used with language specific + /// address spaces (e.g. OpenCL/CUDA) + bool AddrSpaceMapMangling; + friend class ASTDeclReader; friend class ASTReader; friend class ASTWriter; @@ -419,22 +453,7 @@ public: return getParents(ast_type_traits::DynTypedNode::create(Node)); } - ParentVector getParents(const ast_type_traits::DynTypedNode &Node) { - assert(Node.getMemoizationData() && - "Invariant broken: only nodes that support memoization may be " - "used in the parent map."); - if (!AllParents) { - // We always need to run over the whole translation unit, as - // hasAncestor can escape any subtree. - AllParents.reset( - ParentMapASTVisitor::buildMap(*getTranslationUnitDecl())); - } - ParentMap::const_iterator I = AllParents->find(Node.getMemoizationData()); - if (I == AllParents->end()) { - return ParentVector(); - } - return I->second; - } + ParentVector getParents(const ast_type_traits::DynTypedNode &Node); const clang::PrintingPolicy &getPrintingPolicy() const { return PrintingPolicy; @@ -451,7 +470,7 @@ public: return BumpAlloc; } - void *Allocate(unsigned Size, unsigned Align = 8) const { + void *Allocate(size_t Size, unsigned Align = 8) const { return BumpAlloc.Allocate(Size, Align); } void Deallocate(void *Ptr) const { } @@ -470,6 +489,19 @@ public: const TargetInfo &getTargetInfo() const { return *Target; } + /// getIntTypeForBitwidth - + /// sets integer QualTy according to specified details: + /// bitwidth, signed/unsigned. + /// Returns empty type if there is no appropriate target types. + QualType getIntTypeForBitwidth(unsigned DestWidth, + unsigned Signed) const; + /// getRealTypeForBitwidth - + /// sets floating point QualTy according to specified bitwidth. + /// Returns empty type if there is no appropriate target types. + QualType getRealTypeForBitwidth(unsigned DestWidth) const; + + bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const; + const LangOptions& getLangOpts() const { return LangOpts; } DiagnosticsEngine &getDiagnostics() const; @@ -580,7 +612,12 @@ public: /// preprocessor is not available. comments::FullComment *getCommentForDecl(const Decl *D, const Preprocessor *PP) const; - + + /// Return parsed documentation comment attached to a given declaration. + /// Returns NULL if no comment is attached. Does not look at any + /// redeclarations of the declaration. + comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const; + comments::FullComment *cloneFullComment(comments::FullComment *FC, const Decl *D) const; @@ -601,9 +638,13 @@ public: /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member /// from which it was instantiated. + // FIXME: Remove ? MemberSpecializationInfo *getInstantiatedFromStaticDataMember( const VarDecl *Var); + TemplateOrSpecializationInfo + getTemplateOrSpecializationInfo(const VarDecl *Var); + FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD); void setClassScopeSpecializationPattern(FunctionDecl *FD, @@ -615,6 +656,9 @@ public: TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation = SourceLocation()); + void setTemplateOrSpecializationInfo(VarDecl *Inst, + TemplateOrSpecializationInfo TSI); + /// \brief If the given using decl \p Inst is an instantiation of a /// (possibly unresolved) using decl from a template instantiation, /// return it. @@ -632,31 +676,6 @@ public: void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl); - /// \brief Return \c true if \p FD is a zero-length bitfield which follows - /// the non-bitfield \p LastFD. - bool ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD, - const FieldDecl *LastFD) const; - - /// \brief Return \c true if \p FD is a zero-length bitfield which follows - /// the bitfield \p LastFD. - bool ZeroBitfieldFollowsBitfield(const FieldDecl *FD, - const FieldDecl *LastFD) const; - - /// \brief Return \c true if \p FD is a bitfield which follows the bitfield - /// \p LastFD. - bool BitfieldFollowsBitfield(const FieldDecl *FD, - const FieldDecl *LastFD) const; - - /// \brief Return \c true if \p FD is not a bitfield which follows the - /// bitfield \p LastFD. - bool NonBitfieldFollowsBitfield(const FieldDecl *FD, - const FieldDecl *LastFD) const; - - /// \brief Return \c true if \p FD is a bitfield which follows the - /// non-bitfield \p 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 @@ -732,7 +751,15 @@ public: return import_iterator(FirstLocalImport); } import_iterator local_import_end() const { return import_iterator(); } - + + Decl *getPrimaryMergedDecl(Decl *D) { + Decl *Result = MergedDecls.lookup(D); + return Result ? Result : D; + } + void setPrimaryMergedDecl(Decl *D, Decl *Primary) { + MergedDecls[D] = Primary; + } + TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; } @@ -740,7 +767,8 @@ public: CanQualType VoidTy; CanQualType BoolTy; CanQualType CharTy; - CanQualType WCharTy; // [C++ 3.9.1p5], integer type in C99. + CanQualType WCharTy; // [C++ 3.9.1p5]. + CanQualType WideCharTy; // Same as WCharTy in C++, integer type in C99. CanQualType WIntTy; // [C99 7.24.1], integer type unchanged by default promotions. CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99. CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99. @@ -809,6 +837,9 @@ public: /// \brief Retrieve the declaration for the 128-bit unsigned integer type. TypedefDecl *getUInt128Decl() const; + + /// \brief Retrieve the declaration for a 128-bit float stub type. + TypeDecl *getFloat128StubType() const; //===--------------------------------------------------------------------===// // Type Constructors @@ -884,6 +915,14 @@ public: return CanQualType::CreateUnsafe(getPointerType((QualType) T)); } + /// \brief Return the uniqued reference to the decayed version of the given + /// type. Can only be called on array and function types which decay to + /// pointer types. + QualType getDecayedType(QualType T) const; + CanQualType getDecayedType(CanQualType T) const { + return CanQualType::CreateUnsafe(getDecayedType((QualType) T)); + } + /// \brief Return the uniqued reference to the atomic type for the specified /// type. QualType getAtomicType(QualType T) const; @@ -1104,7 +1143,7 @@ public: /// \brief C++11 deduced auto type. QualType getAutoType(QualType DeducedType, bool IsDecltypeAuto, - bool IsDependent = false) const; + bool IsDependent) const; /// \brief C++11 deduction pattern for 'auto' type. QualType getAutoDeductType() const; @@ -1130,11 +1169,15 @@ public: /// . CanQualType getUIntMaxType() const; - /// \brief 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. + /// \brief Return the unique wchar_t type available in C++ (and available as + /// __wchar_t as a Microsoft extension). QualType getWCharType() const { return WCharTy; } + /// \brief Return the type of wide characters. In C++, this returns the + /// unique wchar_t type. In C99, this returns a type compatible with the type + /// defined in as defined by the target. + QualType getWideCharType() const { return WideCharTy; } + /// \brief Return the type of "signed wchar_t". /// /// Used when in C++, as a GCC extension. @@ -1607,14 +1650,17 @@ public: /// \pre \p D must not be a bitfield type, as bitfields do not have a valid /// alignment. /// - /// 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; + /// If \p ForAlignof, references are treated like their underlying type + /// and large arrays don't get any special treatment. If not \p ForAlignof + /// it computes the value expected by CodeGen: references are treated like + /// pointers and large arrays get extra alignment. + CharUnits getDeclAlign(const Decl *D, bool ForAlignof = false) const; /// \brief Get or compute information about the layout of the specified /// record (struct/union/class) \p D, which indicates its size and field /// position information. const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const; + const ASTRecordLayout *BuildMicrosoftASTRecordLayout(const RecordDecl *D) const; /// \brief Get or compute information about the layout of the specified /// Objective-C interface. @@ -1721,6 +1767,9 @@ public: getCanonicalType(T2).getTypePtr(); } + bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl, + const ObjCMethodDecl *MethodImp); + bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2); /// \brief Retrieves the "canonical" nested name specifier for a @@ -1749,19 +1798,9 @@ public: NestedNameSpecifier * getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const; - /// \brief Retrieves the default calling convention to use for - /// C++ instance methods. - CallingConv getDefaultCXXMethodCallConv(bool isVariadic); - - /// \brief Retrieves the canonical representation of the given - /// calling convention. - CallingConv getCanonicalCallConv(CallingConv CC) const; - - /// \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 default calling convention for the current target. + CallingConv getDefaultCallingConvention(bool isVariadic, + bool IsCXXMethod) const; /// \brief Retrieves the "canonical" template name that refers to a /// given template. @@ -1899,6 +1938,12 @@ public: return (*AddrSpaceMap)[AS - LangAS::Offset]; } + bool addressSpaceMapManglingFor(unsigned AS) const { + return AddrSpaceMapMangling || + AS < LangAS::Offset || + AS >= LangAS::Offset + LangAS::Count; + } + private: // Helper for integer ordering unsigned getIntegerRank(const Type *T) const; @@ -1925,7 +1970,6 @@ public: bool isObjCSelType(QualType T) const { return T == getObjCSelType(); } - bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS); bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS, bool ForCompare); @@ -2092,12 +2136,15 @@ public: /// it is not used. bool DeclMustBeEmitted(const Decl *D); - void addUnnamedTag(const TagDecl *Tag); - int getUnnamedTagManglingNumber(const TagDecl *Tag) const; + void setManglingNumber(const NamedDecl *ND, unsigned Number); + unsigned getManglingNumber(const NamedDecl *ND) const; + + /// \brief Retrieve the context for computing mangling numbers in the given + /// DeclContext. + MangleNumberingContext &getManglingNumberContext(const DeclContext *DC); + + MangleNumberingContext *createMangleNumberingContext() const; - /// \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); @@ -2105,7 +2152,12 @@ public: /// \brief Used by ParmVarDecl to retrieve on the side the /// index of the parameter when it exceeds the size of the normal bitfield. unsigned getParameterIndex(const ParmVarDecl *D) const; - + + /// \brief Get the storage for the constant value of a materialized temporary + /// of static storage duration. + APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E, + bool MayCreate); + //===--------------------------------------------------------------------===// // Statistics //===--------------------------------------------------------------------===// @@ -2197,93 +2249,21 @@ private: const ObjCImplementationDecl *Impl) const; private: - /// \brief A set of deallocations that should be performed when the + /// \brief A set of deallocations that should be performed when the /// ASTContext is destroyed. - SmallVector, 16> Deallocations; - + typedef llvm::SmallDenseMap > + DeallocationMap; + DeallocationMap 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 A \c RecursiveASTVisitor that builds a map from nodes to their - /// parents as defined by the \c RecursiveASTVisitor. - /// - /// Note that the relationship described here is purely in terms of AST - /// traversal - there are other relationships (for example declaration context) - /// in the AST that are better modeled by special matchers. - /// - /// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes. - class ParentMapASTVisitor : public RecursiveASTVisitor { - public: - /// \brief Builds and returns the translation unit's parent map. - /// - /// The caller takes ownership of the returned \c ParentMap. - static ParentMap *buildMap(TranslationUnitDecl &TU) { - ParentMapASTVisitor Visitor(new ParentMap); - Visitor.TraverseDecl(&TU); - return Visitor.Parents; - } - - private: - typedef RecursiveASTVisitor VisitorBase; - - ParentMapASTVisitor(ParentMap *Parents) : Parents(Parents) { - } - - bool shouldVisitTemplateInstantiations() const { - return true; - } - bool shouldVisitImplicitCode() const { - return true; - } - // Disables data recursion. We intercept Traverse* methods in the RAV, which - // are not triggered during data recursion. - bool shouldUseDataRecursionFor(clang::Stmt *S) const { - return false; - } - - template - bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) { - if (Node == NULL) - return true; - if (ParentStack.size() > 0) - // FIXME: Currently we add the same parent multiple times, for example - // when we visit all subexpressions of template instantiations; this is - // suboptimal, bug benign: the only way to visit those is with - // hasAncestor / hasParent, and those do not create new matches. - // The plan is to enable DynTypedNode to be storable in a map or hash - // map. The main problem there is to implement hash functions / - // comparison operators for all types that DynTypedNode supports that - // do not have pointer identity. - (*Parents)[Node].push_back(ParentStack.back()); - ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node)); - bool Result = (this ->* traverse) (Node); - ParentStack.pop_back(); - return Result; - } - - bool TraverseDecl(Decl *DeclNode) { - return TraverseNode(DeclNode, &VisitorBase::TraverseDecl); - } - - bool TraverseStmt(Stmt *StmtNode) { - return TraverseNode(StmtNode, &VisitorBase::TraverseStmt); - } - - ParentMap *Parents; - llvm::SmallVector ParentStack; - - friend class RecursiveASTVisitor; - }; - llvm::OwningPtr AllParents; }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h b/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h index 64e955e..1635511 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define ASTSTART #include "clang/Basic/DiagnosticASTKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTFwd.h b/contrib/llvm/tools/clang/include/clang/AST/ASTFwd.h new file mode 100644 index 0000000..4f32798 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTFwd.h @@ -0,0 +1,28 @@ +//===--- ASTFwd.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--------------------------------------------------------------===// +/// +/// \file +/// \brief Forward declaration of all AST node types. +/// +//===-------------------------------------------------------------===// + +namespace clang { + +class Decl; +#define DECL(DERIVED, BASE) class DERIVED##Decl; +#include "clang/AST/DeclNodes.inc" +class Stmt; +#define STMT(DERIVED, BASE) class DERIVED; +#include "clang/AST/StmtNodes.inc" +class Type; +#define TYPE(DERIVED, BASE) class DERIVED##Type; +#include "clang/AST/TypeNodes.def" +class CXXCtorInitializer; + +} // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h b/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h index 1672ab2..b74c8ee 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h @@ -271,6 +271,14 @@ namespace clang { /// Subclasses can override this function to observe all of the \c From -> /// \c To declaration mappings as they are imported. virtual Decl *Imported(Decl *From, Decl *To); + + /// \brief Called by StructuralEquivalenceContext. If a RecordDecl is + /// being compared to another RecordDecl as part of import, completing the + /// other RecordDecl may trigger importation of the first RecordDecl. This + /// happens especially for anonymous structs. If the original of the second + /// RecordDecl can be found, we can complete it without the need for + /// importation, eliminating this loop. + virtual Decl *GetOriginalDecl(Decl *To) { return NULL; } /// \brief Determine whether the given types are structurally /// equivalent. diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTLambda.h b/contrib/llvm/tools/clang/include/clang/AST/ASTLambda.h new file mode 100644 index 0000000..358ac71 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTLambda.h @@ -0,0 +1,80 @@ +//===--- ASTLambda.h - Lambda Helper Functions --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file provides some common utility functions for processing +/// Lambda related AST Constructs. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_LAMBDA_H +#define LLVM_CLANG_AST_LAMBDA_H + +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" + +namespace clang { +inline StringRef getLambdaStaticInvokerName() { + return "__invoke"; +} +// This function returns true if M is a specialization, a template, +// or a non-generic lambda call operator. +inline bool isLambdaCallOperator(const CXXMethodDecl *MD) { + const CXXRecordDecl *LambdaClass = MD->getParent(); + if (!LambdaClass || !LambdaClass->isLambda()) return false; + return MD->getOverloadedOperator() == OO_Call; +} + +inline bool isLambdaCallOperator(const DeclContext *DC) { + if (!DC || !isa(DC)) return false; + return isLambdaCallOperator(cast(DC)); +} + +inline bool isGenericLambdaCallOperatorSpecialization(CXXMethodDecl *MD) { + if (!MD) return false; + CXXRecordDecl *LambdaClass = MD->getParent(); + if (LambdaClass && LambdaClass->isGenericLambda()) + return isLambdaCallOperator(MD) && + MD->isFunctionTemplateSpecialization(); + return false; +} + +inline bool isLambdaConversionOperator(CXXConversionDecl *C) { + return C ? C->getParent()->isLambda() : false; +} + +inline bool isLambdaConversionOperator(Decl *D) { + if (!D) return false; + if (CXXConversionDecl *Conv = dyn_cast(D)) + return isLambdaConversionOperator(Conv); + if (FunctionTemplateDecl *F = dyn_cast(D)) + if (CXXConversionDecl *Conv = + dyn_cast_or_null(F->getTemplatedDecl())) + return isLambdaConversionOperator(Conv); + return false; +} + +inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) { + return isGenericLambdaCallOperatorSpecialization( + dyn_cast(DC)); +} + + +// This returns the parent DeclContext ensuring that the correct +// parent DeclContext is returned for Lambdas +inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) { + if (isLambdaCallOperator(DC)) + return DC->getParent()->getParent(); + else + return DC->getParent(); +} + +} // clang + +#endif // LLVM_CLANG_AST_LAMBDA_H diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h b/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h index 6b70285..6d12a92 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h @@ -27,8 +27,11 @@ namespace clang { class ObjCContainerDecl; class ObjCInterfaceDecl; class ObjCPropertyDecl; + class QualType; class TagDecl; class VarDecl; + class VarTemplateDecl; + class VarTemplateSpecializationDecl; /// \brief An abstract interface that should be implemented by listeners /// that want to be notified when an AST entity gets modified after its @@ -53,9 +56,18 @@ public: /// \brief A template specialization (or partial one) was added to the /// template declaration. + virtual void + AddedCXXTemplateSpecialization(const VarTemplateDecl *TD, + const VarTemplateSpecializationDecl *D) {} + + /// \brief A template specialization (or partial one) was added to the + /// template declaration. virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, const FunctionDecl *D) {} + /// \brief A function's return type has been deduced. + virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType); + /// \brief An implicit member got a definition. virtual void CompletedImplicitDefinition(const FunctionDecl *D) {} @@ -78,6 +90,11 @@ public: const ObjCPropertyDecl *OrigProp, const ObjCCategoryDecl *ClassExt) {} + /// \brief A declaration is marked used which was not previously marked used. + /// + /// \param D the declaration marked used + virtual void DeclarationMarkedUsed(const Decl *D) {} + // NOTE: If new methods are added they should also be added to // MultiplexASTMutationListener. }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h b/contrib/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h index 4688b12..087ad56 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h @@ -7,22 +7,132 @@ // //===----------------------------------------------------------------------===// // -// Provides a dynamically typed node container that can be used to store -// an AST base node at runtime in the same storage in a type safe way. +// Provides a dynamic type identifier and a dynamically typed node container +// that can be used to store an AST base node at runtime in the same storage in +// a type safe way. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_AST_TYPE_TRAITS_H #define LLVM_CLANG_AST_AST_TYPE_TRAITS_H +#include "clang/AST/ASTFwd.h" #include "clang/AST/Decl.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Stmt.h" +#include "clang/AST/TemplateBase.h" #include "clang/AST/TypeLoc.h" +#include "clang/Basic/LLVM.h" #include "llvm/Support/AlignOf.h" +namespace llvm { + +class raw_ostream; + +} + namespace clang { + +struct PrintingPolicy; + namespace ast_type_traits { +/// \brief Kind identifier. +/// +/// It can be constructed from any node kind and allows for runtime type +/// hierarchy checks. +/// Use getFromNodeKind() to construct them. +class ASTNodeKind { +public: + /// \brief Empty identifier. It matches nothing. + ASTNodeKind() : KindId(NKI_None) {} + + /// \brief Construct an identifier for T. + template + static ASTNodeKind getFromNodeKind() { + return ASTNodeKind(KindToKindId::Id); + } + + /// \brief Returns \c true if \c this and \c Other represent the same kind. + bool isSame(ASTNodeKind Other) const; + + /// \brief Returns \c true if \c this is a base kind of (or same as) \c Other. + bool isBaseOf(ASTNodeKind Other) const; + + /// \brief String representation of the kind. + StringRef asStringRef() const; + +private: + /// \brief Kind ids. + /// + /// Includes all possible base and derived kinds. + enum NodeKindId { + NKI_None, + NKI_CXXCtorInitializer, + NKI_TemplateArgument, + NKI_NestedNameSpecifier, + NKI_NestedNameSpecifierLoc, + NKI_QualType, + NKI_TypeLoc, + NKI_Decl, +#define DECL(DERIVED, BASE) NKI_##DERIVED##Decl, +#include "clang/AST/DeclNodes.inc" + NKI_Stmt, +#define STMT(DERIVED, BASE) NKI_##DERIVED, +#include "clang/AST/StmtNodes.inc" + NKI_Type, +#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type, +#include "clang/AST/TypeNodes.def" + NKI_NumberOfKinds + }; + + /// \brief Use getFromNodeKind() to construct the kind. + ASTNodeKind(NodeKindId KindId) : KindId(KindId) {} + + /// \brief Returns \c true if \c Base is a base kind of (or same as) \c + /// Derived. + static bool isBaseOf(NodeKindId Base, NodeKindId Derived); + + /// \brief Helper meta-function to convert a kind T to its enum value. + /// + /// This struct is specialized below for all known kinds. + template struct KindToKindId { + static const NodeKindId Id = NKI_None; + }; + + /// \brief Per kind info. + struct KindInfo { + /// \brief The id of the parent kind, or None if it has no parent. + NodeKindId ParentId; + /// \brief Name of the kind. + const char *Name; + }; + static const KindInfo AllKindInfo[NKI_NumberOfKinds]; + + NodeKindId KindId; +}; + +#define KIND_TO_KIND_ID(Class) \ + template <> struct ASTNodeKind::KindToKindId { \ + static const NodeKindId Id = NKI_##Class; \ + }; +KIND_TO_KIND_ID(CXXCtorInitializer) +KIND_TO_KIND_ID(TemplateArgument) +KIND_TO_KIND_ID(NestedNameSpecifier) +KIND_TO_KIND_ID(NestedNameSpecifierLoc) +KIND_TO_KIND_ID(QualType) +KIND_TO_KIND_ID(TypeLoc) +KIND_TO_KIND_ID(Decl) +KIND_TO_KIND_ID(Stmt) +KIND_TO_KIND_ID(Type) +#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl) +#include "clang/AST/DeclNodes.inc" +#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED) +#include "clang/AST/StmtNodes.inc" +#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type) +#include "clang/AST/TypeNodes.def" +#undef KIND_TO_KIND_ID + /// \brief A dynamically typed AST node container. /// /// Stores an AST node in a type safe way. This allows writing code that @@ -32,7 +142,7 @@ namespace ast_type_traits { /// Use \c create(Node) to create a \c DynTypedNode from an AST node, /// and \c get() to retrieve the node as type T if the types match. /// -/// See \c NodeTypeTag for which node base types are currently supported; +/// See \c ASTNodeKind for which node base types are currently supported; /// You can create DynTypedNodes for all nodes in the inheritance hierarchy of /// the supported base types. class DynTypedNode { @@ -49,15 +159,15 @@ public: /// convertible to \c T. /// /// For types that have identity via their pointer in the AST - /// (like \c Stmt and \c Decl) the returned pointer points to the - /// referenced AST node. + /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned + /// pointer points to the referenced AST node. /// For other types (like \c QualType) the value is stored directly /// in the \c DynTypedNode, and the returned pointer points at /// the storage inside DynTypedNode. For those nodes, do not /// use the pointer outside the scope of the DynTypedNode. template const T *get() const { - return BaseConverter::get(Tag, Storage.buffer); + return BaseConverter::get(NodeKind, Storage.buffer); } /// \brief Returns a pointer that identifies the stored AST node. @@ -67,142 +177,171 @@ public: /// method returns NULL. const void *getMemoizationData() const; + /// \brief Prints the node to the given output stream. + void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const; + + /// \brief Dumps the node to the given output stream. + void dump(llvm::raw_ostream &OS, SourceManager &SM) const; + + /// \brief For nodes which represent textual entities in the source code, + /// return their SourceRange. For all other nodes, return SourceRange(). + SourceRange getSourceRange() const; + + /// @{ + /// \brief Imposes an order on \c DynTypedNode. + /// + /// Supports comparison of nodes that support memoization. + /// FIXME: Implement comparsion for other node types (currently + /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data). + bool operator<(const DynTypedNode &Other) const { + assert(getMemoizationData() && Other.getMemoizationData()); + return getMemoizationData() < Other.getMemoizationData(); + } + bool operator==(const DynTypedNode &Other) const { + // Nodes with different types cannot be equal. + if (!NodeKind.isSame(Other.NodeKind)) + return false; + + // FIXME: Implement for other types. + if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) { + return *get() == *Other.get(); + } + assert(getMemoizationData() && Other.getMemoizationData()); + return getMemoizationData() == Other.getMemoizationData(); + } + bool operator!=(const DynTypedNode &Other) const { + return !operator==(Other); + } + /// @} + private: /// \brief Takes care of converting from and to \c T. template struct BaseConverter; - /// \brief Supported base node types. - enum NodeTypeTag { - NT_Decl, - NT_Stmt, - NT_NestedNameSpecifier, - NT_NestedNameSpecifierLoc, - NT_QualType, - NT_Type, - NT_TypeLoc - } Tag; + /// \brief Converter that uses dyn_cast from a stored BaseT*. + template struct DynCastPtrConverter { + static const T *get(ASTNodeKind NodeKind, const char Storage[]) { + if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) + return dyn_cast(*reinterpret_cast(Storage)); + return NULL; + } + static DynTypedNode create(const BaseT &Node) { + DynTypedNode Result; + Result.NodeKind = ASTNodeKind::getFromNodeKind(); + new (Result.Storage.buffer) const BaseT * (&Node); + return Result; + } + }; + + /// \brief Converter that stores T* (by pointer). + template struct PtrConverter { + static const T *get(ASTNodeKind NodeKind, const char Storage[]) { + if (ASTNodeKind::getFromNodeKind().isSame(NodeKind)) + return *reinterpret_cast(Storage); + return NULL; + } + static DynTypedNode create(const T &Node) { + DynTypedNode Result; + Result.NodeKind = ASTNodeKind::getFromNodeKind(); + new (Result.Storage.buffer) const T * (&Node); + return Result; + } + }; + + /// \brief Converter that stores T (by value). + template struct ValueConverter { + static const T *get(ASTNodeKind NodeKind, const char Storage[]) { + if (ASTNodeKind::getFromNodeKind().isSame(NodeKind)) + return reinterpret_cast(Storage); + return NULL; + } + static DynTypedNode create(const T &Node) { + DynTypedNode Result; + Result.NodeKind = ASTNodeKind::getFromNodeKind(); + new (Result.Storage.buffer) T(Node); + return Result; + } + }; + + ASTNodeKind NodeKind; /// \brief Stores the data of the node. /// - /// Note that we can store \c Decls and \c Stmts by pointer as they are - /// guaranteed to be unique pointers pointing to dedicated storage in the - /// AST. \c QualTypes on the other hand do not have storage or unique + /// Note that we can store \c Decls, \c Stmts, \c Types, + /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are + /// guaranteed to be unique pointers pointing to dedicated storage in the AST. + /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs and + /// \c TemplateArguments on the other hand do not have storage or unique /// pointers and thus need to be stored by value. - llvm::AlignedCharArrayUnion Storage; + typedef llvm::AlignedCharArrayUnion< + Decl *, Stmt *, Type *, NestedNameSpecifier *, CXXCtorInitializer *> + KindsByPointer; + llvm::AlignedCharArrayUnion + Storage; }; -// FIXME: Pull out abstraction for the following. -template struct DynTypedNode::BaseConverter >::type> { - static const T *get(NodeTypeTag Tag, const char Storage[]) { - if (Tag == NT_Decl) - return dyn_cast(*reinterpret_cast(Storage)); - return NULL; - } - static DynTypedNode create(const Decl &Node) { - DynTypedNode Result; - Result.Tag = NT_Decl; - new (Result.Storage.buffer) const Decl*(&Node); - return Result; - } -}; -template struct DynTypedNode::BaseConverter >::type> { - static const T *get(NodeTypeTag Tag, const char Storage[]) { - if (Tag == NT_Stmt) - return dyn_cast(*reinterpret_cast(Storage)); - return NULL; - } - static DynTypedNode create(const Stmt &Node) { - DynTypedNode Result; - Result.Tag = NT_Stmt; - new (Result.Storage.buffer) const Stmt*(&Node); - return Result; - } -}; -template struct DynTypedNode::BaseConverter >::type> { - static const T *get(NodeTypeTag Tag, const char Storage[]) { - if (Tag == NT_Type) - return dyn_cast(*reinterpret_cast(Storage)); - return NULL; - } - static DynTypedNode create(const Type &Node) { - DynTypedNode Result; - Result.Tag = NT_Type; - new (Result.Storage.buffer) const Type*(&Node); - return Result; - } -}; -template<> struct DynTypedNode::BaseConverter { - static const NestedNameSpecifier *get(NodeTypeTag Tag, const char Storage[]) { - if (Tag == NT_NestedNameSpecifier) - return *reinterpret_cast(Storage); - return NULL; - } - static DynTypedNode create(const NestedNameSpecifier &Node) { - DynTypedNode Result; - Result.Tag = NT_NestedNameSpecifier; - new (Result.Storage.buffer) const NestedNameSpecifier*(&Node); - return Result; - } -}; -template<> struct DynTypedNode::BaseConverter { - static const NestedNameSpecifierLoc *get(NodeTypeTag Tag, - const char Storage[]) { - if (Tag == NT_NestedNameSpecifierLoc) - return reinterpret_cast(Storage); - return NULL; - } - static DynTypedNode create(const NestedNameSpecifierLoc &Node) { - DynTypedNode Result; - Result.Tag = NT_NestedNameSpecifierLoc; - new (Result.Storage.buffer) NestedNameSpecifierLoc(Node); - return Result; - } -}; -template<> struct DynTypedNode::BaseConverter { - static const QualType *get(NodeTypeTag Tag, const char Storage[]) { - if (Tag == NT_QualType) - return reinterpret_cast(Storage); - return NULL; - } - static DynTypedNode create(const QualType &Node) { - DynTypedNode Result; - Result.Tag = NT_QualType; - new (Result.Storage.buffer) QualType(Node); - return Result; - } -}; -template<> struct DynTypedNode::BaseConverter { - static const TypeLoc *get(NodeTypeTag Tag, const char Storage[]) { - if (Tag == NT_TypeLoc) - return reinterpret_cast(Storage); - return NULL; - } - static DynTypedNode create(const TypeLoc &Node) { - DynTypedNode Result; - Result.Tag = NT_TypeLoc; - new (Result.Storage.buffer) TypeLoc(Node); - return Result; - } -}; +template +struct DynTypedNode::BaseConverter< + T, typename llvm::enable_if >::type> : public DynCastPtrConverter {}; + +template +struct DynTypedNode::BaseConverter< + T, typename llvm::enable_if >::type> : public DynCastPtrConverter {}; + +template +struct DynTypedNode::BaseConverter< + T, typename llvm::enable_if >::type> : public DynCastPtrConverter {}; + +template <> +struct DynTypedNode::BaseConverter< + NestedNameSpecifier, void> : public PtrConverter {}; + +template <> +struct DynTypedNode::BaseConverter< + CXXCtorInitializer, void> : public PtrConverter {}; + +template <> +struct DynTypedNode::BaseConverter< + TemplateArgument, void> : public ValueConverter {}; + +template <> +struct DynTypedNode::BaseConverter< + NestedNameSpecifierLoc, + void> : public ValueConverter {}; + +template <> +struct DynTypedNode::BaseConverter : public ValueConverter {}; + +template <> +struct DynTypedNode::BaseConverter< + TypeLoc, void> : public ValueConverter {}; + // The only operation we allow on unsupported types is \c get. // This allows to conveniently use \c DynTypedNode when having an arbitrary // AST node that is not supported, but prevents misuse - a user cannot create // a DynTypedNode from arbitrary types. template struct DynTypedNode::BaseConverter { - static const T *get(NodeTypeTag Tag, const char Storage[]) { return NULL; } + static const T *get(ASTNodeKind NodeKind, const char Storage[]) { + return NULL; + } }; inline const void *DynTypedNode::getMemoizationData() const { - switch (Tag) { - case NT_Decl: return BaseConverter::get(Tag, Storage.buffer); - case NT_Stmt: return BaseConverter::get(Tag, Storage.buffer); - default: return NULL; - }; + if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) { + return BaseConverter::get(NodeKind, Storage.buffer); + } else if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) { + return BaseConverter::get(NodeKind, Storage.buffer); + } else if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) { + return BaseConverter::get(NodeKind, Storage.buffer); + } else if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) { + return BaseConverter::get(NodeKind, Storage.buffer); + } + return NULL; } } // end namespace ast_type_traits diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTUnresolvedSet.h b/contrib/llvm/tools/clang/include/clang/AST/ASTUnresolvedSet.h index 5a56b4d..e8be670 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTUnresolvedSet.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTUnresolvedSet.h @@ -22,12 +22,21 @@ namespace clang { /// \brief An UnresolvedSet-like class which uses the ASTContext's allocator. class ASTUnresolvedSet { - typedef ASTVector DeclsTy; + struct DeclsTy : ASTVector { + DeclsTy() {} + DeclsTy(ASTContext &C, unsigned N) : ASTVector(C, N) {} + + bool isLazy() const { return getTag(); } + void setLazy(bool Lazy) { setTag(Lazy); } + }; + DeclsTy Decls; ASTUnresolvedSet(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION; void operator=(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION; + friend class LazyASTUnresolvedSet; + public: ASTUnresolvedSet() {} ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {} @@ -48,7 +57,7 @@ public: /// Replaces the given declaration with the new one, once. /// /// \return true if the set changed - bool replace(const NamedDecl* Old, NamedDecl *New, AccessSpecifier AS) { + bool replace(const NamedDecl *Old, NamedDecl *New, AccessSpecifier AS) { for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) { if (I->getDecl() == Old) { I->set(New, AS); @@ -58,10 +67,7 @@ public: return false; } - void erase(unsigned I) { - Decls[I] = Decls.back(); - Decls.pop_back(); - } + void erase(unsigned I) { Decls[I] = Decls.pop_back_val(); } void clear() { Decls.clear(); } @@ -79,7 +85,29 @@ public: DeclAccessPair &operator[](unsigned I) { return Decls[I]; } const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; } }; - + +/// \brief An UnresolvedSet-like class that might not have been loaded from the +/// external AST source yet. +class LazyASTUnresolvedSet { + mutable ASTUnresolvedSet Impl; + + void getFromExternalSource(ASTContext &C) const; + +public: + ASTUnresolvedSet &get(ASTContext &C) const { + if (Impl.Decls.isLazy()) + getFromExternalSource(C); + return Impl; + } + + void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); } + void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) { + assert(Impl.empty() || Impl.Decls.isLazy()); + Impl.Decls.setLazy(true); + Impl.addDecl(C, reinterpret_cast(ID << 2), AS); + } +}; + } // namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTVector.h b/contrib/llvm/tools/clang/include/clang/AST/ASTVector.h index 669e50d..6db918e 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTVector.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTVector.h @@ -55,16 +55,24 @@ namespace clang { template class ASTVector { - T *Begin, *End, *Capacity; +private: + T *Begin, *End; + llvm::PointerIntPair Capacity; void setEnd(T *P) { this->End = P; } +protected: + // Make a tag bit available to users of this class. + // FIXME: This is a horrible hack. + bool getTag() const { return Capacity.getInt(); } + void setTag(bool B) { Capacity.setInt(B); } + public: // Default ctor - Initialize to empty. - ASTVector() : Begin(NULL), End(NULL), Capacity(NULL) { } + ASTVector() : Begin(0), End(0), Capacity(0, false) {} - ASTVector(ASTContext &C, unsigned N) - : Begin(NULL), End(NULL), Capacity(NULL) { + ASTVector(const ASTContext &C, unsigned N) + : Begin(0), End(0), Capacity(0, false) { reserve(C, N); } @@ -155,8 +163,8 @@ public: return const_pointer(Begin); } - void push_back(const_reference Elt, ASTContext &C) { - if (End < Capacity) { + void push_back(const_reference Elt, const ASTContext &C) { + if (End < this->capacity_ptr()) { Retry: new (End) T(Elt); ++End; @@ -166,19 +174,19 @@ public: goto Retry; } - void reserve(ASTContext &C, unsigned N) { - if (unsigned(Capacity-Begin) < N) + void reserve(const ASTContext &C, unsigned N) { + if (unsigned(this->capacity_ptr()-Begin) < N) grow(C, N); } /// capacity - Return the total number of elements in the currently allocated /// buffer. - size_t capacity() const { return Capacity - Begin; } + size_t capacity() const { return this->capacity_ptr() - 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) { + void append(const ASTContext &C, in_iter in_start, in_iter in_end) { size_type NumInputs = std::distance(in_start, in_end); if (NumInputs == 0) @@ -197,7 +205,7 @@ public: /// append - Add the specified range to the end of the SmallVector. /// - void append(ASTContext &C, size_type NumInputs, const T &Elt) { + void append(const ASTContext &C, size_type NumInputs, const T &Elt) { // Grow allocated space if needed. if (NumInputs > size_type(this->capacity_ptr()-this->end())) this->grow(C, this->size()+NumInputs); @@ -214,13 +222,13 @@ public: std::uninitialized_copy(I, E, Dest); } - iterator insert(ASTContext &C, iterator I, const T &Elt) { + iterator insert(const ASTContext &C, iterator I, const T &Elt) { if (I == this->end()) { // Important special case for empty vector. - push_back(Elt); + push_back(Elt, C); return this->end()-1; } - if (this->EndX < this->CapacityX) { + if (this->End < this->capacity_ptr()) { Retry: new (this->end()) T(this->back()); this->setEnd(this->end()+1); @@ -235,7 +243,7 @@ public: goto Retry; } - iterator insert(ASTContext &C, iterator I, size_type NumToInsert, + iterator insert(const ASTContext &C, iterator I, size_type NumToInsert, const T &Elt) { if (I == this->end()) { // Important special case for empty vector. append(C, NumToInsert, Elt); @@ -284,7 +292,7 @@ public: } template - iterator insert(ASTContext &C, iterator I, ItTy From, ItTy To) { + iterator insert(const 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; @@ -335,7 +343,7 @@ public: return I; } - void resize(ASTContext &C, unsigned N, const T &NV) { + void resize(const ASTContext &C, unsigned N, const T &NV) { if (N < this->size()) { this->destroy_range(this->begin()+N, this->end()); this->setEnd(this->begin()+N); @@ -350,7 +358,7 @@ public: 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 grow(const ASTContext &C, size_type MinSize = 1); void construct_range(T *S, T *E, const T &Elt) { for (; S != E; ++S) @@ -365,13 +373,16 @@ private: } protected: - iterator capacity_ptr() { return (iterator)this->Capacity; } + const_iterator capacity_ptr() const { + return (iterator) Capacity.getPointer(); + } + iterator capacity_ptr() { return (iterator)Capacity.getPointer(); } }; // Define this out-of-line to dissuade the C++ compiler from inlining it. template -void ASTVector::grow(ASTContext &C, size_t MinSize) { - size_t CurCapacity = Capacity-Begin; +void ASTVector::grow(const ASTContext &C, size_t MinSize) { + size_t CurCapacity = this->capacity(); size_t CurSize = size(); size_t NewCapacity = 2*CurCapacity; if (NewCapacity < MinSize) @@ -394,7 +405,7 @@ void ASTVector::grow(ASTContext &C, size_t MinSize) { // ASTContext never frees any memory. Begin = NewElts; End = NewElts+CurSize; - Capacity = Begin+NewCapacity; + Capacity.setPointer(Begin+NewCapacity); } } // end: clang namespace diff --git a/contrib/llvm/tools/clang/include/clang/AST/Attr.h b/contrib/llvm/tools/clang/include/clang/AST/Attr.h index 27dcef2..7dbf413 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Attr.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Attr.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_ATTR_H #include "clang/AST/AttrIterator.h" +#include "clang/AST/Decl.h" #include "clang/AST/Type.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/LLVM.h" @@ -145,7 +146,7 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { // Relies on relative order of enum emission with respect to param attrs. - return (A->getKind() <= attr::LAST_MS_INHERITABLE && + return (A->getKind() <= attr::LAST_MS_INHERITANCE && A->getKind() > attr::LAST_INHERITABLE_PARAM); } }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h b/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h index 2983e04..dbe4ad0 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h @@ -287,9 +287,9 @@ public: // Iterate over the set of overriding virtual methods in a given // subobject. - typedef SmallVector::iterator + typedef SmallVectorImpl::iterator overriding_iterator; - typedef SmallVector::const_iterator + typedef SmallVectorImpl::const_iterator overriding_const_iterator; // Add a new overriding method for a particular subobject. diff --git a/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h b/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h index 9460757..9c699b7 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h @@ -81,7 +81,7 @@ public: operator QualType() const { return Stored; } /// \brief Implicit conversion to bool. - operator bool() const { return !isNull(); } + LLVM_EXPLICIT operator bool() const { return !isNull(); } bool isNull() const { return Stored.isNull(); diff --git a/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h b/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h index 082c672..09ff682 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h @@ -19,21 +19,20 @@ #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 + /// 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. + /// quantities in bit units and character units. + /// + /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned + /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to + /// the same quantity of storage. However, we use the term 'character unit' + /// rather than 'byte' to avoid an implication that a character unit is + /// exactly 8 bits. /// - /// 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 + /// 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 { diff --git a/contrib/llvm/tools/clang/include/clang/AST/Comment.h b/contrib/llvm/tools/clang/include/clang/AST/Comment.h index c02a82f..28849f5 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Comment.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Comment.h @@ -699,7 +699,10 @@ private: unsigned ParamIndex; public: - enum { InvalidParamIndex = ~0U }; + enum LLVM_ENUM_INT_TYPE(unsigned) { + InvalidParamIndex = ~0U, + VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U + }; ParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, @@ -755,14 +758,25 @@ public: return ParamIndex != InvalidParamIndex; } + bool isVarArgParam() const LLVM_READONLY { + return ParamIndex == VarArgParamIndex; + } + + void setIsVarArgParam() { + ParamIndex = VarArgParamIndex; + assert(isParamIndexValid()); + } + unsigned getParamIndex() const LLVM_READONLY { assert(isParamIndexValid()); + assert(!isVarArgParam()); return ParamIndex; } void setParamIndex(unsigned Index) { ParamIndex = Index; assert(isParamIndexValid()); + assert(!isVarArgParam()); } }; @@ -1097,10 +1111,6 @@ public: return ThisDeclInfo; } - DeclInfo *getThisDeclInfo() const LLVM_READONLY { - return ThisDeclInfo; - } - ArrayRef getBlocks() const { return Blocks; } }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentCommandTraits.h b/contrib/llvm/tools/clang/include/clang/AST/CommentCommandTraits.h index d1f5209..dde7a14 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentCommandTraits.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentCommandTraits.h @@ -67,6 +67,9 @@ struct CommandInfo { /// a template parameter (\\tparam or an alias). unsigned IsTParamCommand : 1; + /// True if this command is \\throws or an alias. + unsigned IsThrowsCommand : 1; + /// True if this command is \\deprecated or an alias. unsigned IsDeprecatedCommand : 1; @@ -142,6 +145,8 @@ public: llvm_unreachable("the command should be known"); } + const CommandInfo *getTypoCorrectCommandInfo(StringRef Typo) const; + const CommandInfo *getCommandInfo(unsigned CommandID) const; const CommandInfo *registerUnknownCommand(StringRef CommandName); diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentCommands.td b/contrib/llvm/tools/clang/include/clang/AST/CommentCommands.td index 8c88494..ed323da 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentCommands.td +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentCommands.td @@ -15,6 +15,7 @@ class Command { bit IsReturnsCommand = 0; bit IsParamCommand = 0; bit IsTParamCommand = 0; + bit IsThrowsCommand = 0; bit IsDeprecatedCommand = 0; bit IsHeaderfileCommand = 0; @@ -109,6 +110,10 @@ def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; } // HeaderDoc command for template parameter documentation. def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; } +def Throws : BlockCommand<"throws"> { let IsThrowsCommand = 1; } +def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; } +def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; } + def Deprecated : BlockCommand<"deprecated"> { let IsEmptyParagraphAllowed = 1; let IsDeprecatedCommand = 1; @@ -200,11 +205,17 @@ def Mainpage : VerbatimLineCommand<"mainpage">; def Subpage : VerbatimLineCommand<"subpage">; def Ref : VerbatimLineCommand<"ref">; +def Relates : VerbatimLineCommand<"relates">; +def Related : VerbatimLineCommand<"related">; +def RelatesAlso : VerbatimLineCommand<"relatesalso">; +def RelatedAlso : VerbatimLineCommand<"relatedalso">; + //===----------------------------------------------------------------------===// // DeclarationVerbatimLineCommand //===----------------------------------------------------------------------===// // Doxygen commands. +def Def : DeclarationVerbatimLineCommand<"def">; def Fn : DeclarationVerbatimLineCommand<"fn">; def Namespace : DeclarationVerbatimLineCommand<"namespace">; def Overload : DeclarationVerbatimLineCommand<"overload">; diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentDiagnostic.h b/contrib/llvm/tools/clang/include/clang/AST/CommentDiagnostic.h index 6e89410..312da06 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define COMMENTSTART #include "clang/Basic/DiagnosticCommentKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentParser.h b/contrib/llvm/tools/clang/include/clang/AST/CommentParser.h index d6a1072..7e00813 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentParser.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentParser.h @@ -61,10 +61,8 @@ class Parser { void consumeToken() { if (MoreLATokens.empty()) L.lex(Tok); - else { - Tok = MoreLATokens.back(); - MoreLATokens.pop_back(); - } + else + Tok = MoreLATokens.pop_back_val(); } void putBack(const Token &OldTok) { diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h b/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h index 15e454d..3910960 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h @@ -58,9 +58,6 @@ class Sema { /// AST node for the \\brief command and its aliases. const BlockCommandComment *BriefCommand; - /// AST node for the \\returns command and its aliases. - const BlockCommandComment *ReturnsCommand; - /// AST node for the \\headerfile command. const BlockCommandComment *HeaderfileCommand; @@ -211,7 +208,11 @@ public: bool isFunctionDecl(); bool isAnyFunctionDecl(); + + /// \returns \c true if declaration that this comment is attached to declares + /// a function pointer. bool isFunctionPointerVarDecl(); + bool isFunctionOrMethodVariadic(); bool isObjCMethodDecl(); bool isObjCPropertyDecl(); bool isTemplateOrSpecialization(); @@ -220,6 +221,8 @@ public: bool isUnionDecl(); bool isObjCInterfaceDecl(); bool isObjCProtocolDecl(); + bool isClassTemplateDecl(); + bool isFunctionTemplateDecl(); ArrayRef getParamVars(); diff --git a/contrib/llvm/tools/clang/include/clang/AST/Decl.h b/contrib/llvm/tools/clang/include/clang/AST/Decl.h index a0c76c0..244a7b8 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Decl.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Decl.h @@ -24,6 +24,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/raw_ostream.h" namespace clang { struct ASTTemplateArgumentListInfo; @@ -43,6 +44,7 @@ class TemplateArgumentList; class TemplateParameterList; class TypeLoc; class UnresolvedSetImpl; +class VarTemplateDecl; /// \brief A container of type source information. /// @@ -109,7 +111,6 @@ class NamedDecl : public Decl { private: NamedDecl *getUnderlyingDeclImpl(); - void verifyLinkage() const; protected: NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N) @@ -142,7 +143,7 @@ public: // FIXME: Deprecated, move clients to getName(). std::string getNameAsString() const { return Name.getAsString(); } - void printName(raw_ostream &os) const { return Name.printName(os); } + void printName(raw_ostream &os) const { os << Name; } /// getDeclName - Get the actual, stored name of the declaration, /// which may be a special name. @@ -189,10 +190,13 @@ public: using Decl::isModulePrivate; using Decl::setModulePrivate; - + /// \brief Determine whether this declaration is hidden from name lookup. bool isHidden() const { return Hidden; } - + + /// \brief Set whether this declaration is hidden from name lookup. + void setHidden(bool Hide) { Hidden = Hide; } + /// \brief Determine whether this declaration is a C++ class member. bool isCXXClassMember() const { const DeclContext *DC = getDeclContext(); @@ -212,11 +216,24 @@ public: bool isCXXInstanceMember() const; /// \brief Determine what kind of linkage this entity has. - Linkage getLinkage() const; + /// This is not the linkage as defined by the standard or the codegen notion + /// of linkage. It is just an implementation detail that is used to compute + /// those. + Linkage getLinkageInternal() const; + + /// \brief Get the linkage from a semantic point of view. Entities in + /// anonymous namespaces are external (in c++98). + Linkage getFormalLinkage() const { + return clang::getFormalLinkage(getLinkageInternal()); + } /// \brief True if this decl has external linkage. - bool hasExternalLinkage() const { - return getLinkage() == ExternalLinkage; + bool hasExternalFormalLinkage() const { + return isExternalFormalLinkage(getLinkageInternal()); + } + + bool isExternallyVisible() const { + return clang::isExternallyVisible(getLinkageInternal()); } /// \brief Determines the visibility of this entity. @@ -256,6 +273,13 @@ public: return const_cast(this)->getUnderlyingDecl(); } + NamedDecl *getMostRecentDecl() { + return cast(static_cast(this)->getMostRecentDecl()); + } + const NamedDecl *getMostRecentDecl() const { + return const_cast(this)->getMostRecentDecl(); + } + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; } }; @@ -351,6 +375,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; /// \brief Returns true if this is an anonymous namespace declaration. /// @@ -377,7 +402,7 @@ public: /// \brief Get the original (first) namespace declaration. NamespaceDecl *getOriginalNamespace() { - if (isFirstDeclaration()) + if (isFirstDecl()) return this; return AnonOrFirstNamespaceAndInline.getPointer(); @@ -385,7 +410,7 @@ public: /// \brief Get the original (first) namespace declaration. const NamespaceDecl *getOriginalNamespace() const { - if (isFirstDeclaration()) + if (isFirstDecl()) return this; return AnonOrFirstNamespaceAndInline.getPointer(); @@ -394,9 +419,7 @@ public: /// \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(); - } + bool isOriginalNamespace() const { return isFirstDecl(); } /// \brief Retrieve the anonymous namespace nested inside this namespace, /// if any. @@ -689,11 +712,21 @@ private: /// \brief Whether this variable is (C++0x) constexpr. unsigned IsConstexpr : 1; + + /// \brief Whether this variable is the implicit variable for a lambda + /// init-capture. + unsigned IsInitCapture : 1; + + /// \brief Whether this local extern variable's previous declaration was + /// declared in the same block scope. This controls whether we should merge + /// the type of this declaration with its previous declaration. + unsigned PreviousDeclInSameBlockScope : 1; }; - enum { NumVarDeclBits = 12 }; + enum { NumVarDeclBits = 14 }; friend class ASTDeclReader; friend class StmtIteratorBase; + friend class ASTNodeImporter; protected: enum { NumParameterIndexBits = 8 }; @@ -732,15 +765,8 @@ protected: }; VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, StorageClass SC) - : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() { - assert(sizeof(VarDeclBitfields) <= sizeof(unsigned)); - assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned)); - AllBits = 0; - VarDeclBits.SClass = SC; - // Everything else is implicitly initialized to false. - } + SourceLocation IdLoc, IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, StorageClass SC); typedef Redeclarable redeclarable_base; virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); } @@ -757,6 +783,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; static VarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -797,7 +824,8 @@ public: /// is a non-static local variable. bool hasLocalStorage() const { if (getStorageClass() == SC_None) - return !isFileVarDecl(); + // Second check is for C++11 [dcl.stc]p4. + return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified; // Return true for: Auto, Register. // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal. @@ -808,7 +836,10 @@ public: /// isStaticLocal - Returns true if a variable with function scope is a /// static local variable. bool isStaticLocal() const { - return getStorageClass() == SC_Static && !isFileVarDecl(); + return (getStorageClass() == SC_Static || + // C++11 [dcl.stc]p4 + (getStorageClass() == SC_None && getTSCSpec() == TSCS_thread_local)) + && !isFileVarDecl(); } /// \brief Returns true if a variable has extern or __private_extern__ @@ -818,12 +849,19 @@ public: 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. + /// \brief Returns true for all variables that do not have local storage. + /// + /// This includes all global variables as well as static variables declared + /// within a function. bool hasGlobalStorage() const { return !hasLocalStorage(); } - /// Compute the language linkage. + /// \brief Get the storage duration of this variable, per C++ [basic.stc]. + StorageDuration getStorageDuration() const { + return hasLocalStorage() ? SD_Automatic : + getTSCSpec() ? SD_Thread : SD_Static; + } + + /// \brief Compute the language linkage. LanguageLinkage getLanguageLinkage() const; /// \brief Determines whether this variable is a variable with @@ -847,7 +885,7 @@ public: bool isLocalVarDecl() const { if (getKind() != Decl::Var) return false; - if (const DeclContext *DC = getDeclContext()) + if (const DeclContext *DC = getLexicalDeclContext()) return DC->getRedeclContext()->isFunctionOrMethod(); return false; } @@ -857,7 +895,7 @@ public: bool isFunctionOrMethodVarDecl() const { if (getKind() != Decl::Var) return false; - const DeclContext *DC = getDeclContext()->getRedeclContext(); + const DeclContext *DC = getLexicalDeclContext()->getRedeclContext(); return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block; } @@ -908,10 +946,6 @@ public: 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 { @@ -933,10 +967,11 @@ public: /// isFileVarDecl - Returns true for file scoped variable declaration. bool isFileVarDecl() const { - if (getKind() != Decl::Var) + Kind K = getKind(); + if (K == ParmVar || K == ImplicitParam) return false; - if (getDeclContext()->getRedeclContext()->isFileContext()) + if (getLexicalDeclContext()->getRedeclContext()->isFileContext()) return true; if (isStaticDataMember()) @@ -1000,20 +1035,6 @@ public: 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 @@ -1123,15 +1144,34 @@ public: bool isConstexpr() const { return VarDeclBits.IsConstexpr; } void setConstexpr(bool IC) { VarDeclBits.IsConstexpr = IC; } + /// Whether this variable is the implicit variable for a lambda init-capture. + bool isInitCapture() const { return VarDeclBits.IsInitCapture; } + void setInitCapture(bool IC) { VarDeclBits.IsInitCapture = IC; } + + /// Whether this local extern variable declaration's previous declaration + /// was declared in the same block scope. Only correct in C++. + bool isPreviousDeclInSameBlockScope() const { + return VarDeclBits.PreviousDeclInSameBlockScope; + } + void setPreviousDeclInSameBlockScope(bool Same) { + VarDeclBits.PreviousDeclInSameBlockScope = Same; + } + /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member /// from which it was instantiated. VarDecl *getInstantiatedFromStaticDataMember() const; - /// \brief If this variable is a static data member, determine what kind of + /// \brief If this variable is an instantiation of a variable template or a + /// static data member of a class template, determine what kind of /// template specialization or instantiation this is. TemplateSpecializationKind getTemplateSpecializationKind() const; + /// \brief If this variable is an instantiation of a variable template or a + /// static data member of a class template, determine its point of + /// instantiation. + SourceLocation getPointOfInstantiation() const; + /// \brief If this variable is an instantiation of a static data member of a /// class template specialization, retrieves the member specialization /// information. @@ -1142,6 +1182,26 @@ public: void setTemplateSpecializationKind(TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation = SourceLocation()); + /// \brief Specify that this variable is an instantiation of the + /// static data member VD. + void setInstantiationOfStaticDataMember(VarDecl *VD, + TemplateSpecializationKind TSK); + + /// \brief Retrieves the variable template that is described by this + /// variable declaration. + /// + /// Every variable template is represented as a VarTemplateDecl and a + /// VarDecl. The former contains template properties (such as + /// the template parameter lists) while the latter contains the + /// actual description of the template's + /// contents. VarTemplateDecl::getTemplatedDecl() retrieves the + /// VarDecl that from a VarTemplateDecl, while + /// getDescribedVarTemplate() retrieves the VarTemplateDecl from + /// a VarDecl. + VarTemplateDecl *getDescribedVarTemplate() const; + + void setDescribedVarTemplate(VarTemplateDecl *Template); + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; } @@ -1314,11 +1374,7 @@ public: ParmVarDeclBits.HasInheritedDefaultArg = I; } - QualType getOriginalType() const { - if (getTypeSourceInfo()) - return getTypeSourceInfo()->getType(); - return getType(); - } + QualType getOriginalType() const; /// \brief Determine whether this parameter is actually a function /// parameter pack. @@ -1517,6 +1573,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, @@ -1701,6 +1758,10 @@ public: /// entry point into an executable program. bool isMain() const; + /// \brief Determines whether this function is a MSVCRT user defined entry + /// point. + bool isMSVCRTEntryPoint() const; + /// \brief Determines whether this operator new or delete is one /// of the reserved global placement operators: /// void *operator new(size_t, void *); @@ -1716,6 +1777,28 @@ public: /// This function must be an allocation or deallocation function. bool isReservedGlobalPlacementOperator() const; + /// \brief Determines whether this function is one of the replaceable + /// global allocation functions: + /// void *operator new(size_t); + /// void *operator new(size_t, const std::nothrow_t &) noexcept; + /// void *operator new[](size_t); + /// void *operator new[](size_t, const std::nothrow_t &) noexcept; + /// void operator delete(void *) noexcept; + /// void operator delete(void *, std::size_t) noexcept; [C++1y] + /// void operator delete(void *, const std::nothrow_t &) noexcept; + /// void operator delete[](void *) noexcept; + /// void operator delete[](void *, std::size_t) noexcept; [C++1y] + /// void operator delete[](void *, const std::nothrow_t &) noexcept; + /// These functions have special behavior under C++1y [expr.new]: + /// An implementation is allowed to omit a call to a replaceable global + /// allocation function. [...] + bool isReplaceableGlobalAllocationFunction() const; + + /// \brief Determine whether this function is a sized global deallocation + /// function in C++1y. If so, find and return the corresponding unsized + /// deallocation function. + FunctionDecl *getCorrespondingUnsizedGlobalDeallocationFunction() const; + /// Compute the language linkage. LanguageLinkage getLanguageLinkage() const; @@ -2039,7 +2122,7 @@ public: /// FieldDecl - An instance of this class is created by Sema::ActOnField to /// represent a member of a struct/union/class. -class FieldDecl : public DeclaratorDecl { +class FieldDecl : public DeclaratorDecl, public Mergeable { // FIXME: This can be packed into the bitfields in Decl. bool Mutable : 1; mutable unsigned CachedFieldIndex : 31; @@ -2153,6 +2236,10 @@ public: SourceRange getSourceRange() const LLVM_READONLY; + /// Retrieves the canonical declaration of this field. + FieldDecl *getCanonicalDecl() { return getFirstDecl(); } + const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstField && K <= lastField; } @@ -2165,7 +2252,7 @@ public: /// 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 { +class EnumConstantDecl : public ValueDecl, public Mergeable { Stmt *Init; // an integer constant expression llvm::APSInt Val; // The value. protected: @@ -2191,6 +2278,10 @@ public: SourceRange getSourceRange() const LLVM_READONLY; + /// Retrieves the canonical declaration of this enumerator. + EnumConstantDecl *getCanonicalDecl() { return getFirstDecl(); } + const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == EnumConstant; } @@ -2289,14 +2380,14 @@ public: /// 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; + typedef std::pair ModedTInfo; + llvm::PointerUnion MaybeModedTInfo; protected: TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) - : TypeDecl(DK, DC, IdLoc, Id, StartLoc), TInfo(TInfo) {} + : TypeDecl(DK, DC, IdLoc, Id, StartLoc), MaybeModedTInfo(TInfo) {} typedef Redeclarable redeclarable_base; virtual TypedefNameDecl *getNextRedeclaration() { @@ -2315,26 +2406,31 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; - TypeSourceInfo *getTypeSourceInfo() const { - return TInfo; - } + bool isModed() const { return MaybeModedTInfo.is(); } - /// Retrieves the canonical declaration of this typedef-name. - TypedefNameDecl *getCanonicalDecl() { - return getFirstDeclaration(); - } - const TypedefNameDecl *getCanonicalDecl() const { - return getFirstDeclaration(); + TypeSourceInfo *getTypeSourceInfo() const { + return isModed() + ? MaybeModedTInfo.get()->first + : MaybeModedTInfo.get(); } - QualType getUnderlyingType() const { - return TInfo->getType(); + return isModed() + ? MaybeModedTInfo.get()->second + : MaybeModedTInfo.get()->getType(); } void setTypeSourceInfo(TypeSourceInfo *newType) { - TInfo = newType; + MaybeModedTInfo = newType; + } + void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) { + MaybeModedTInfo = new (getASTContext()) ModedTInfo(unmodedTSI, modedTy); } + /// Retrieves the canonical declaration of this typedef-name. + TypedefNameDecl *getCanonicalDecl() { return getFirstDecl(); } + const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { @@ -2436,6 +2532,9 @@ protected: /// This option is only enabled when modules are enabled. bool MayHaveOutOfDateDef : 1; + /// Has the full definition of this type been required by a use somewhere in + /// the TU. + bool IsCompleteDefinitionRequired : 1; private: SourceLocation RBraceLoc; @@ -2443,33 +2542,33 @@ private: // to be used for the (uncommon) case of out-of-line declarations. typedef QualifierInfo ExtInfo; - /// TypedefNameDeclOrQualifier - If the (out-of-line) tag declaration name + /// \brief If the (out-of-line) tag declaration name /// is qualified, it points to the qualifier info (nns and range); /// otherwise, if the tag declaration is anonymous and it is part of /// a typedef or alias, it points to the TypedefNameDecl (used for mangling); + /// otherwise, if the tag declaration is anonymous and it is used as a + /// declaration specifier for variables, it points to the first VarDecl (used + /// for mangling); /// otherwise, it is a null (TypedefNameDecl) pointer. - llvm::PointerUnion TypedefNameDeclOrQualifier; + llvm::PointerUnion NamedDeclOrQualifier; - bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is(); } - ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get(); } + bool hasExtInfo() const { return NamedDeclOrQualifier.is(); } + ExtInfo *getExtInfo() { return NamedDeclOrQualifier.get(); } const ExtInfo *getExtInfo() const { - return TypedefNameDeclOrQualifier.get(); + return NamedDeclOrQualifier.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) { + TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, + IdentifierInfo *Id, TagDecl *PrevDecl, SourceLocation StartL) + : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), TagDeclKind(TK), + IsCompleteDefinition(false), IsBeingDefined(false), + IsEmbeddedInDeclarator(false), IsFreeStanding(false), + IsCompleteDefinitionRequired(false), + NamedDeclOrQualifier((NamedDecl *)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); + setPreviousDecl(PrevDecl); } typedef Redeclarable redeclarable_base; @@ -2492,6 +2591,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; SourceLocation getRBraceLoc() const { return RBraceLoc; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } @@ -2522,6 +2622,12 @@ public: return IsCompleteDefinition; } + /// \brief Return true if this complete decl is + /// required to be complete for some existing use. + bool isCompleteDefinitionRequired() const { + return IsCompleteDefinitionRequired; + } + /// isBeingDefined - Return true if this decl is currently being defined. bool isBeingDefined() const { return IsBeingDefined; @@ -2563,6 +2669,10 @@ public: void setCompleteDefinition(bool V) { IsCompleteDefinition = V; } + void setCompleteDefinitionRequired(bool V = true) { + IsCompleteDefinitionRequired = V; + } + // FIXME: Return StringRef; const char *getKindName() const { return TypeWithKeyword::getTagTypeKindName(getTagKind()); @@ -2599,11 +2709,22 @@ public: return (getDeclName() || getTypedefNameForAnonDecl()); } + bool hasDeclaratorForAnonDecl() const { + return dyn_cast_or_null( + NamedDeclOrQualifier.get()); + } + DeclaratorDecl *getDeclaratorForAnonDecl() const { + return hasExtInfo() ? 0 : dyn_cast_or_null( + NamedDeclOrQualifier.get()); + } + TypedefNameDecl *getTypedefNameForAnonDecl() const { - return hasExtInfo() ? 0 : - TypedefNameDeclOrQualifier.get(); + return hasExtInfo() ? 0 : dyn_cast_or_null( + NamedDeclOrQualifier.get()); } + void setDeclaratorForAnonDecl(DeclaratorDecl *DD) { NamedDeclOrQualifier = DD; } + void setTypedefNameForAnonDecl(TypedefNameDecl *TDD); /// \brief Retrieve the nested-name-specifier that qualifies the name of this @@ -2702,21 +2823,22 @@ public: return cast(TagDecl::getCanonicalDecl()); } const EnumDecl *getCanonicalDecl() const { - return cast(TagDecl::getCanonicalDecl()); + return const_cast(this)->getCanonicalDecl(); } - const EnumDecl *getPreviousDecl() const { - return cast_or_null(TagDecl::getPreviousDecl()); - } EnumDecl *getPreviousDecl() { - return cast_or_null(TagDecl::getPreviousDecl()); + return cast_or_null( + static_cast(this)->getPreviousDecl()); } - - const EnumDecl *getMostRecentDecl() const { - return cast(TagDecl::getMostRecentDecl()); + const EnumDecl *getPreviousDecl() const { + return const_cast(this)->getPreviousDecl(); } + EnumDecl *getMostRecentDecl() { - return cast(TagDecl::getMostRecentDecl()); + return cast(static_cast(this)->getMostRecentDecl()); + } + const EnumDecl *getMostRecentDecl() const { + return const_cast(this)->getMostRecentDecl(); } EnumDecl *getDefinition() const { @@ -2912,18 +3034,19 @@ public: 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()); + return cast_or_null( + static_cast(this)->getPreviousDecl()); } - - const RecordDecl *getMostRecentDecl() const { - return cast(TagDecl::getMostRecentDecl()); + const RecordDecl *getPreviousDecl() const { + return const_cast(this)->getPreviousDecl(); } + RecordDecl *getMostRecentDecl() { - return cast(TagDecl::getMostRecentDecl()); + return cast(static_cast(this)->getMostRecentDecl()); + } + const RecordDecl *getMostRecentDecl() const { + return const_cast(this)->getMostRecentDecl(); } bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; } @@ -3106,13 +3229,17 @@ private: Capture *Captures; unsigned NumCaptures; + unsigned ManglingNumber; + Decl *ManglingContextDecl; + protected: BlockDecl(DeclContext *DC, SourceLocation CaretLoc) : Decl(Block, DC, CaretLoc), DeclContext(Block), IsVariadic(false), CapturesCXXThis(false), BlockMissingReturnType(true), IsConversionFromLambda(false), ParamInfo(0), NumParams(0), Body(0), - SignatureAsWritten(0), Captures(0), NumCaptures(0) {} + SignatureAsWritten(0), Captures(0), NumCaptures(0), + ManglingNumber(0), ManglingContextDecl(0) {} public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); @@ -3182,6 +3309,18 @@ public: const Capture *end, bool capturesCXXThis); + unsigned getBlockManglingNumber() const { + return ManglingNumber; + } + Decl *getBlockManglingContextDecl() const { + return ManglingContextDecl; + } + + void setBlockMangling(unsigned Number, Decl *Ctx) { + ManglingNumber = Number; + ManglingContextDecl = Ctx; + } + virtual SourceRange getSourceRange() const LLVM_READONLY; // Implement isa/cast/dyncast/etc. @@ -3354,7 +3493,7 @@ inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, } template -void Redeclarable::setPreviousDeclaration(decl_type *PrevDecl) { +void Redeclarable::setPreviousDecl(decl_type *PrevDecl) { // Note: This routine is implemented here because we need both NamedDecl // and Redeclarable to be defined. @@ -3364,10 +3503,16 @@ void Redeclarable::setPreviousDeclaration(decl_type *PrevDecl) { // Point to previous. Make sure that this is actually the most recent // redeclaration, or we can build invalid chains. If the most recent // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. - First = PrevDecl->getFirstDeclaration(); + First = PrevDecl->getFirstDecl(); assert(First->RedeclLink.NextIsLatest() && "Expected first"); decl_type *MostRecent = First->RedeclLink.getNext(); RedeclLink = PreviousDeclLink(cast(MostRecent)); + + // If the declaration was previously visible, a redeclaration of it remains + // visible even if it wouldn't be visible by itself. + static_cast(this)->IdentifierNamespace |= + MostRecent->getIdentifierNamespace() & + (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type); } else { // Make this first. First = static_cast(this); diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclAccessPair.h b/contrib/llvm/tools/clang/include/clang/AST/DeclAccessPair.h index 5731308..3c5056c 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclAccessPair.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclAccessPair.h @@ -28,7 +28,7 @@ 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 + uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial enum { Mask = 0x3 }; @@ -40,10 +40,10 @@ public: } NamedDecl *getDecl() const { - return (NamedDecl*) (~Mask & (uintptr_t) Ptr); + return reinterpret_cast(~Mask & Ptr); } AccessSpecifier getAccess() const { - return AccessSpecifier(Mask & (uintptr_t) Ptr); + return AccessSpecifier(Mask & Ptr); } void setDecl(NamedDecl *D) { @@ -53,8 +53,7 @@ public: set(getDecl(), AS); } void set(NamedDecl *D, AccessSpecifier AS) { - Ptr = reinterpret_cast(uintptr_t(AS) | - reinterpret_cast(D)); + Ptr = uintptr_t(AS) | reinterpret_cast(D); } operator NamedDecl*() const { return getDecl(); } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h index 754facf..26eea64 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h @@ -16,6 +16,7 @@ #include "clang/AST/AttrIterator.h" #include "clang/AST/DeclarationName.h" +#include "clang/Basic/Linkage.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/Support/Compiler.h" @@ -31,6 +32,7 @@ class DeclarationName; class DependentDiagnostic; class EnumDecl; class FunctionDecl; +class LinkageComputer; class LinkageSpecDecl; class Module; class NamedDecl; @@ -157,7 +159,12 @@ public: /// 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 + IDNS_NonMemberOperator = 0x0400, + + /// This declaration is a function-local extern declaration of a + /// variable or function. This may also be IDNS_Ordinary if it + /// has been declared outside any function. + IDNS_LocalExtern = 0x0800 }; /// ObjCDeclQualifier - 'Qualifiers' written next to the return and @@ -284,19 +291,16 @@ protected: /// 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; + /// \brief If 0, we have not computed the linkage of this declaration. + /// Otherwise, it is the linkage + 1. + mutable unsigned CacheValidAndLinkage : 3; friend class ASTDeclWriter; friend class ASTDeclReader; friend class ASTReader; + friend class LinkageComputer; + + template friend class Redeclarable; private: void CheckAccessDeclContext() const; @@ -309,7 +313,7 @@ protected: HasAttrs(false), Implicit(false), Used(false), Referenced(false), Access(AS_none), FromASTFile(0), Hidden(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), - HasCachedLinkage(0) + CacheValidAndLinkage(0) { if (StatisticsEnabled) add(DK); } @@ -319,7 +323,7 @@ protected: HasAttrs(false), Implicit(false), Used(false), Referenced(false), Access(AS_none), FromASTFile(0), Hidden(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), - HasCachedLinkage(0) + CacheValidAndLinkage(0) { if (StatisticsEnabled) add(DK); } @@ -341,6 +345,18 @@ protected: /// \brief Update a potentially out-of-date declaration. void updateOutOfDate(IdentifierInfo &II) const; + Linkage getCachedLinkage() const { + return Linkage(CacheValidAndLinkage - 1); + } + + void setCachedLinkage(Linkage L) const { + CacheValidAndLinkage = L + 1; + } + + bool hasCachedLinkage() const { + return CacheValidAndLinkage; + } + public: /// \brief Source range that this declaration covers. @@ -419,7 +435,6 @@ public: return const_cast(const_cast(this)->getAttrs()); } const AttrVec &getAttrs() const; - void swapAttrs(Decl *D); void dropAttrs(); void addAttr(Attr *A) { @@ -490,7 +505,16 @@ public: /// whether the function is used. bool isUsed(bool CheckUsedAttr = true) const; - void setUsed(bool U = true) { Used = U; } + /// \brief Set whether the declaration is used, in the sense of odr-use. + /// + /// This should only be used immediately after creating a declaration. + void setIsUsed() { Used = true; } + + /// \brief Mark the declaration used, in the sense of odr-use. + /// + /// This notifies any mutation listeners in addition to setting a bit + /// indicating the declaration is used. + void markUsed(ASTContext &C); /// \brief Whether this declaration was referenced. bool isReferenced() const; @@ -513,13 +537,13 @@ public: NextInContextAndBits.setInt(Bits); } -protected: /// \brief Whether this declaration was marked as being private to the /// module in which it was defined. - bool isModulePrivate() const { + bool isModulePrivate() const { return NextInContextAndBits.getInt() & ModulePrivateFlag; } - + +protected: /// \brief Specify whether this declaration was marked as being private /// to the module in which it was defined. void setModulePrivate(bool MP = true) { @@ -761,7 +785,12 @@ public: const Decl *getPreviousDecl() const { return const_cast(this)->getPreviousDeclImpl(); } - + + /// \brief True if this is the first declaration in its redeclaration chain. + bool isFirstDecl() const { + return getPreviousDecl() == 0; + } + /// \brief Retrieve the most recent declaration that declares the same entity /// as this declaration (which may be this declaration). Decl *getMostRecentDecl() { return getMostRecentDeclImpl(); } @@ -777,8 +806,10 @@ public: /// 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 + /// \brief Returns true if this \c Decl represents a declaration for a body of /// code, such as a function or method definition. + /// Note that \c hasBody can also return true if any redeclaration of this + /// \c Decl represents a declaration for a body of code. virtual bool hasBody() const { return getBody() != 0; } /// getBodyRBrace - Gets the right brace of the body, if a body exists. @@ -808,37 +839,71 @@ public: bool isFunctionOrFunctionTemplate() const; /// \brief Changes the namespace of this declaration to reflect that it's + /// a function-local extern declaration. + /// + /// These declarations appear in the lexical context of the extern + /// declaration, but in the semantic context of the enclosing namespace + /// scope. + void setLocalExternDecl() { + assert((IdentifierNamespace == IDNS_Ordinary || + IdentifierNamespace == IDNS_OrdinaryFriend) && + "namespace is not ordinary"); + + Decl *Prev = getPreviousDecl(); + IdentifierNamespace &= ~IDNS_Ordinary; + + IdentifierNamespace |= IDNS_LocalExtern; + if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary) + IdentifierNamespace |= IDNS_Ordinary; + } + + /// \brief Determine whether this is a block-scope declaration with linkage. + /// This will either be a local variable declaration declared 'extern', or a + /// local function declaration. + bool isLocalExternDecl() { + return IdentifierNamespace & IDNS_LocalExtern; + } + + /// \brief Changes the namespace of this declaration to reflect that it's /// the object of a friend declaration. /// /// These declarations appear in the lexical context of the friending /// class, but in the semantic context of the actual entity. This property /// applies only to a specific decl object; other redeclarations of the /// same entity may not (and probably don't) share this property. - void setObjectOfFriendDecl(bool PreviouslyDeclared) { + void setObjectOfFriendDecl(bool PerformFriendInjection = false) { unsigned OldNS = IdentifierNamespace; assert((OldNS & (IDNS_Tag | IDNS_Ordinary | - IDNS_TagFriend | IDNS_OrdinaryFriend)) && + IDNS_TagFriend | IDNS_OrdinaryFriend | + IDNS_LocalExtern)) && "namespace includes neither ordinary nor tag"); assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | - IDNS_TagFriend | IDNS_OrdinaryFriend)) && + IDNS_TagFriend | IDNS_OrdinaryFriend | + IDNS_LocalExtern)) && "namespace includes other than ordinary or tag"); - IdentifierNamespace = 0; + Decl *Prev = getPreviousDecl(); + IdentifierNamespace &= ~(IDNS_Ordinary | IDNS_Tag | IDNS_Type); + if (OldNS & (IDNS_Tag | IDNS_TagFriend)) { IdentifierNamespace |= IDNS_TagFriend; - if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Tag | IDNS_Type; + if (PerformFriendInjection || + (Prev && Prev->getIdentifierNamespace() & IDNS_Tag)) + IdentifierNamespace |= IDNS_Tag | IDNS_Type; } - if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend)) { + if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend | IDNS_LocalExtern)) { IdentifierNamespace |= IDNS_OrdinaryFriend; - if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Ordinary; + if (PerformFriendInjection || + (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)) + IdentifierNamespace |= IDNS_Ordinary; } } enum FriendObjectKind { - FOK_None, // not a friend object - FOK_Declared, // a friend of a previously-declared entity - FOK_Undeclared // a friend of a previously-undeclared entity + 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 @@ -846,11 +911,11 @@ public: /// /// There is currently no direct way to find the associated FriendDecl. FriendObjectKind getFriendObjectKind() const { - unsigned mask - = (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend)); + unsigned mask = + (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend)); if (!mask) return FOK_None; - return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ? - FOK_Declared : FOK_Undeclared); + return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ? FOK_Declared + : FOK_Undeclared); } /// Specifies that this declaration is a C++ overloaded non-member. @@ -877,9 +942,6 @@ public: // Same as dump(), but forces color printing. LLVM_ATTRIBUTE_USED void dumpColor() const; void dump(raw_ostream &Out) const; - // Debuggers don't usually respect default arguments. - LLVM_ATTRIBUTE_USED void dumpXML() const; - void dumpXML(raw_ostream &OS) const; private: void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx); @@ -974,6 +1036,7 @@ protected: mutable Decl *LastDecl; friend class ExternalASTSource; + friend class ASTDeclReader; friend class ASTWriter; /// \brief Build up a chain of declarations. @@ -1096,6 +1159,14 @@ public: /// C++0x scoped enums), and C++ linkage specifications. bool isTransparentContext() const; + /// \brief Determines whether this context or some of its ancestors is a + /// linkage specification context that specifies C linkage. + bool isExternCContext() const; + + /// \brief Determines whether this context or some of its ancestors is a + /// linkage specification context that specifies C++ linkage. + bool isExternCXXContext() const; + /// \brief Determine whether this declaration context is equivalent /// to the declaration context DC. bool Equals(const DeclContext *DC) const { @@ -1429,12 +1500,20 @@ public: return const_cast(this)->lookup(Name); } + /// \brief Find the declarations with the given name that are visible + /// within this context; don't attempt to retrieve anything from an + /// external source. + lookup_result noload_lookup(DeclarationName Name); + /// \brief A simplistic name lookup mechanism that performs name lookup /// into this declaration context without consulting the external source. /// /// This function should almost never be used, because it subverts the /// usual relationship between a DeclContext and the external source. /// See the ASTImporter for the (few, but important) use cases. + /// + /// FIXME: This is very inefficient; replace uses of it with uses of + /// noload_lookup. void localUncachedLookup(DeclarationName Name, SmallVectorImpl &Results); @@ -1458,10 +1537,16 @@ public: /// of looking up every possible name. class all_lookups_iterator; + /// \brief Iterators over all possible lookups within this context. all_lookups_iterator lookups_begin() const; - all_lookups_iterator lookups_end() const; + /// \brief Iterators over all possible lookups within this context that are + /// currently loaded; don't attempt to retrieve anything from an external + /// source. + all_lookups_iterator noload_lookups_begin() const; + all_lookups_iterator noload_lookups_end() const; + /// udir_iterator - Iterates through the using-directives stored /// within this context. typedef UsingDirectiveDecl * const * udir_iterator; @@ -1532,6 +1617,8 @@ public: static bool classof(const DeclContext *D) { return true; } LLVM_ATTRIBUTE_USED void dumpDeclContext() const; + LLVM_ATTRIBUTE_USED void dumpLookups() const; + LLVM_ATTRIBUTE_USED void dumpLookups(llvm::raw_ostream &OS) const; private: void reconcileExternalVisibleStorage(); @@ -1548,6 +1635,8 @@ private: friend class DependentDiagnostic; StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const; + template void buildLookupImpl(DeclContext *DCtx); void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, bool Rediscoverable); diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h index c483dde..dbc4132 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h @@ -6,10 +6,11 @@ // 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). -// +/// +/// \file +/// \brief Defines the C++ Decl subclasses, other than those for templates +/// (found in DeclTemplate.h) and friends (in DeclFriend.h). +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_DECLCXX_H @@ -88,7 +89,7 @@ namespace llvm { namespace clang { -/// @brief Represents an access specifier followed by colon ':'. +/// \brief Represents an access specifier followed by colon ':'. /// /// An objects of this class represents sugar for the syntactic occurrence /// of an access specifier followed by a colon in the list of member @@ -146,16 +147,16 @@ public: /// level of access (public, protected, private) is used for the /// derivation. For example: /// -/// @code +/// \code /// class A { }; /// class B { }; /// class C : public virtual A, protected B { }; -/// @endcode +/// \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 + /// \brief The source code range that covers the full base /// specifier, including the "virtual" (if present) and access /// specifier (if present). SourceRange Range; @@ -167,25 +168,26 @@ class CXXBaseSpecifier { /// \brief 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. + /// \brief Whether this is the base of a class (true) or of a struct (false). + /// + /// This determines the mapping from the access specifier as written in the + /// source code to the access specifier used for semantic analysis. bool BaseOfClass : 1; - /// 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. + /// \brief Access specifier as written in the source code (may be AS_none). + /// + /// The actual type of data stored here is an AccessSpecifier, but we use + /// "unsigned" here to work around a VC++ bug. unsigned Access : 2; - /// InheritConstructors - Whether the class contains a using declaration + /// \brief 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. + /// \brief The type of the base class. + /// + /// This will be a class or struct (or a typedef of such). The source code + /// range does not include the \c virtual or the access specifier. TypeSourceInfo *BaseTypeInfo; public: @@ -196,14 +198,12 @@ public: : 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. + /// \brief Retrieves the source range that contains the entire base specifier. SourceRange getSourceRange() const LLVM_READONLY { return Range; } SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } - /// isVirtual - Determines whether the base class is a virtual base - /// class (or not). + /// \brief Determines whether the base class is a virtual base class (or not). bool isVirtual() const { return Virtual; } /// \brief Determine whether this base class is a base of a class declared @@ -226,11 +226,11 @@ public: 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(). + /// \brief Returns the access specifier for this base specifier. + /// + /// This is the actual base specifier as used for semantic analysis, so + /// the result can never be AS_none. To retrieve the access specifier as + /// written in the source code, use getAccessSpecifierAsWritten(). AccessSpecifier getAccessSpecifier() const { if ((AccessSpecifier)Access == AS_none) return BaseOfClass? AS_private : AS_public; @@ -238,19 +238,23 @@ public: 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. + /// \brief Retrieves the access specifier as written in the source code + /// (which may mean that no access specifier was explicitly written). + /// + /// Use getAccessSpecifier() to retrieve the access specifier for use in + /// semantic analysis. AccessSpecifier getAccessSpecifierAsWritten() const { return (AccessSpecifier)Access; } - /// getType - Retrieves the type of the base class. This type will - /// always be an unqualified class type. - QualType getType() const { return BaseTypeInfo->getType(); } + /// \brief Retrieves the type of the base class. + /// + /// This type will always be an unqualified class type. + QualType getType() const { + return BaseTypeInfo->getType().getUnqualifiedType(); + } - /// getTypeLoc - Retrieves the type and source location of the base class. + /// \brief Retrieves the type and source location of the base class. TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; } }; @@ -264,7 +268,8 @@ enum MSInheritanceModel { MSIM_Unspecified }; -/// CXXRecordDecl - Represents a C++ struct/union/class. +/// \brief Represents a C++ struct/union/class. +/// /// FIXME: This class will disappear once we've properly taught RecordDecl /// to deal with C++-specific things. class CXXRecordDecl : public RecordDecl { @@ -288,32 +293,32 @@ class CXXRecordDecl : public RecordDecl { /// \brief True if this class has any user-declared constructors. bool UserDeclaredConstructor : 1; - /// The user-declared special members which this class has. + /// \brief The user-declared special members which this class has. unsigned UserDeclaredSpecialMembers : 6; - /// Aggregate - True when this class is an aggregate. + /// \brief True when this class is an aggregate. bool Aggregate : 1; - /// PlainOldData - True when this class is a POD-type. + /// \brief True when this class is a POD-type. bool PlainOldData : 1; - /// Empty - true when this class is empty for traits purposes, + /// 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 + /// \brief 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 + /// \brief True when this class is abstract, i.e., has at least /// one pure virtual function, (that can come from a base class). bool Abstract : 1; - /// IsStandardLayout - True when this class has standard layout. + /// \brief True when this class has standard layout. /// - /// C++0x [class]p7. A standard-layout class is a class that: + /// C++11 [class]p7. A standard-layout class is a class that: /// * has no non-static data members of type non-standard-layout class (or /// array of such types) or reference, /// * has no virtual functions (10.3) and no virtual base classes (10.1), @@ -327,20 +332,19 @@ class CXXRecordDecl : public RecordDecl { /// member. bool IsStandardLayout : 1; - /// HasNoNonEmptyBases - True when there are no non-empty base classes. + /// \brief True when there are no non-empty base classes. /// /// This is a helper bit of state used to implement IsStandardLayout more /// efficiently. bool HasNoNonEmptyBases : 1; - /// HasPrivateFields - True when there are private non-static data members. + /// \brief True when there are private non-static data members. bool HasPrivateFields : 1; - /// HasProtectedFields - True when there are protected non-static data - /// members. + /// \brief True when there are protected non-static data members. bool HasProtectedFields : 1; - /// HasPublicFields - True when there are private non-static data members. + /// \brief True when there are private non-static data members. bool HasPublicFields : 1; /// \brief True if this class (or any subobject) has mutable fields. @@ -353,8 +357,10 @@ class CXXRecordDecl : public RecordDecl { bool HasInClassInitializer : 1; /// \brief True if any field is of reference type, and does not have an - /// in-class initializer. In this case, value-initialization of this class - /// is illegal in C++98 even if the class has a trivial default constructor. + /// in-class initializer. + /// + /// In this case, value-initialization of this class is illegal in C++98 + /// even if the class has a trivial default constructor. bool HasUninitializedReferenceMember : 1; /// \brief These flags are \c true if a defaulted corresponding special @@ -389,30 +395,29 @@ class CXXRecordDecl : public RecordDecl { /// members which have not yet been declared. unsigned DeclaredNonTrivialSpecialMembers : 6; - /// HasIrrelevantDestructor - True when this class has a destructor with no - /// semantic effect. + /// \brief True when this class has a destructor with no semantic effect. bool HasIrrelevantDestructor : 1; - /// HasConstexprNonCopyMoveConstructor - True when this class has at least - /// one user-declared constexpr constructor which is neither the copy nor - /// move constructor. + /// \brief 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. + /// \brief True if a defaulted default constructor for this class would + /// be constexpr. bool DefaultedDefaultConstructorIsConstexpr : 1; - /// HasConstexprDefaultConstructor - True if this class has a constexpr - /// default constructor (either user-declared or implicitly declared). + /// \brief True if this class has a constexpr default constructor. + /// + /// This is true for either a user-declared constexpr default constructor + /// or an implicitly declared constexpr default constructor.. bool HasConstexprDefaultConstructor : 1; - /// HasNonLiteralTypeFieldsOrBases - True when this class contains at least - /// one non-static data member or base class of non-literal or volatile - /// type. + /// \brief True when this class contains at least one non-static data + /// member or base class of non-literal or volatile type. bool HasNonLiteralTypeFieldsOrBases : 1; - /// ComputedVisibleConversions - True when visible conversion functions are - /// already computed and are available. + /// \brief True when visible conversion functions are already computed + /// and are available. bool ComputedVisibleConversions : 1; /// \brief Whether we have a C++11 user-provided default constructor (not @@ -439,50 +444,44 @@ class CXXRecordDecl : public RecordDecl { /// const-qualified reference parameter or a non-reference parameter. bool HasDeclaredCopyAssignmentWithConstParam : 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. + /// \brief The number of base class specifiers in Bases. unsigned NumBases; - /// NumVBases - The number of virtual base class specifiers in VBases. + /// \brief The number of virtual base class specifiers in VBases. unsigned NumVBases; - /// Bases - Base classes of this class. + /// \brief 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. + /// \brief 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. - ASTUnresolvedSet Conversions; + /// \brief The conversion functions of this C++ class (but not its + /// inherited conversion functions). + /// + /// Each of the entries in this overload set is a CXXConversionDecl. + LazyASTUnresolvedSet Conversions; - /// 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 + /// \brief The conversion functions of this C++ class and all those + /// inherited conversion functions that are visible in this class. + /// + /// Each of the entries in this overload set is a CXXConversionDecl or a /// FunctionTemplateDecl. - ASTUnresolvedSet VisibleConversions; + LazyASTUnresolvedSet VisibleConversions; - /// Definition - The declaration which defines this record. + /// \brief 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 The first friend declaration in this class, or null if there + /// aren't any. + /// + /// This is actually currently stored in reverse order. + LazyDeclPtr FirstFriend; /// \brief Retrieve the set of direct base classes. CXXBaseSpecifier *getBases() const { @@ -507,10 +506,12 @@ class CXXRecordDecl : public RecordDecl { struct LambdaDefinitionData : public DefinitionData { typedef LambdaExpr::Capture Capture; - LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, bool Dependent) - : DefinitionData(D), Dependent(Dependent), NumCaptures(0), - NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0), - MethodTyInfo(Info) + LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, + bool Dependent, bool IsGeneric, + LambdaCaptureDefault CaptureDefault) + : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric), + CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0), + ManglingNumber(0), ContextDecl(0), Captures(0), MethodTyInfo(Info) { IsLambda = true; } @@ -522,14 +523,20 @@ class CXXRecordDecl : public RecordDecl { /// 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 + /// artifact of having to parse the default arguments before. unsigned Dependent : 1; - /// \brief The number of captures in this lambda. - unsigned NumCaptures : 16; + /// \brief Whether this lambda is a generic lambda. + unsigned IsGenericLambda : 1; + + /// \brief The Default Capture. + unsigned CaptureDefault : 2; + + /// \brief The number of captures in this lambda is limited 2^NumCaptures. + unsigned NumCaptures : 15; /// \brief The number of explicit captures in this lambda. - unsigned NumExplicitCaptures : 15; + unsigned NumExplicitCaptures : 13; /// \brief The number used to indicate this lambda expression for name /// mangling in the Itanium C++ ABI. @@ -547,6 +554,7 @@ class CXXRecordDecl : public RecordDecl { /// \brief The type of the call method. TypeSourceInfo *MethodTyInfo; + }; struct DefinitionData &data() { @@ -569,7 +577,7 @@ class CXXRecordDecl : public RecordDecl { /// \brief The template or declaration that this declaration /// describes or was instantiated from, respectively. /// - /// For non-templates, this value will be NULL. For record + /// 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 @@ -597,27 +605,29 @@ class CXXRecordDecl : public RecordDecl { friend class ASTNodeImporter; + /// \brief Get the head of our list of friend declarations, possibly + /// deserializing the friends from an external AST source. + FriendDecl *getFirstFriend() const; + protected: CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl); public: - /// base_class_iterator - Iterator that traverses the base classes - /// of a class. + /// \brief 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. + /// \brief 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. + /// \brief 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. + /// \brief Iterator that traverses the base classes of a class in reverse + /// order. typedef std::reverse_iterator reverse_base_class_const_iterator; @@ -628,18 +638,21 @@ public: return cast(RecordDecl::getCanonicalDecl()); } + CXXRecordDecl *getPreviousDecl() { + return cast_or_null( + static_cast(this)->getPreviousDecl()); + } const CXXRecordDecl *getPreviousDecl() const { - return cast_or_null(RecordDecl::getPreviousDecl()); + return const_cast(this)->getPreviousDecl(); } - CXXRecordDecl *getPreviousDecl() { - return cast_or_null(RecordDecl::getPreviousDecl()); + + CXXRecordDecl *getMostRecentDecl() { + return cast( + static_cast(this)->getMostRecentDecl()); } const CXXRecordDecl *getMostRecentDecl() const { - return cast_or_null(RecordDecl::getMostRecentDecl()); - } - CXXRecordDecl *getMostRecentDecl() { - return cast_or_null(RecordDecl::getMostRecentDecl()); + return const_cast(this)->getMostRecentDecl(); } CXXRecordDecl *getDefinition() const { @@ -655,18 +668,18 @@ public: bool DelayTypeCreation = false); static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC, TypeSourceInfo *Info, SourceLocation Loc, - bool DependentLambda); + bool DependentLambda, bool IsGeneric, + LambdaCaptureDefault CaptureDefault); 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. + /// \brief 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. + /// \brief Retrieves the number of base classes of this class. unsigned getNumBases() const { return data().NumBases; } base_class_iterator bases_begin() { return data().getBases(); } @@ -688,8 +701,7 @@ public: return reverse_base_class_const_iterator(bases_begin()); } - /// getNumVBases - Retrieves the number of virtual base classes of this - /// class. + /// \brief Retrieves the number of virtual base classes of this class. unsigned getNumVBases() const { return data().NumVBases; } base_class_iterator vbases_begin() { return data().getVBases(); } @@ -720,12 +732,12 @@ public: /// special methods, etc. typedef specific_decl_iterator method_iterator; - /// method_begin - Method begin iterator. Iterates in the order the methods + /// \brief 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. + /// \brief Method past-the-end iterator. method_iterator method_end() const { return method_iterator(decls_end()); } @@ -749,18 +761,20 @@ public: /// Determines whether this record has any friends. bool hasFriends() const { - return data().FirstFriend != 0; + return data().FirstFriend.isValid(); } /// \brief \c true if we know for sure that this class has a single, /// accessible, unambiguous move constructor that is not deleted. bool hasSimpleMoveConstructor() const { - return !hasUserDeclaredMoveConstructor() && hasMoveConstructor(); + return !hasUserDeclaredMoveConstructor() && hasMoveConstructor() && + !data().DefaultedMoveConstructorIsDeleted; } /// \brief \c true if we know for sure that this class has a single, /// accessible, unambiguous move assignment operator that is not deleted. bool hasSimpleMoveAssignment() const { - return !hasUserDeclaredMoveAssignment() && hasMoveAssignment(); + return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() && + !data().DefaultedMoveAssignmentIsDeleted; } /// \brief \c true if we know for sure that this class has an accessible /// destructor that is not deleted. @@ -784,22 +798,22 @@ public: !(data().DeclaredSpecialMembers & SMF_DefaultConstructor); } - /// hasUserDeclaredConstructor - Whether this class has any - /// user-declared constructors. When true, a default constructor - /// will not be implicitly declared. + /// \brief Determine whether this class has any user-declared constructors. + /// + /// When true, a default constructor will not be implicitly declared. bool hasUserDeclaredConstructor() const { return data().UserDeclaredConstructor; } - /// hasUserProvidedDefaultconstructor - Whether this class has a - /// user-provided default constructor per C++0x. + /// \brief Whether this class has a user-provided default constructor + /// per C++11. 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. + /// \brief Determine whether this class has a user-declared copy constructor. + /// + /// When false, a copy constructor will be implicitly declared. bool hasUserDeclaredCopyConstructor() const { return data().UserDeclaredSpecialMembers & SMF_CopyConstructor; } @@ -830,9 +844,11 @@ public: implicitCopyConstructorHasConstParam()); } - /// 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. + /// \brief Whether this class has a user-declared move constructor or + /// assignment operator. + /// + /// When false, a move constructor and assignment operator may be + /// implicitly declared. bool hasUserDeclaredMoveOperation() const { return data().UserDeclaredSpecialMembers & (SMF_MoveConstructor | SMF_MoveAssignment); @@ -850,28 +866,23 @@ public: needsImplicitMoveConstructor(); } - /// \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 Set that we attempted to declare an implicitly move + /// constructor, but overload resolution failed so we deleted it. + void setImplicitMoveConstructorIsDeleted() { + assert((data().DefaultedMoveConstructorIsDeleted || + needsOverloadResolutionForMoveConstructor()) && + "move constructor should not be deleted"); + data().DefaultedMoveConstructorIsDeleted = true; } /// \brief Determine whether this class should get an implicit move /// constructor or if any existing special member function inhibits this. bool needsImplicitMoveConstructor() const { - return !hasFailedImplicitMoveConstructor() && - !(data().DeclaredSpecialMembers & SMF_MoveConstructor) && + return !(data().DeclaredSpecialMembers & SMF_MoveConstructor) && !hasUserDeclaredCopyConstructor() && !hasUserDeclaredCopyAssignment() && !hasUserDeclaredMoveAssignment() && - !hasUserDeclaredDestructor() && - !data().DefaultedMoveConstructorIsDeleted; + !hasUserDeclaredDestructor(); } /// \brief Determine whether we need to eagerly declare a defaulted move @@ -880,9 +891,10 @@ public: return data().NeedOverloadResolutionForMoveConstructor; } - /// hasUserDeclaredCopyAssignment - Whether this class has a - /// user-declared copy assignment operator. When false, a copy - /// assigment operator will be implicitly declared. + /// \brief Determine whether this class has a user-declared copy assignment + /// operator. + /// + /// When false, a copy assigment operator will be implicitly declared. bool hasUserDeclaredCopyAssignment() const { return data().UserDeclaredSpecialMembers & SMF_CopyAssignment; } @@ -907,7 +919,7 @@ public: /// \brief Determine whether this class has a copy assignment operator with /// a parameter type which is a reference to a const-qualified type or is not - /// a reference.. + /// a reference. bool hasCopyAssignmentWithConstParam() const { return data().HasDeclaredCopyAssignmentWithConstParam || (needsImplicitCopyAssignment() && @@ -926,29 +938,24 @@ public: needsImplicitMoveAssignment(); } - /// \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 Set that we attempted to declare an implicit move assignment + /// operator, but overload resolution failed so we deleted it. + void setImplicitMoveAssignmentIsDeleted() { + assert((data().DefaultedMoveAssignmentIsDeleted || + needsOverloadResolutionForMoveAssignment()) && + "move assignment should not be deleted"); + data().DefaultedMoveAssignmentIsDeleted = true; } /// \brief Determine whether this class should get an implicit move /// assignment operator or if any existing special member function inhibits /// this. bool needsImplicitMoveAssignment() const { - return !hasFailedImplicitMoveAssignment() && - !(data().DeclaredSpecialMembers & SMF_MoveAssignment) && + return !(data().DeclaredSpecialMembers & SMF_MoveAssignment) && !hasUserDeclaredCopyConstructor() && !hasUserDeclaredCopyAssignment() && !hasUserDeclaredMoveConstructor() && - !hasUserDeclaredDestructor() && - !data().DefaultedMoveAssignmentIsDeleted; + !hasUserDeclaredDestructor(); } /// \brief Determine whether we need to eagerly declare a move assignment @@ -957,9 +964,9 @@ public: return data().NeedOverloadResolutionForMoveAssignment; } - /// hasUserDeclaredDestructor - Whether this class has a - /// user-declared destructor. When false, a destructor will be - /// implicitly declared. + /// \brief Determine whether this class has a user-declared destructor. + /// + /// When false, a destructor will be implicitly declared. bool hasUserDeclaredDestructor() const { return data().UserDeclaredSpecialMembers & SMF_Destructor; } @@ -979,15 +986,42 @@ public: /// \brief Determine whether this class describes a lambda function object. bool isLambda() const { return hasDefinition() && data().IsLambda; } + /// \brief Determine whether this class describes a generic + /// lambda function object (i.e. function call operator is + /// a template). + bool isGenericLambda() const; + + /// \brief Retrieve the lambda call operator of the closure type + /// if this is a closure type. + CXXMethodDecl *getLambdaCallOperator() const; + + /// \brief Retrieve the lambda static invoker, the address of which + /// is returned by the conversion operator, and the body of which + /// is forwarded to the lambda call operator. + CXXMethodDecl *getLambdaStaticInvoker() const; + + /// \brief Retrieve the generic lambda's template parameter list. + /// Returns null if the class does not represent a lambda or a generic + /// lambda. + TemplateParameterList *getGenericLambdaTemplateParameterList() const; + + LambdaCaptureDefault getLambdaCaptureDefault() const { + assert(isLambda()); + return static_cast(getLambdaData().CaptureDefault); + } + /// \brief For a closure type, retrieve the mapping from captured - /// variables and this to the non-static data members that store the + /// variables and \c this to the non-static data members that store the /// values or references of the captures. /// /// \param Captures Will be populated with the mapping from captured /// variables to the corresponding fields. /// /// \param ThisCapture Will be set to the field declaration for the - /// 'this' capture. + /// \c this capture. + /// + /// \note No entries will be added for init-captures, as they do not capture + /// variables. void getCaptureFields(llvm::DenseMap &Captures, FieldDecl *&ThisCapture) const; @@ -1001,10 +1035,10 @@ public: typedef UnresolvedSetIterator conversion_iterator; conversion_iterator conversion_begin() const { - return data().Conversions.begin(); + return data().Conversions.get(getASTContext()).begin(); } conversion_iterator conversion_end() const { - return data().Conversions.end(); + return data().Conversions.get(getASTContext()).end(); } /// Removes a conversion function from this class. The conversion @@ -1012,38 +1046,39 @@ public: /// 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. + /// \brief Get all conversion functions visible in current class, + /// including conversion function templates. std::pair 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). + /// Determine whether this class is an aggregate (C++ [dcl.init.aggr]), + /// which is a class with no user-declared constructors, no private + /// or protected non-static data members, no base classes, and no virtual + /// functions (C++ [dcl.init.aggr]p1). bool isAggregate() const { return data().Aggregate; } - /// hasInClassInitializer - Whether this class has any in-class initializers + /// \brief Whether this class has any in-class initializers /// for non-static data members. bool hasInClassInitializer() const { return data().HasInClassInitializer; } /// \brief Whether this class or any of its subobjects has any members of - /// reference type which would make value-initialization ill-formed, per - /// C++03 [dcl.init]p5: - /// -- if T is a non-union class type without a user-declared constructor, - /// then every non-static data member and base-class component of T is - /// value-initialized - /// [...] - /// A program that calls for [...] value-initialization of an entity of - /// reference type is ill-formed. + /// reference type which would make value-initialization ill-formed. + /// + /// Per C++03 [dcl.init]p5: + /// - if T is a non-union class type without a user-declared constructor, + /// then every non-static data member and base-class component of T is + /// value-initialized [...] A program that calls for [...] + /// value-initialization of an entity of reference type is ill-formed. bool hasUninitializedReferenceMember() const { return !isUnion() && !hasUserDeclaredConstructor() && data().HasUninitializedReferenceMember; } - /// 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 + /// \brief Whether this class is a POD-type (C++ [class]p4) + /// + /// For purposes of this function a class is POD if it is an aggregate + /// that has no non-static non-POD data members, no reference data + /// members, no user-defined copy assignment operator and no /// user-defined destructor. /// /// Note that this is the C++ TR1 definition of POD. @@ -1053,26 +1088,33 @@ public: /// 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. + /// \brief Determine whether this is an empty class in the sense of + /// (C++11 [meta.unary.prop]). + /// + /// A non-union class is empty iff it has a virtual function, virtual base, + /// data member (other than 0-width bit-field) or inherits from a non-empty + /// class. + /// + /// \note This does NOT include a check for union-ness. bool isEmpty() const { return data().Empty; } - /// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]), + /// 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. + /// \brief Determine whether this class has a pure virtual function. + /// + /// The class is is abstract per (C++ [class.abstract]p2) if it declares + /// a pure virtual function or inherits a pure virtual function that is + /// not overridden. bool isAbstract() const { return data().Abstract; } - /// isStandardLayout - Whether this class has standard layout + /// \brief Determine whether this class has standard layout per /// (C++ [class]p7) bool isStandardLayout() const { return data().IsStandardLayout; } - /// \brief Whether this class, or any of its class subobjects, contains a - /// mutable field. + /// \brief Determine whether this class, or any of its class subobjects, + /// contains a mutable field. bool hasMutableFields() const { return data().HasMutableFields; } /// \brief Determine whether this class has a trivial default constructor @@ -1180,47 +1222,49 @@ public: return !(data().HasTrivialSpecialMembers & SMF_Destructor); } - // 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. + /// \brief Determine whether this class has a destructor which has no + /// semantic effect. + /// + /// Any such destructor will be trivial, public, defaulted and not deleted, + /// and will call only irrelevant destructors. bool hasIrrelevantDestructor() const { return data().HasIrrelevantDestructor; } - // hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal or - // volatile type non-static data member or base class. + /// \brief Determine whether this class has a non-literal or/ volatile type + /// non-static data member or base class. bool hasNonLiteralTypeFieldsOrBases() const { return data().HasNonLiteralTypeFieldsOrBases; } - // isTriviallyCopyable - Whether this class is considered trivially copyable - // (C++0x [class]p6). + /// \brief Determine whether this class is considered trivially copyable per + /// (C++11 [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. + /// \brief Determine whether this class is considered trivial. + /// + /// C++11 [class]p6: + /// "A trivial class is a class that has a trivial default constructor and + /// is trivially copiable." bool isTrivial() const { return isTriviallyCopyable() && hasTrivialDefaultConstructor(); } - // 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. + /// \brief Determine whether this class is a literal type. + /// + /// C++11 [basic.types]p10: + /// A class type that has all the following properties: + /// - it has a trivial destructor + /// - every constructor call and full-expression in the + /// brace-or-equal-intializers for non-static data members (if any) is + /// a constant expression. + /// - it is an aggregate type or has at least one constexpr constructor + /// or constructor template that is not a copy or move constructor, and + /// - all of its non-static data members and base classes are of literal + /// types + /// + /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by + /// treating types with trivial default constructors as literal types. bool isLiteral() const { return hasTrivialDestructor() && (isAggregate() || hasConstexprNonCopyMoveConstructor() || @@ -1231,15 +1275,15 @@ public: /// \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 + /// This routine will return non-null for (non-templated) member /// classes of class templates. For example, given: /// - /// @code + /// \code /// template /// struct X { /// struct A { }; /// }; - /// @endcode + /// \endcode /// /// The declaration for X::A is a (non-templated) CXXRecordDecl /// whose parent is the class template specialization X. For @@ -1257,7 +1301,7 @@ public: } /// \brief Specify that this record is an instantiation of the - /// member class RD. + /// member class \p RD. void setInstantiationOfMemberClass(CXXRecordDecl *RD, TemplateSpecializationKind TSK); @@ -1288,10 +1332,10 @@ public: /// \brief Set the kind of specialization or template instantiation this is. void setTemplateSpecializationKind(TemplateSpecializationKind TSK); - /// getDestructor - Returns the destructor decl for this class. + /// \brief Returns the destructor decl for this class. CXXDestructorDecl *getDestructor() const; - /// isLocalClass - If the class is a local class [class.local], returns + /// \brief If the class is a local class [class.local], returns /// the enclosing function declaration. const FunctionDecl *isLocalClass() const { if (const CXXRecordDecl *RD = dyn_cast(getDeclContext())) @@ -1300,6 +1344,11 @@ public: return dyn_cast(getDeclContext()); } + FunctionDecl *isLocalClass() { + return const_cast( + const_cast(this)->isLocalClass()); + } + /// \brief Determine whether this dependent class is a current instantiation, /// when viewed from within the given context. bool isCurrentInstantiation(const DeclContext *CurContext) const; @@ -1328,7 +1377,7 @@ public: /// \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. + /// \returns true if this class is derived from \p Base, false otherwise. /// /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than /// tangling input and output in \p Paths @@ -1367,6 +1416,13 @@ public: /// The class itself does not count as a base class. This routine /// returns false if the class has non-computable base classes. /// + /// \param BaseMatches Callback invoked for each (direct or indirect) base + /// class of this type, or if \p AllowShortCircuit is true then until a call + /// returns false. + /// + /// \param UserData Passed as the second argument of every call to + /// \p BaseMatches. + /// /// \param AllowShortCircuit if false, forces the callback to be called /// for every base class, even if a dependent or non-matching base was /// found. @@ -1471,12 +1527,12 @@ public: /// \brief Get the indirect primary bases for this class. void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const; - /// viewInheritance - Renders and displays an inheritance diagram + /// 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 + /// \brief Calculates the access of a decl that is reached /// along a path. static AccessSpecifier MergeAccess(AccessSpecifier PathAccess, AccessSpecifier DeclAccess) { @@ -1575,8 +1631,10 @@ public: friend class ASTWriter; }; -/// CXXMethodDecl - Represents a static or instance method of a -/// struct/union/class. +/// \brief Represents a static or instance method of a struct/union/class. +/// +/// In the terminology of the C++ Standard, these are the (static and +/// non-static) member functions, whether virtual or not. class CXXMethodDecl : public FunctionDecl { virtual void anchor(); protected: @@ -1606,6 +1664,18 @@ public: bool isStatic() const; bool isInstance() const { return !isStatic(); } + /// Returns true if the given operator is implicitly static in a record + /// context. + static bool isStaticOverloadedOperator(OverloadedOperatorKind OOK) { + // [class.free]p1: + // Any allocation function for a class T is a static member + // (even if not explicitly declared static). + // [class.free]p6 Any deallocation function for a class X is a static member + // (even if not explicitly declared static). + return OOK == OO_New || OOK == OO_Array_New || OOK == OO_Delete || + OOK == OO_Array_Delete; + } + bool isConst() const { return getType()->castAs()->isConst(); } bool isVolatile() const { return getType()->castAs()->isVolatile(); } @@ -1633,14 +1703,22 @@ public: /// \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()); } + const CXXMethodDecl *getCanonicalDecl() const { + return const_cast(this)->getCanonicalDecl(); + } + + CXXMethodDecl *getMostRecentDecl() { + return cast( + static_cast(this)->getMostRecentDecl()); + } + const CXXMethodDecl *getMostRecentDecl() const { + return const_cast(this)->getMostRecentDecl(); + } - /// isUserProvided - True if this method is user-declared and was not + /// True if this method is user-declared and was not /// deleted or defaulted on its first declaration. bool isUserProvided() const { return !(isDeleted() || getCanonicalDecl()->isDefaulted()); @@ -1655,21 +1733,22 @@ public: method_iterator end_overridden_methods() const; unsigned size_overridden_methods() const; - /// getParent - Returns the parent of this method declaration, which + /// 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 + /// 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. + /// \brief Returns the type of the \c this pointer. + /// + /// Should only be called for instance (i.e., non-static) methods. QualType getThisType(ASTContext &C) const; unsigned getTypeQualifiers() const { @@ -1702,11 +1781,11 @@ public: /// or clone the function call operator. bool isLambdaStaticInvoker() const; - /// \brief Find the method in RD that corresponds to this one. + /// \brief Find the method in \p RD that corresponds to this one. /// - /// Find if RD or one of the classes it inherits from override this method. - /// If so, return it. RD is assumed to be a subclass of the class defining - /// this method (or be the class itself), unless MayBeBase is set to true. + /// Find if \p RD or one of the classes it inherits from override this method. + /// If so, return it. \p RD is assumed to be a subclass of the class defining + /// this method (or be the class itself), unless \p MayBeBase is set to true. CXXMethodDecl * getCorrespondingMethodInClass(const CXXRecordDecl *RD, bool MayBeBase = false); @@ -1725,20 +1804,21 @@ public: } }; -/// CXXCtorInitializer - Represents a C++ base or member -/// initializer, which is part of a constructor initializer that +/// \brief Represents a C++ base or member initializer. +/// +/// This is part of a constructor initializer that /// initializes one non-static member variable or one base class. For /// example, in the following, both 'A(a)' and 'f(3.14159)' are member /// initializers: /// -/// @code +/// \code /// class A { }; /// class B : public A { /// float f; /// public: /// B(A& a) : A(a), f(3.14159) { } /// }; -/// @endcode +/// \endcode class CXXCtorInitializer { /// \brief Either the base class name/delegating constructor type (stored as /// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field @@ -1747,7 +1827,9 @@ class CXXCtorInitializer { 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 + /// 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; @@ -1756,29 +1838,28 @@ class CXXCtorInitializer { /// end up constructing an object (when multiple arguments are involved). Stmt *Init; - /// LParenLoc - Location of the left paren of the ctor-initializer. + /// \brief Location of the left paren of the ctor-initializer. SourceLocation LParenLoc; - /// RParenLoc - Location of the right paren of the ctor-initializer. + /// \brief Location of the right paren of the ctor-initializer. SourceLocation RParenLoc; /// \brief If the initializee is a type, whether that type makes this /// a delegating initialization. bool IsDelegating : 1; - /// IsVirtual - If the initializer is a base initializer, this keeps track + /// \brief 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 + /// \brief 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. + /// If IsWritten is true, then this number keeps track of the textual order + /// of this initializer in the original sources, counting from 0; otherwise, + /// it stores the number of array index variables stored after this object + /// in memory. unsigned SourceOrderOrNumArrayIndices : 13; CXXCtorInitializer(ASTContext &Context, FieldDecl *Member, @@ -1786,25 +1867,25 @@ class CXXCtorInitializer { SourceLocation R, VarDecl **Indices, unsigned NumIndices); public: - /// CXXCtorInitializer - Creates a new base-class initializer. + /// \brief 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. + /// \brief 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. + /// \brief 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. + /// \brief Creates a new delegating initializer. explicit CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, SourceLocation L, Expr *Init, SourceLocation R); @@ -1816,14 +1897,13 @@ public: Expr *Init, SourceLocation R, VarDecl **Indices, unsigned NumIndices); - /// isBaseInitializer - Returns true when this initializer is - /// initializing a base class. + /// \brief Determine whether 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. + /// \brief Determine whether this initializer is initializing a non-static + /// data member. bool isMemberInitializer() const { return Initializee.is(); } bool isAnyMemberInitializer() const { @@ -1834,15 +1914,18 @@ public: 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. + /// \brief Determine whether this initializer is an implicit initializer + /// generated for a field with an initializer defined on the member + /// declaration. + /// + /// In-class member initializers (also known as "non-static data member + /// initializations", NSDMIs) were introduced in C++11. bool isInClassMemberInitializer() const { return isa(Init); } - /// isDelegatingInitializer - Returns true when this initializer is creating - /// a delegating constructor. + /// \brief Determine whether this initializer is creating a delegating + /// constructor. bool isDelegatingInitializer() const { return Initializee.is() && IsDelegating; } @@ -1864,7 +1947,7 @@ public: TypeLoc getBaseClassLoc() const; /// If this is a base class initializer, returns the type of the base class. - /// Otherwise, returns NULL. + /// Otherwise, returns null. const Type *getBaseClass() const; /// Returns whether the base is virtual or not. @@ -1880,9 +1963,8 @@ public: 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. + /// \brief If this is a member initializer, returns the declaration of the + /// non-static data member being initialized. Otherwise, returns null. FieldDecl *getMember() const { if (isMemberInitializer()) return Initializee.get(); @@ -1912,7 +1994,7 @@ public: /// \brief Determine the source range covering the entire initializer. SourceRange getSourceRange() const LLVM_READONLY; - /// isWritten - Returns true if this initializer is explicitly written + /// \brief Determine whether this initializer is explicitly written /// in the source code. bool isWritten() const { return IsWritten; } @@ -1922,9 +2004,13 @@ public: 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. + /// \brief Set the source order of this initializer. + /// + /// This can only be called once for each initializer; it cannot be called + /// on an initializer having a positive number of (implicit) array indices. + /// + /// This assumes that the initialzier was written in the source code, and + /// ensures that isWritten() returns true. void setSourceOrder(int pos) { assert(!IsWritten && "calling twice setSourceOrder() on the same initializer"); @@ -1969,34 +2055,28 @@ public: Expr *getInit() const { return static_cast(Init); } }; -/// CXXConstructorDecl - Represents a C++ constructor within a -/// class. For example: +/// \brief Represents a C++ constructor within a class. /// -/// @code +/// For example: +/// +/// \code /// class X { /// public: /// explicit X(int); // represented by a CXXConstructorDecl. /// }; -/// @endcode +/// \endcode class CXXConstructorDecl : public CXXMethodDecl { virtual void anchor(); - /// IsExplicitSpecified - Whether this constructor declaration has the - /// 'explicit' keyword specified. + /// \brief Whether this constructor declaration has the \c 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. + /// \name Support for base and member initializers. + /// \{ + /// \brief The arguments used to initialize the base or member. CXXCtorInitializer **CtorInitializers; unsigned NumCtorInitializers; + /// \} CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, @@ -2005,8 +2085,8 @@ class CXXConstructorDecl : public CXXMethodDecl { bool isImplicitlyDeclared, bool isConstexpr) : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, isConstexpr, SourceLocation()), - IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false), - CtorInitializers(0), NumCtorInitializers(0) { + IsExplicitSpecified(isExplicitSpecified), CtorInitializers(0), + NumCtorInitializers(0) { setImplicit(isImplicitlyDeclared); } @@ -2020,52 +2100,31 @@ public: bool isInline, bool isImplicitlyDeclared, bool isConstexpr); - /// isExplicitSpecified - Whether this constructor declaration has the - /// 'explicit' keyword specified. + /// \brief Determine whether this constructor declaration has the + /// \c explicit keyword specified. bool isExplicitSpecified() const { return IsExplicitSpecified; } - /// isExplicit - Whether this constructor was marked "explicit" or not. + /// \brief Determine 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; + return cast(getFirstDecl())->isExplicitSpecified(); } - /// init_iterator - Iterates through the member/base initializer list. + /// \brief Iterates through the member/base initializer list. typedef CXXCtorInitializer **init_iterator; - /// init_const_iterator - Iterates through the memberbase initializer list. + /// \brief Iterates through the member/base initializer list. typedef CXXCtorInitializer * const * init_const_iterator; - /// init_begin() - Retrieve an iterator to the first initializer. + /// \brief Retrieve an iterator to the first initializer. init_iterator init_begin() { return CtorInitializers; } - /// begin() - Retrieve an iterator to the first initializer. + /// \brief Retrieve an iterator to the first initializer. init_const_iterator init_begin() const { return CtorInitializers; } - /// init_end() - Retrieve an iterator past the last initializer. + /// \brief Retrieve an iterator past the last initializer. init_iterator init_end() { return CtorInitializers + NumCtorInitializers; } - /// end() - Retrieve an iterator past the last initializer. + /// \brief Retrieve an iterator past the last initializer. init_const_iterator init_end() const { return CtorInitializers + NumCtorInitializers; } @@ -2088,8 +2147,8 @@ public: return init_const_reverse_iterator(init_begin()); } - /// getNumArgs - Determine the number of arguments used to - /// initialize the member or base. + /// \brief Determine the number of arguments used to initialize the member + /// or base. unsigned getNumCtorInitializers() const { return NumCtorInitializers; } @@ -2102,37 +2161,36 @@ public: CtorInitializers = initializers; } - /// isDelegatingConstructor - Whether this constructor is a - /// delegating constructor + /// \brief Determine 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 + /// \brief When this constructor delegates to another, retrieve the target. CXXConstructorDecl *getTargetConstructor() const; - /// isDefaultConstructor - Whether this constructor is a default + /// 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 + /// \brief Whether this constructor is a copy constructor (C++ [class.copy]p2, + /// which can be used to copy the class. + /// + /// \p TypeQuals will be set to the qualifiers on the + /// argument type. For example, \p TypeQuals would be set to \c /// Qualifiers::Const for the following copy constructor: /// - /// @code + /// \code /// class X { /// public: /// X(const X&); /// }; - /// @endcode + /// \endcode bool isCopyConstructor(unsigned &TypeQuals) const; - /// isCopyConstructor - Whether this constructor is a copy + /// Whether this constructor is a copy /// constructor (C++ [class.copy]p2, which can be used to copy the /// class. bool isCopyConstructor() const { @@ -2166,7 +2224,7 @@ public: return isCopyOrMoveConstructor(Quals); } - /// isConvertingConstructor - Whether this constructor is a + /// Whether this constructor is a /// converting constructor (C++ [class.conv.ctor]), which can be /// used for user-defined conversions. bool isConvertingConstructor(bool AllowExplicit) const; @@ -2197,24 +2255,18 @@ public: friend class ASTDeclWriter; }; -/// CXXDestructorDecl - Represents a C++ destructor within a -/// class. For example: +/// \brief Represents a C++ destructor within a class. /// -/// @code +/// For example: +/// +/// \code /// class X { /// public: /// ~X(); // represented by a CXXDestructorDecl. /// }; -/// @endcode +/// \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; @@ -2224,7 +2276,7 @@ class CXXDestructorDecl : public CXXMethodDecl { bool isInline, bool isImplicitlyDeclared) : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, /*isConstexpr=*/false, SourceLocation()), - ImplicitlyDefined(false), OperatorDelete(0) { + OperatorDelete(0) { setImplicit(isImplicitlyDeclared); } @@ -2237,26 +2289,6 @@ public: 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; } @@ -2268,19 +2300,20 @@ public: friend class ASTDeclWriter; }; -/// CXXConversionDecl - Represents a C++ conversion function within a -/// class. For example: +/// \brief Represents a C++ conversion function within a class. +/// +/// For example: /// -/// @code +/// \code /// class X { /// public: /// operator bool(); /// }; -/// @endcode +/// \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 + /// 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; @@ -2303,21 +2336,20 @@ public: 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. + /// Whether this conversion function declaration is marked + /// "explicit", meaning that it can only be used for direct initialization + /// (including explitly written casts). This is a C++11 feature. bool isExplicitSpecified() const { return IsExplicitSpecified; } - /// 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. + /// \brief Whether this is an explicit conversion operator (C++11 and later). + /// + /// Explicit conversion operators are only considered for direct + /// initialization, e.g., when the user has explicitly written a cast. bool isExplicit() const { - return cast(getFirstDeclaration()) - ->isExplicitSpecified(); + return cast(getFirstDecl())->isExplicitSpecified(); } - /// getConversionType - Returns the type that this conversion - /// function is converting to. + /// \brief Returns the type that this conversion function is converting to. QualType getConversionType() const { return getType()->getAs()->getResultType(); } @@ -2334,32 +2366,37 @@ public: friend class ASTDeclWriter; }; -/// LinkageSpecDecl - This represents a linkage specification. For example: -/// extern "C" void foo(); +/// \brief Represents a linkage specification. /// +/// For example: +/// \code +/// extern "C" void foo(); +/// \endcode 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 + /// \brief Represents the language in a linkage specification. + /// + /// The values are part of the serialization ABI for + /// ASTs and cannot be changed without altering that ABI. To help + /// ensure a stable ABI for this, we choose the DW_LANG_ encodings /// from the dwarf standard. enum LanguageIDs { lang_c = /* DW_LANG_C */ 0x0002, lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 }; private: - /// Language - The language for this linkage specification. + /// \brief The language for this linkage specification. unsigned Language : 3; - /// True if this linkage spec has brances. This is needed so that hasBraces() - /// returns the correct result while the linkage spec body is being parsed. - /// Once RBraceLoc has been set this is not used, so it doesn't need to be - /// serialized. + /// \brief True if this linkage spec has braces. + /// + /// This is needed so that hasBraces() returns the correct result while the + /// linkage spec body is being parsed. Once RBraceLoc has been set this is + /// not used, so it doesn't need to be serialized. unsigned HasBraces : 1; - /// ExternLoc - The source location for the extern keyword. + /// \brief The source location for the extern keyword. SourceLocation ExternLoc; - /// RBraceLoc - The source location for the right brace (if valid). + /// \brief The source location for the right brace (if valid). SourceLocation RBraceLoc; LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc, @@ -2417,34 +2454,38 @@ public: } }; -/// UsingDirectiveDecl - Represents C++ using-directive. For example: +/// \brief Represents C++ using-directive. /// +/// For example: +/// \code /// using namespace std; +/// \endcode /// -// NB: UsingDirectiveDecl should be Decl not NamedDecl, but we provide -// artificial names for all using-directives in order to store -// them in DeclContext effectively. +/// \note UsingDirectiveDecl should be Decl not NamedDecl, but we provide +/// artificial names for all using-directives in order to store +/// them in DeclContext effectively. class UsingDirectiveDecl : public NamedDecl { virtual void anchor(); - /// \brief The location of the "using" keyword. + /// \brief The location of the \c using keyword. SourceLocation UsingLoc; - /// SourceLocation - Location of 'namespace' token. + /// \brief The location of the \c namespace keyword. SourceLocation NamespaceLoc; /// \brief The nested-name-specifier that precedes the namespace. NestedNameSpecifierLoc QualifierLoc; - /// NominatedNamespace - Namespace nominated by using-directive. + /// \brief The namespace nominated by this 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. + /// \brief Returns special DeclarationName used by using-directives. + /// + /// This is only used by DeclContext for storing UsingDirectiveDecls in + /// its lookup structure. static DeclarationName getName() { return DeclarationName::getUsingDirectiveName(); } @@ -2475,7 +2516,7 @@ public: return NominatedNamespace; } - /// getNominatedNamespace - Returns namespace nominated by using-directive. + /// \brief Returns the namespace nominated by this using-directive. NamespaceDecl *getNominatedNamespace(); const NamespaceDecl *getNominatedNamespace() const { @@ -2487,14 +2528,14 @@ public: DeclContext *getCommonAncestor() { return CommonAncestor; } const DeclContext *getCommonAncestor() const { return CommonAncestor; } - /// \brief Return the location of the "using" keyword. + /// \brief Return the location of the \c using keyword. SourceLocation getUsingLoc() const { return UsingLoc; } // FIXME: Could omit 'Key' in name. - /// getNamespaceKeyLocation - Returns location of namespace keyword. + /// \brief Returns the location of the \c namespace keyword. SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; } - /// getIdentLocation - Returns location of identifier. + /// \brief Returns the location of this using declaration's identifier. SourceLocation getIdentLocation() const { return getLocation(); } static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC, @@ -2523,23 +2564,25 @@ public: /// /// For example: /// -/// @code +/// \code /// namespace Foo = Bar; -/// @endcode +/// \endcode class NamespaceAliasDecl : public NamedDecl { virtual void anchor(); - /// \brief The location of the "namespace" keyword. + /// \brief The location of the \c namespace keyword. SourceLocation NamespaceLoc; - /// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc. + /// \brief The location of the namespace's identifier. + /// + /// This is accessed by TargetNameLoc. SourceLocation IdentLoc; /// \brief The nested-name-specifier that precedes the namespace. NestedNameSpecifierLoc QualifierLoc; - /// Namespace - The Decl that this alias points to. Can either be a - /// NamespaceDecl or a NamespaceAliasDecl. + /// \brief The Decl that this alias points to, either a NamespaceDecl or + /// a NamespaceAliasDecl. NamedDecl *Namespace; NamespaceAliasDecl(DeclContext *DC, SourceLocation NamespaceLoc, @@ -2579,7 +2622,7 @@ public: /// "namespace foo = ns::bar;". SourceLocation getAliasLoc() const { return getLocation(); } - /// Returns the location of the 'namespace' keyword. + /// Returns the location of the \c namespace keyword. SourceLocation getNamespaceLoc() const { return NamespaceLoc; } /// Returns the location of the identifier in the named namespace. @@ -2611,7 +2654,7 @@ public: /// (resolved) using declaration. /// /// For example, -/// @code +/// \code /// namespace A { /// void foo(); /// } @@ -2619,8 +2662,8 @@ public: /// using A::foo; // <- a UsingDecl /// // Also creates a UsingShadowDecl for A::foo() in B /// } -/// @endcode -class UsingShadowDecl : public NamedDecl { +/// \endcode +class UsingShadowDecl : public NamedDecl, public Redeclarable { virtual void anchor(); /// The referenced declaration. @@ -2643,6 +2686,17 @@ class UsingShadowDecl : public NamedDecl { setImplicit(); } + typedef Redeclarable redeclarable_base; + virtual UsingShadowDecl *getNextRedeclaration() { + return RedeclLink.getNext(); + } + virtual UsingShadowDecl *getPreviousDeclImpl() { + return getPreviousDecl(); + } + virtual UsingShadowDecl *getMostRecentDeclImpl() { + return getMostRecentDecl(); + } + public: static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, UsingDecl *Using, @@ -2651,7 +2705,20 @@ public: } static UsingShadowDecl *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; + + virtual UsingShadowDecl *getCanonicalDecl() { + return getFirstDecl(); + } + virtual const UsingShadowDecl *getCanonicalDecl() const { + return getFirstDecl(); + } + /// \brief Gets the underlying declaration which has been brought into the /// local scope. NamedDecl *getTargetDecl() const { return Underlying; } @@ -2683,20 +2750,20 @@ public: /// \brief Represents a C++ using-declaration. /// /// For example: -/// @code +/// \code /// using someNameSpace::someIdentifier; -/// @endcode +/// \endcode class UsingDecl : public NamedDecl { virtual void anchor(); - /// \brief The source location of the "using" location itself. + /// \brief The source location of the 'using' keyword 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. + /// \brief Provides source/type location info for the declaration name + /// embedded in the ValueDecl base class. DeclarationNameLoc DNLoc; /// \brief The first shadow declaration of the shadow decl chain associated @@ -2708,18 +2775,18 @@ class UsingDecl : public NamedDecl { UsingDecl(DeclContext *DC, SourceLocation UL, NestedNameSpecifierLoc QualifierLoc, - const DeclarationNameInfo &NameInfo, bool IsTypeNameArg) + const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword) : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()), UsingLocation(UL), QualifierLoc(QualifierLoc), - DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, IsTypeNameArg) { + DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, HasTypenameKeyword) { } public: - /// \brief Returns the source location of the "using" keyword. - SourceLocation getUsingLocation() const { return UsingLocation; } + /// \brief Return the source location of the 'using' keyword. + SourceLocation getUsingLoc() const { return UsingLocation; } /// \brief Set the source location of the 'using' keyword. - void setUsingLocation(SourceLocation L) { UsingLocation = L; } + void setUsingLoc(SourceLocation L) { UsingLocation = L; } /// \brief Retrieve the nested-name-specifier that qualifies the name, /// with source-location information. @@ -2734,13 +2801,16 @@ public: return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); } + /// \brief Return true if it is a C++03 access declaration (no 'using'). + bool isAccessDeclaration() const { return UsingLocation.isInvalid(); } + /// \brief Return true if the using declaration has 'typename'. - bool isTypeName() const { return FirstUsingShadow.getInt(); } + bool hasTypename() const { return FirstUsingShadow.getInt(); } /// \brief Sets whether the using declaration has 'typename'. - void setTypeName(bool TN) { FirstUsingShadow.setInt(TN); } + void setTypename(bool TN) { FirstUsingShadow.setInt(TN); } - /// \brief Iterates through the using shadow declarations assosiated with + /// \brief Iterates through the using shadow declarations associated with /// this using declaration. class shadow_iterator { /// \brief The current using shadow declaration. @@ -2796,13 +2866,11 @@ public: SourceLocation UsingL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, - bool IsTypeNameArg); + bool HasTypenameKeyword); static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(UsingLocation, getNameInfo().getEndLoc()); - } + + SourceRange getSourceRange() const LLVM_READONLY; static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Using; } @@ -2817,11 +2885,11 @@ public: /// Unlike non-dependent using declarations, these *only* bring through /// non-types; otherwise they would break two-phase lookup. /// -/// @code +/// \code /// template \ class A : public Base { /// using Base::foo; /// }; -/// @endcode +/// \endcode class UnresolvedUsingValueDecl : public ValueDecl { virtual void anchor(); @@ -2831,8 +2899,8 @@ class UnresolvedUsingValueDecl : public ValueDecl { /// \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. + /// \brief Provides source/type location info for the declaration name + /// embedded in the ValueDecl base class. DeclarationNameLoc DNLoc; UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty, @@ -2852,6 +2920,9 @@ public: /// \brief Set the source location of the 'using' keyword. void setUsingLoc(SourceLocation L) { UsingLocation = L; } + /// \brief Return true if it is a C++03 access declaration (no 'using'). + bool isAccessDeclaration() const { return UsingLocation.isInvalid(); } + /// \brief Retrieve the nested-name-specifier that qualifies the name, /// with source-location information. NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } @@ -2873,9 +2944,7 @@ public: static UnresolvedUsingValueDecl * CreateDeserialized(ASTContext &C, unsigned ID); - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(UsingLocation, getNameInfo().getEndLoc()); - } + SourceRange getSourceRange() const LLVM_READONLY; static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == UnresolvedUsingValue; } @@ -2884,23 +2953,20 @@ public: friend class ASTDeclWriter; }; -/// @brief Represents a dependent using declaration which was marked with +/// \brief Represents a dependent using declaration which was marked with /// \c typename. /// -/// @code +/// \code /// template \ class A : public Base { /// using typename Base::foo; /// }; -/// @endcode +/// \endcode /// /// The type associated with an 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; diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h b/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h index 84f3698..9c626c8 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h @@ -18,6 +18,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclarationName.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" #include @@ -26,23 +27,29 @@ namespace clang { class DependentDiagnostic; -/// StoredDeclsList - This is an array of decls optimized a common case of only -/// containing one entry. +/// \brief An array of decls optimized for the common case of only containing +/// one entry. struct StoredDeclsList { - /// DeclsTy - When in vector form, this is what the Data pointer points to. + /// \brief When in vector form, this is what the Data pointer points to. typedef SmallVector DeclsTy; + /// \brief A collection of declarations, with a flag to indicate if we have + /// further external declarations. + typedef llvm::PointerIntPair DeclsAndHasExternalTy; + /// \brief The stored data, which will be either a pointer to a NamedDecl, - /// or a pointer to a vector. - llvm::PointerUnion Data; + /// or a pointer to a vector with a flag to indicate if there are further + /// external declarations. + llvm::PointerUnion Data; public: StoredDeclsList() {} StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) { if (DeclsTy *RHSVec = RHS.getAsVector()) - Data = new DeclsTy(*RHSVec); + Data = DeclsAndHasExternalTy(new DeclsTy(*RHSVec), + RHS.hasExternalDecls()); } ~StoredDeclsList() { @@ -56,7 +63,7 @@ public: delete Vector; Data = RHS.Data; if (DeclsTy *RHSVec = RHS.getAsVector()) - Data = new DeclsTy(*RHSVec); + Data = DeclsAndHasExternalTy(new DeclsTy(*RHSVec), hasExternalDecls()); return *this; } @@ -66,8 +73,27 @@ public: return Data.dyn_cast(); } + DeclsAndHasExternalTy getAsVectorAndHasExternal() const { + return Data.dyn_cast(); + } + DeclsTy *getAsVector() const { - return Data.dyn_cast(); + return getAsVectorAndHasExternal().getPointer(); + } + + bool hasExternalDecls() const { + return getAsVectorAndHasExternal().getInt(); + } + + void setHasExternalDecls() { + if (DeclsTy *Vec = getAsVector()) + Data = DeclsAndHasExternalTy(Vec, true); + else { + DeclsTy *VT = new DeclsTy(); + if (NamedDecl *OldD = getAsDecl()) + VT->push_back(OldD); + Data = DeclsAndHasExternalTy(VT, true); + } } void setOnlyValue(NamedDecl *ND) { @@ -110,6 +136,8 @@ public: Vec.erase(std::remove_if(Vec.begin(), Vec.end(), std::mem_fun(&Decl::isFromASTFile)), Vec.end()); + // Don't have any external decls any more. + Data = DeclsAndHasExternalTy(&Vec, false); } } @@ -165,12 +193,14 @@ public: /// not a redeclaration to merge it into the appropriate place in our list. /// void AddSubsequentDecl(NamedDecl *D) { + assert(!isNull() && "don't AddSubsequentDecl when we have no decls"); + // If this is the second decl added to the list, convert this to vector // form. if (NamedDecl *OldD = getAsDecl()) { DeclsTy *VT = new DeclsTy(); VT->push_back(OldD); - Data = VT; + Data = DeclsAndHasExternalTy(VT, false); } DeclsTy &Vec = *getAsVector(); diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h b/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h index 3a12878..be6f2eb 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h @@ -220,7 +220,7 @@ public: }; inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const { - return friend_iterator(data().FirstFriend); + return friend_iterator(getFirstFriend()); } inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const { @@ -228,7 +228,7 @@ inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const { } inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) { - assert(FD->NextFriend == 0 && "friend already has next friend?"); + assert(!FD->NextFriend && "friend already has next friend?"); FD->NextFriend = data().FirstFriend; data().FirstFriend = FD; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclLookups.h b/contrib/llvm/tools/clang/include/clang/AST/DeclLookups.h index 4477c25..c16975a 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclLookups.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclLookups.h @@ -37,6 +37,8 @@ public: StoredDeclsMap::iterator End) : It(It), End(End) {} + DeclarationName getLookupName() const { return It->first; } + reference operator*() const { return It->second.getLookupResult(); } pointer operator->() const { return It->second.getLookupResult(); } @@ -66,7 +68,7 @@ public: } }; -DeclContext::all_lookups_iterator DeclContext::lookups_begin() const { +inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const { DeclContext *Primary = const_cast(this)->getPrimaryContext(); if (Primary->hasExternalVisibleStorage()) getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary); @@ -75,7 +77,7 @@ DeclContext::all_lookups_iterator DeclContext::lookups_begin() const { return all_lookups_iterator(); } -DeclContext::all_lookups_iterator DeclContext::lookups_end() const { +inline DeclContext::all_lookups_iterator DeclContext::lookups_end() const { DeclContext *Primary = const_cast(this)->getPrimaryContext(); if (Primary->hasExternalVisibleStorage()) getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary); @@ -84,6 +86,22 @@ DeclContext::all_lookups_iterator DeclContext::lookups_end() const { return all_lookups_iterator(); } +inline +DeclContext::all_lookups_iterator DeclContext::noload_lookups_begin() const { + DeclContext *Primary = const_cast(this)->getPrimaryContext(); + if (StoredDeclsMap *Map = Primary->getLookupPtr()) + return all_lookups_iterator(Map->begin(), Map->end()); + return all_lookups_iterator(); +} + +inline +DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const { + DeclContext *Primary = const_cast(this)->getPrimaryContext(); + if (StoredDeclsMap *Map = Primary->getLookupPtr()) + return all_lookups_iterator(Map->end(), Map->end()); + return all_lookups_iterator(); +} + } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h b/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h index 40de013..2e760d6 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h @@ -452,7 +452,7 @@ public: } /// \brief Determine whether this method has a body. - virtual bool hasBody() const { return Body; } + virtual bool hasBody() const { return Body.isValid(); } /// \brief Retrieve the body of this method, if it has one. virtual Stmt *getBody() const; @@ -463,7 +463,7 @@ public: void setBody(Stmt *B) { Body = B; } /// \brief Returns whether this specific method is a definition. - bool isThisDeclarationADefinition() const { return Body; } + bool isThisDeclarationADefinition() const { return hasBody(); } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -553,6 +553,9 @@ public: typedef llvm::DenseMap PropertyMap; + typedef llvm::DenseMap + ProtocolPropertyMap; + typedef llvm::SmallVector PropertyDeclOrder; /// This routine collects list of properties to be implemented in the class. @@ -1133,6 +1136,8 @@ public: return lookupInstanceVariable(IVarName, ClassDeclared); } + ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name); + // Lookup a method. First, we search locally. If a method isn't // found, we search referenced protocols and class categories. ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, @@ -1196,14 +1201,11 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; /// Retrieves the canonical declaration of this Objective-C class. - ObjCInterfaceDecl *getCanonicalDecl() { - return getFirstDeclaration(); - } - const ObjCInterfaceDecl *getCanonicalDecl() const { - return getFirstDeclaration(); - } + ObjCInterfaceDecl *getCanonicalDecl() { return getFirstDecl(); } + const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); } // Low-level accessor const Type *getTypeForDecl() const { return TypeForDecl; } @@ -1244,10 +1246,12 @@ private: ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW, - bool synthesized) + bool synthesized, + bool backingIvarReferencedInAccessor) : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit), - NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {} + NextIvar(0), DeclAccess(ac), Synthesized(synthesized), + BackingIvarReferencedInAccessor(backingIvarReferencedInAccessor) {} public: static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC, @@ -1255,7 +1259,8 @@ public: IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW = NULL, - bool synthesized=false); + bool synthesized=false, + bool backingIvarReferencedInAccessor=false); static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1277,6 +1282,13 @@ public: return DeclAccess == None ? Protected : AccessControl(DeclAccess); } + void setBackingIvarReferencedInAccessor(bool val) { + BackingIvarReferencedInAccessor = val; + } + bool getBackingIvarReferencedInAccessor() const { + return BackingIvarReferencedInAccessor; + } + void setSynthesize(bool synth) { Synthesized = synth; } bool getSynthesize() const { return Synthesized; } @@ -1291,6 +1303,7 @@ private: // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum unsigned DeclAccess : 3; unsigned Synthesized : 1; + unsigned BackingIvarReferencedInAccessor : 1; }; @@ -1502,17 +1515,17 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; /// Retrieves the canonical declaration of this Objective-C protocol. - ObjCProtocolDecl *getCanonicalDecl() { - return getFirstDeclaration(); - } - const ObjCProtocolDecl *getCanonicalDecl() const { - return getFirstDeclaration(); - } + ObjCProtocolDecl *getCanonicalDecl() { return getFirstDecl(); } + const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); } virtual void collectPropertiesToImplement(PropertyMap &PM, PropertyDeclOrder &PO) const; + +void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property, + ProtocolPropertyMap &PM) const; static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCProtocol; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclOpenMP.h b/contrib/llvm/tools/clang/include/clang/AST/DeclOpenMP.h index ca92040..42fe907 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclOpenMP.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclOpenMP.h @@ -1,4 +1,4 @@ -//===--- OpenMP.h - Classes for representing OpenMP directives ---*- C++ -*-===// +//===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief This file defines OpenMP nodes. +/// \brief This file defines OpenMP nodes for declarative directives. /// //===----------------------------------------------------------------------===// @@ -20,8 +20,6 @@ namespace clang { -class DeclRefExpr; - /// \brief This represents '#pragma omp threadprivate ...' directive. /// For example, in the following, both 'a' and 'A::b' are threadprivate: /// @@ -43,29 +41,29 @@ class OMPThreadPrivateDecl : public Decl { OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) : Decl(DK, DC, L), NumVars(0) { } - ArrayRef getVars() const { - return ArrayRef( - reinterpret_cast(this + 1), + ArrayRef getVars() const { + return ArrayRef( + reinterpret_cast(this + 1), NumVars); } - llvm::MutableArrayRef getVars() { - return llvm::MutableArrayRef( - reinterpret_cast(this + 1), + llvm::MutableArrayRef getVars() { + return llvm::MutableArrayRef( + reinterpret_cast(this + 1), NumVars); } - void setVars(ArrayRef VL); + void setVars(ArrayRef VL); public: static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - ArrayRef VL); + ArrayRef VL); static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C, unsigned ID, unsigned N); - typedef llvm::MutableArrayRef::iterator varlist_iterator; - typedef ArrayRef::iterator varlist_const_iterator; + typedef llvm::MutableArrayRef::iterator varlist_iterator; + typedef ArrayRef::iterator varlist_const_iterator; unsigned varlist_size() const { return NumVars; } bool varlist_empty() const { return NumVars == 0; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h b/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h index 425a617..24bd28a 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h @@ -34,6 +34,8 @@ class TemplateTypeParmDecl; class NonTypeTemplateParmDecl; class TemplateTemplateParmDecl; class TypeAliasTemplateDecl; +class VarTemplateDecl; +class VarTemplatePartialSpecializationDecl; /// \brief Stores a template parameter of any kind. typedef llvm::PointerUnion3 friend class RedeclarableTemplate; /// \brief Retrieves the canonical declaration of this template. - RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDeclaration(); } - const RedeclarableTemplateDecl *getCanonicalDecl() const { - return getFirstDeclaration(); + RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDecl(); } + const RedeclarableTemplateDecl *getCanonicalDecl() const { + return getFirstDecl(); } /// \brief Determines whether this template was a specialization of a @@ -713,6 +715,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -743,7 +746,7 @@ protected: /// \brief Data that is common to all of the declarations of a given /// function template. struct Common : CommonBase { - Common() : InjectedArgs(0) { } + Common() : InjectedArgs(), LazySpecializations() { } /// \brief The function template specializations for this function /// template, including explicit specializations and instantiations. @@ -757,6 +760,13 @@ protected: /// template, and is allocated lazily, since most function templates do not /// require the use of this information. TemplateArgument *InjectedArgs; + + /// \brief If non-null, points to an array of specializations known only + /// by their external declaration IDs. + /// + /// The first value in the array is the number of of specializations + /// that follow. + uint32_t *LazySpecializations; }; FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, @@ -771,12 +781,13 @@ protected: friend class FunctionDecl; + /// \brief Load any lazily-loaded specializations from the external source. + void LoadLazySpecializations() const; + /// \brief Retrieve the set of function template specializations of this /// function template. llvm::FoldingSetVector & - getSpecializations() const { - return getCommonPtr()->Specializations; - } + getSpecializations() const; /// \brief Add a specialization of this function template. /// @@ -815,14 +826,14 @@ public: /// NULL if no such declaration exists. FunctionTemplateDecl *getPreviousDecl() { return cast_or_null( - RedeclarableTemplateDecl::getPreviousDecl()); + static_cast(this)->getPreviousDecl()); } /// \brief Retrieve the previous declaration of this function template, or /// NULL if no such declaration exists. const FunctionTemplateDecl *getPreviousDecl() const { return cast_or_null( - RedeclarableTemplateDecl::getPreviousDecl()); + static_cast(this)->getPreviousDecl()); } FunctionTemplateDecl *getInstantiatedFromMemberTemplate() { @@ -847,7 +858,7 @@ public: /// 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(); + ArrayRef getInjectedTemplateArgs(); /// \brief Create a function template node. static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC, @@ -1377,7 +1388,7 @@ class ClassTemplateSpecializationDecl /// \brief The template argument list deduced for the class template /// partial specialization itself. - TemplateArgumentList *TemplateArgs; + const TemplateArgumentList *TemplateArgs; }; /// \brief The template that this specialization specializes @@ -1402,7 +1413,7 @@ class ClassTemplateSpecializationDecl ExplicitSpecializationInfo *ExplicitInfo; /// \brief The template arguments used to describe this specialization. - TemplateArgumentList *TemplateArgs; + const TemplateArgumentList *TemplateArgs; /// \brief The point where this template was instantiated (if any) SourceLocation PointOfInstantiation; @@ -1438,9 +1449,9 @@ public: bool Qualified) const; ClassTemplateSpecializationDecl *getMostRecentDecl() { - CXXRecordDecl *Recent - = cast(CXXRecordDecl::getMostRecentDecl()); - if (!isa(Recent)) { + CXXRecordDecl *Recent = static_cast( + this)->getMostRecentDecl(); + while (!isa(Recent)) { // FIXME: Does injected class name need to be in the redeclarations chain? assert(Recent->isInjectedClassName() && Recent->getPreviousDecl()); Recent = Recent->getPreviousDecl(); @@ -1553,7 +1564,7 @@ public: /// instantiation of the given class template partial specialization whose /// template arguments have been deduced. void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec, - TemplateArgumentList *TemplateArgs) { + const TemplateArgumentList *TemplateArgs) { assert(!SpecializedTemplate.is() && "Already set to a class template partial specialization!"); SpecializedPartialSpecialization *PS @@ -1639,13 +1650,7 @@ class ClassTemplatePartialSpecializationDecl /// \brief The source info for the template arguments as written. /// FIXME: redundant with TypeAsWritten? - TemplateArgumentLoc *ArgsAsWritten; - unsigned NumArgsAsWritten; - - /// \brief Sequence number indicating when this class template partial - /// specialization was added to the set of partial specializations for - /// its owning class template. - unsigned SequenceNumber; + const ASTTemplateArgumentListInfo *ArgsAsWritten; /// \brief The class template partial specialization from which this /// class template partial specialization was instantiated. @@ -1663,16 +1668,12 @@ class ClassTemplatePartialSpecializationDecl ClassTemplateDecl *SpecializedTemplate, const TemplateArgument *Args, unsigned NumArgs, - TemplateArgumentLoc *ArgInfos, - unsigned NumArgInfos, - ClassTemplatePartialSpecializationDecl *PrevDecl, - unsigned SequenceNumber); + const ASTTemplateArgumentListInfo *ArgsAsWritten, + ClassTemplatePartialSpecializationDecl *PrevDecl); ClassTemplatePartialSpecializationDecl() : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization), - TemplateParams(0), ArgsAsWritten(0), - NumArgsAsWritten(0), SequenceNumber(0), - InstantiatedFromMember(0, false) { } + TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) { } public: static ClassTemplatePartialSpecializationDecl * @@ -1684,15 +1685,15 @@ public: unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos, QualType CanonInjectedType, - ClassTemplatePartialSpecializationDecl *PrevDecl, - unsigned SequenceNumber); + ClassTemplatePartialSpecializationDecl *PrevDecl); static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID); ClassTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( - ClassTemplateSpecializationDecl::getMostRecentDecl()); + static_cast( + this)->getMostRecentDecl()); } /// Get the list of template parameters @@ -1701,19 +1702,10 @@ public: } /// Get the template arguments as written. - TemplateArgumentLoc *getTemplateArgsAsWritten() const { + const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { return ArgsAsWritten; } - /// Get the number of template arguments as written. - unsigned getNumTemplateArgsAsWritten() const { - return NumArgsAsWritten; - } - - /// \brief Get the sequence number for this class template partial - /// specialization. - unsigned getSequenceNumber() const { return SequenceNumber; } - /// \brief Retrieve the member class template partial specialization from /// which this particular class template partial specialization was /// instantiated. @@ -1735,15 +1727,15 @@ public: /// \c Outer::Inner, this function would return /// \c Outer::Inner. ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() { - ClassTemplatePartialSpecializationDecl *First - = cast(getFirstDeclaration()); + ClassTemplatePartialSpecializationDecl *First = + cast(getFirstDecl()); return First->InstantiatedFromMember.getPointer(); } void setInstantiatedFromMember( ClassTemplatePartialSpecializationDecl *PartialSpec) { - ClassTemplatePartialSpecializationDecl *First - = cast(getFirstDeclaration()); + ClassTemplatePartialSpecializationDecl *First = + cast(getFirstDecl()); First->InstantiatedFromMember.setPointer(PartialSpec); } @@ -1764,15 +1756,15 @@ public: /// struct X::Inner { /* ... */ }; /// \endcode bool isMemberSpecialization() { - ClassTemplatePartialSpecializationDecl *First - = cast(getFirstDeclaration()); + ClassTemplatePartialSpecializationDecl *First = + cast(getFirstDecl()); return First->InstantiatedFromMember.getInt(); } /// \brief Note that this member template is a specialization. void setMemberSpecialization() { - ClassTemplatePartialSpecializationDecl *First - = cast(getFirstDeclaration()); + ClassTemplatePartialSpecializationDecl *First = + cast(getFirstDecl()); assert(First->InstantiatedFromMember.getPointer() && "Only member templates can be member template specializations"); return First->InstantiatedFromMember.setInt(true); @@ -1821,7 +1813,7 @@ protected: QualType InjectedClassNameType; /// \brief If non-null, points to an array of specializations (including - /// partial specializations) known ownly by their external declaration IDs. + /// partial specializations) known only by their external declaration IDs. /// /// The first value in the array is the number of of specializations/ /// partial specializations that follow. @@ -1900,14 +1892,23 @@ public: /// NULL if no such declaration exists. ClassTemplateDecl *getPreviousDecl() { return cast_or_null( - RedeclarableTemplateDecl::getPreviousDecl()); + static_cast(this)->getPreviousDecl()); } /// \brief Retrieve the previous declaration of this class template, or /// NULL if no such declaration exists. const ClassTemplateDecl *getPreviousDecl() const { return cast_or_null( - RedeclarableTemplateDecl::getPreviousDecl()); + static_cast( + this)->getPreviousDecl()); + } + + ClassTemplateDecl *getMostRecentDecl() { + return cast( + static_cast(this)->getMostRecentDecl()); + } + const ClassTemplateDecl *getMostRecentDecl() const { + return const_cast(this)->getMostRecentDecl(); } ClassTemplateDecl *getInstantiatedFromMemberTemplate() { @@ -1926,11 +1927,6 @@ public: void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos); - /// \brief Return the next partial specialization sequence number. - unsigned getNextPartialSpecSequenceNumber() { - return getPartialSpecializations().size(); - } - /// \brief Retrieve the partial specializations as an ordered list. void getPartialSpecializations( SmallVectorImpl &PS); @@ -2139,14 +2135,15 @@ public: /// NULL if no such declaration exists. TypeAliasTemplateDecl *getPreviousDecl() { return cast_or_null( - RedeclarableTemplateDecl::getPreviousDecl()); + static_cast(this)->getPreviousDecl()); } /// \brief Retrieve the previous declaration of this function template, or /// NULL if no such declaration exists. const TypeAliasTemplateDecl *getPreviousDecl() const { return cast_or_null( - RedeclarableTemplateDecl::getPreviousDecl()); + static_cast( + this)->getPreviousDecl()); } TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() { @@ -2239,6 +2236,578 @@ public: inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD) : Function(FTD) { } +/// \brief Represents a variable template specialization, which refers to +/// a variable template with a given set of template arguments. +/// +/// Variable template specializations represent both explicit +/// specializations of variable templates, as in the example below, and +/// implicit instantiations of variable templates. +/// +/// \code +/// template constexpr T pi = T(3.1415926535897932385); +/// +/// template<> +/// constexpr float pi; // variable template specialization pi +/// \endcode +class VarTemplateSpecializationDecl : public VarDecl, + public llvm::FoldingSetNode { + + /// \brief Structure that stores information about a variable template + /// specialization that was instantiated from a variable template partial + /// specialization. + struct SpecializedPartialSpecialization { + /// \brief The variable template partial specialization from which this + /// variable template specialization was instantiated. + VarTemplatePartialSpecializationDecl *PartialSpecialization; + + /// \brief The template argument list deduced for the variable template + /// partial specialization itself. + const TemplateArgumentList *TemplateArgs; + }; + + /// \brief The template that this specialization specializes. + llvm::PointerUnion + SpecializedTemplate; + + /// \brief Further info for explicit template specialization/instantiation. + struct ExplicitSpecializationInfo { + /// \brief The type-as-written. + TypeSourceInfo *TypeAsWritten; + /// \brief The location of the extern keyword. + SourceLocation ExternLoc; + /// \brief The location of the template keyword. + SourceLocation TemplateKeywordLoc; + + ExplicitSpecializationInfo() + : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {} + }; + + /// \brief Further info for explicit template specialization/instantiation. + /// Does not apply to implicit specializations. + ExplicitSpecializationInfo *ExplicitInfo; + + /// \brief The template arguments used to describe this specialization. + const TemplateArgumentList *TemplateArgs; + TemplateArgumentListInfo TemplateArgsInfo; + + /// \brief The point where this template was instantiated (if any). + SourceLocation PointOfInstantiation; + + /// \brief The kind of specialization this declaration refers to. + /// Really a value of type TemplateSpecializationKind. + unsigned SpecializationKind : 3; + +protected: + VarTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + VarTemplateDecl *SpecializedTemplate, + QualType T, TypeSourceInfo *TInfo, + StorageClass S, const TemplateArgument *Args, + unsigned NumArgs); + + explicit VarTemplateSpecializationDecl(Kind DK); + +public: + static VarTemplateSpecializationDecl * + Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, + TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, + unsigned NumArgs); + static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, + unsigned ID); + + virtual void getNameForDiagnostic(raw_ostream &OS, + const PrintingPolicy &Policy, + bool Qualified) const; + + VarTemplateSpecializationDecl *getMostRecentDecl() { + VarDecl *Recent = static_cast(this)->getMostRecentDecl(); + return cast(Recent); + } + + /// \brief Retrieve the template that this specialization specializes. + VarTemplateDecl *getSpecializedTemplate() const; + + /// \brief Retrieve the template arguments of the variable template + /// specialization. + const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; } + + // TODO: Always set this when creating the new specialization? + void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo); + + const TemplateArgumentListInfo &getTemplateArgsInfo() const { + return TemplateArgsInfo; + } + + /// \brief Determine the kind of specialization that this + /// declaration represents. + TemplateSpecializationKind getSpecializationKind() const { + return static_cast(SpecializationKind); + } + + bool isExplicitSpecialization() const { + return getSpecializationKind() == TSK_ExplicitSpecialization; + } + + /// \brief True if this declaration is an explicit specialization, + /// explicit instantiation declaration, or explicit instantiation + /// definition. + bool isExplicitInstantiationOrSpecialization() const { + switch (getTemplateSpecializationKind()) { + case TSK_ExplicitSpecialization: + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + return true; + + case TSK_Undeclared: + case TSK_ImplicitInstantiation: + return false; + } + llvm_unreachable("bad template specialization kind"); + } + + void setSpecializationKind(TemplateSpecializationKind TSK) { + SpecializationKind = TSK; + } + + /// \brief Get the point of instantiation (if any), or null if none. + SourceLocation getPointOfInstantiation() const { + return PointOfInstantiation; + } + + void setPointOfInstantiation(SourceLocation Loc) { + assert(Loc.isValid() && "point of instantiation must be valid!"); + PointOfInstantiation = Loc; + } + + /// \brief If this variable template specialization is an instantiation of + /// a template (rather than an explicit specialization), return the + /// variable template or variable template partial specialization from which + /// it was instantiated. + llvm::PointerUnion + getInstantiatedFrom() const { + if (getSpecializationKind() != TSK_ImplicitInstantiation && + getSpecializationKind() != TSK_ExplicitInstantiationDefinition && + getSpecializationKind() != TSK_ExplicitInstantiationDeclaration) + return llvm::PointerUnion(); + + if (SpecializedPartialSpecialization *PartialSpec = + SpecializedTemplate.dyn_cast()) + return PartialSpec->PartialSpecialization; + + return SpecializedTemplate.get(); + } + + /// \brief Retrieve the variable template or variable template partial + /// specialization which was specialized by this. + llvm::PointerUnion + getSpecializedTemplateOrPartial() const { + if (SpecializedPartialSpecialization *PartialSpec = + SpecializedTemplate.dyn_cast()) + return PartialSpec->PartialSpecialization; + + return SpecializedTemplate.get(); + } + + /// \brief Retrieve the set of template arguments that should be used + /// to instantiate the initializer of the variable template or variable + /// template partial specialization from which this variable template + /// specialization was instantiated. + /// + /// \returns For a variable template specialization instantiated from the + /// primary template, this function will return the same template arguments + /// as getTemplateArgs(). For a variable template specialization instantiated + /// from a variable template partial specialization, this function will the + /// return deduced template arguments for the variable template partial + /// specialization itself. + const TemplateArgumentList &getTemplateInstantiationArgs() const { + if (SpecializedPartialSpecialization *PartialSpec = + SpecializedTemplate.dyn_cast()) + return *PartialSpec->TemplateArgs; + + return getTemplateArgs(); + } + + /// \brief Note that this variable template specialization is actually an + /// instantiation of the given variable template partial specialization whose + /// template arguments have been deduced. + void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec, + const TemplateArgumentList *TemplateArgs) { + assert(!SpecializedTemplate.is() && + "Already set to a variable template partial specialization!"); + SpecializedPartialSpecialization *PS = + new (getASTContext()) SpecializedPartialSpecialization(); + PS->PartialSpecialization = PartialSpec; + PS->TemplateArgs = TemplateArgs; + SpecializedTemplate = PS; + } + + /// \brief Note that this variable template specialization is an instantiation + /// of the given variable template. + void setInstantiationOf(VarTemplateDecl *TemplDecl) { + assert(!SpecializedTemplate.is() && + "Previously set to a variable template partial specialization!"); + SpecializedTemplate = TemplDecl; + } + + /// \brief Sets the type of this specialization as it was written by + /// the user. + void setTypeAsWritten(TypeSourceInfo *T) { + if (!ExplicitInfo) + ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; + ExplicitInfo->TypeAsWritten = T; + } + /// \brief Gets the type of this specialization as it was written by + /// the user, if it was so written. + TypeSourceInfo *getTypeAsWritten() const { + return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0; + } + + /// \brief Gets the location of the extern keyword, if present. + SourceLocation getExternLoc() const { + return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation(); + } + /// \brief Sets the location of the extern keyword. + void setExternLoc(SourceLocation Loc) { + if (!ExplicitInfo) + ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; + ExplicitInfo->ExternLoc = Loc; + } + + /// \brief Sets the location of the template keyword. + void setTemplateKeywordLoc(SourceLocation Loc) { + if (!ExplicitInfo) + ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; + ExplicitInfo->TemplateKeywordLoc = Loc; + } + /// \brief Gets the location of the template keyword, if present. + SourceLocation getTemplateKeywordLoc() const { + return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation(); + } + + void Profile(llvm::FoldingSetNodeID &ID) const { + Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, + const TemplateArgument *TemplateArgs, + unsigned NumTemplateArgs, ASTContext &Context) { + ID.AddInteger(NumTemplateArgs); + for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg) + TemplateArgs[Arg].Profile(ID, Context); + } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { + return K >= firstVarTemplateSpecialization && + K <= lastVarTemplateSpecialization; + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +class VarTemplatePartialSpecializationDecl + : public VarTemplateSpecializationDecl { + virtual void anchor(); + + /// \brief The list of template parameters + TemplateParameterList *TemplateParams; + + /// \brief The source info for the template arguments as written. + /// FIXME: redundant with TypeAsWritten? + const ASTTemplateArgumentListInfo *ArgsAsWritten; + + /// \brief The variable template partial specialization from which this + /// variable template partial specialization was instantiated. + /// + /// The boolean value will be true to indicate that this variable template + /// partial specialization was specialized at this level. + llvm::PointerIntPair + InstantiatedFromMember; + + VarTemplatePartialSpecializationDecl( + ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, TemplateParameterList *Params, + VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, + StorageClass S, const TemplateArgument *Args, unsigned NumArgs, + const ASTTemplateArgumentListInfo *ArgInfos); + + VarTemplatePartialSpecializationDecl() + : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization), + TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) {} + +public: + static VarTemplatePartialSpecializationDecl * + Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, TemplateParameterList *Params, + VarTemplateDecl *SpecializedTemplate, QualType T, + TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, + unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos); + + static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C, + unsigned ID); + + VarTemplatePartialSpecializationDecl *getMostRecentDecl() { + return cast( + static_cast( + this)->getMostRecentDecl()); + } + + /// Get the list of template parameters + TemplateParameterList *getTemplateParameters() const { + return TemplateParams; + } + + /// Get the template arguments as written. + const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { + return ArgsAsWritten; + } + + /// \brief Retrieve the member variable template partial specialization from + /// which this particular variable template partial specialization was + /// instantiated. + /// + /// \code + /// template + /// struct Outer { + /// template U Inner; + /// template U* Inner = (U*)(0); // #1 + /// }; + /// + /// template int* Outer::Inner; + /// \endcode + /// + /// In this example, the instantiation of \c Outer::Inner will + /// end up instantiating the partial specialization + /// \c Outer::Inner, which itself was instantiated from the + /// variable template partial specialization \c Outer::Inner. Given + /// \c Outer::Inner, this function would return + /// \c Outer::Inner. + VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() { + VarTemplatePartialSpecializationDecl *First = + cast(getFirstDecl()); + return First->InstantiatedFromMember.getPointer(); + } + + void + setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) { + VarTemplatePartialSpecializationDecl *First = + cast(getFirstDecl()); + First->InstantiatedFromMember.setPointer(PartialSpec); + } + + /// \brief Determines whether this variable template partial specialization + /// was a specialization of a member partial specialization. + /// + /// In the following example, the member template partial specialization + /// \c X::Inner is a member specialization. + /// + /// \code + /// template + /// struct X { + /// template U Inner; + /// template U* Inner = (U*)(0); + /// }; + /// + /// template<> template + /// U* X::Inner = (T*)(0) + 1; + /// \endcode + bool isMemberSpecialization() { + VarTemplatePartialSpecializationDecl *First = + cast(getFirstDecl()); + return First->InstantiatedFromMember.getInt(); + } + + /// \brief Note that this member template is a specialization. + void setMemberSpecialization() { + VarTemplatePartialSpecializationDecl *First = + cast(getFirstDecl()); + assert(First->InstantiatedFromMember.getPointer() && + "Only member templates can be member template specializations"); + return First->InstantiatedFromMember.setInt(true); + } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { + return K == VarTemplatePartialSpecialization; + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// Declaration of a variable template. +class VarTemplateDecl : public RedeclarableTemplateDecl { + static void DeallocateCommon(void *Ptr); + +protected: + /// \brief Data that is common to all of the declarations of a given + /// variable template. + struct Common : CommonBase { + Common() : LazySpecializations() {} + + /// \brief The variable template specializations for this variable + /// template, including explicit specializations and instantiations. + llvm::FoldingSetVector Specializations; + + /// \brief The variable template partial specializations for this variable + /// template. + llvm::FoldingSetVector + PartialSpecializations; + + /// \brief If non-null, points to an array of specializations (including + /// partial specializations) known ownly by their external declaration IDs. + /// + /// The first value in the array is the number of of specializations/ + /// partial specializations that follow. + uint32_t *LazySpecializations; + }; + + /// \brief Load any lazily-loaded specializations from the external source. + void LoadLazySpecializations() const; + + /// \brief Retrieve the set of specializations of this variable template. + llvm::FoldingSetVector & + getSpecializations() const; + + /// \brief Retrieve the set of partial specializations of this class + /// template. + llvm::FoldingSetVector & + getPartialSpecializations(); + + VarTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, NamedDecl *Decl) + : RedeclarableTemplateDecl(VarTemplate, DC, L, Name, Params, Decl) {} + + VarTemplateDecl(EmptyShell Empty) + : RedeclarableTemplateDecl(VarTemplate, 0, SourceLocation(), + DeclarationName(), 0, 0) {} + + CommonBase *newCommon(ASTContext &C) const; + + Common *getCommonPtr() const { + return static_cast(RedeclarableTemplateDecl::getCommonPtr()); + } + +public: + /// \brief Get the underlying variable declarations of the template. + VarDecl *getTemplatedDecl() const { + return static_cast(TemplatedDecl); + } + + /// \brief Returns whether this template declaration defines the primary + /// variable pattern. + bool isThisDeclarationADefinition() const { + return getTemplatedDecl()->isThisDeclarationADefinition(); + } + + VarTemplateDecl *getDefinition(); + + /// \brief Create a variable template node. + static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, NamedDecl *Decl, + VarTemplateDecl *PrevDecl); + + /// \brief Create an empty variable template node. + static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + /// \brief Return the specialization with the provided arguments if it exists, + /// otherwise return the insertion point. + VarTemplateSpecializationDecl * + findSpecialization(const TemplateArgument *Args, unsigned NumArgs, + void *&InsertPos); + + /// \brief Insert the specified specialization knowing that it is not already + /// in. InsertPos must be obtained from findSpecialization. + void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos); + + VarTemplateDecl *getCanonicalDecl() { + return cast(RedeclarableTemplateDecl::getCanonicalDecl()); + } + const VarTemplateDecl *getCanonicalDecl() const { + return cast(RedeclarableTemplateDecl::getCanonicalDecl()); + } + + /// \brief Retrieve the previous declaration of this variable template, or + /// NULL if no such declaration exists. + VarTemplateDecl *getPreviousDecl() { + return cast_or_null( + static_cast(this)->getPreviousDecl()); + } + + /// \brief Retrieve the previous declaration of this variable template, or + /// NULL if no such declaration exists. + const VarTemplateDecl *getPreviousDecl() const { + return cast_or_null( + static_cast( + this)->getPreviousDecl()); + } + + VarTemplateDecl *getInstantiatedFromMemberTemplate() { + return cast_or_null( + RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); + } + + /// \brief Return the partial specialization with the provided arguments if it + /// exists, otherwise return the insertion point. + VarTemplatePartialSpecializationDecl * + findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs, + void *&InsertPos); + + /// \brief Insert the specified partial specialization knowing that it is not + /// already in. InsertPos must be obtained from findPartialSpecialization. + void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, + void *InsertPos); + + /// \brief Retrieve the partial specializations as an ordered list. + void getPartialSpecializations( + SmallVectorImpl &PS); + + /// \brief Find a variable template partial specialization which was + /// instantiated + /// from the given member partial specialization. + /// + /// \param D a member variable template partial specialization. + /// + /// \returns the variable template partial specialization which was + /// instantiated + /// from the given member partial specialization, or NULL if no such partial + /// specialization exists. + VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember( + VarTemplatePartialSpecializationDecl *D); + + typedef SpecIterator spec_iterator; + + spec_iterator spec_begin() const { + return makeSpecIterator(getSpecializations(), false); + } + + spec_iterator spec_end() const { + return makeSpecIterator(getSpecializations(), true); + } + + typedef SpecIterator + partial_spec_iterator; + + partial_spec_iterator partial_spec_begin() { + return makeSpecIterator(getPartialSpecializations(), false); + } + + partial_spec_iterator partial_spec_end() { + return makeSpecIterator(getPartialSpecializations(), true); + } + + // Implement isa/cast/dyncast support + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == VarTemplate; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + } /* end of namespace clang */ #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h b/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h index f28882b..00766c2 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h @@ -182,11 +182,16 @@ public: // operator bool() - Evaluates true when this declaration name is // non-empty. - operator bool() const { + LLVM_EXPLICIT operator bool() const { return ((Ptr & PtrMask) != 0) || (reinterpret_cast(Ptr & ~PtrMask)); } + /// \brief Evaluates true when this declaration name is empty. + bool isEmpty() const { + return !*this; + } + /// Predicate functions for querying what type of name this is. bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; } bool isObjCZeroArgSelector() const { @@ -210,9 +215,6 @@ public: /// getNameAsString - Retrieve the human-readable string for this name. std::string getAsString() const; - /// printName - Print the human-readable name to a stream. - void printName(raw_ostream &OS) const; - /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in /// this declaration name, or NULL if this declaration name isn't a /// simple identifier. @@ -302,6 +304,8 @@ public: void dump() const; }; +raw_ostream &operator<<(raw_ostream &OS, DeclarationName N); + /// Ordering on two declaration names. If both names are identifiers, /// this provides a lexicographical ordering. inline bool operator<(DeclarationName LHS, DeclarationName RHS) { diff --git a/contrib/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h index 2e3cbfa..12c4fcc 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h @@ -53,7 +53,7 @@ public: if (E->getCond()->isValueDependent()) return; // Only the selected subexpression matters; the other one is not evaluated. - return this->Visit(E->getChosenSubExpr(Context)); + return this->Visit(E->getChosenSubExpr()); } void VisitDesignatedInitExpr(DesignatedInitExpr *E) { diff --git a/contrib/llvm/tools/clang/include/clang/AST/Expr.h b/contrib/llvm/tools/clang/include/clang/AST/Expr.h index 4ff1257..f2648b9 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Expr.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Expr.h @@ -277,7 +277,6 @@ public: MLV_IncompleteType, MLV_ConstQualified, MLV_ArrayType, - MLV_ReadonlyProperty, MLV_NoSetterProperty, MLV_MemberFunction, MLV_SubObjCPropertySetting, @@ -483,21 +482,22 @@ public: /// /// Note: This does not perform the implicit conversions required by C++11 /// [expr.const]p5. - bool isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, + bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc = 0, bool isEvaluated = true) const; - bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const; + bool isIntegerConstantExpr(const ASTContext &Ctx, + SourceLocation *Loc = 0) const; /// isCXX98IntegralConstantExpr - Return true if this expression is an /// integral constant expression in C++98. Can only be used in C++. - bool isCXX98IntegralConstantExpr(ASTContext &Ctx) const; + bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const; /// isCXX11ConstantExpr - Return true if this expression is a constant /// expression in C++11. Can only be used in C++. /// /// Note: This does not perform the implicit conversions required by C++11 /// [expr.const]p5. - bool isCXX11ConstantExpr(ASTContext &Ctx, APValue *Result = 0, + bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = 0, SourceLocation *Loc = 0) const; /// isPotentialConstantExpr - Return true if this function's definition @@ -579,15 +579,14 @@ public: /// \brief Determine whether this expression involves a call to any function /// that is not trivial. bool hasNonTrivialCall(ASTContext &Ctx); - + /// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded /// integer. This must be called on an expression that constant folds to an /// integer. llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl *Diag=0) const; - - void EvaluateForOverflow(const ASTContext &Ctx, - SmallVectorImpl *Diag) const; + + void EvaluateForOverflow(const ASTContext &Ctx) const; /// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an /// lvalue with link time known address, with no side-effects. @@ -760,10 +759,10 @@ public: /// Walk outwards from an expression we want to bind a reference to and /// find the expression whose lifetime needs to be extended. Record - /// the adjustments needed along the path. - const Expr * - skipRValueSubobjectAdjustments( - SmallVectorImpl &Adjustments) const; + /// the LHSs of comma expressions and adjustments needed along the path. + const Expr *skipRValueSubobjectAdjustments( + SmallVectorImpl &CommaLHS, + SmallVectorImpl &Adjustments) const; /// Skip irrelevant expressions to find what should be materialize for /// binding with a reference. @@ -893,7 +892,7 @@ class DeclRefExpr : public Expr { bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; } /// \brief Helper to retrieve the optional NamedDecl through which this - /// reference occured. + /// reference occurred. NamedDecl *&getInternalFoundDecl() { assert(hasFoundDecl()); if (hasQualifier()) @@ -902,12 +901,12 @@ class DeclRefExpr : public Expr { } /// \brief Helper to retrieve the optional NamedDecl through which this - /// reference occured. + /// reference occurred. NamedDecl *getInternalFoundDecl() const { return const_cast(this)->getInternalFoundDecl(); } - DeclRefExpr(ASTContext &Ctx, + DeclRefExpr(const ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool refersToEnclosingLocal, @@ -922,7 +921,7 @@ class DeclRefExpr : public Expr { /// \brief Computes the type- and value-dependence flags for this /// declaration reference expression. - void computeDependence(ASTContext &C); + void computeDependence(const ASTContext &C); public: DeclRefExpr(ValueDecl *D, bool refersToEnclosingLocal, QualType T, @@ -938,7 +937,7 @@ public: computeDependence(D->getASTContext()); } - static DeclRefExpr *Create(ASTContext &Context, + static DeclRefExpr *Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, @@ -948,7 +947,7 @@ public: NamedDecl *FoundD = 0, const TemplateArgumentListInfo *TemplateArgs = 0); - static DeclRefExpr *Create(ASTContext &Context, + static DeclRefExpr *Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, @@ -959,7 +958,7 @@ public: const TemplateArgumentListInfo *TemplateArgs = 0); /// \brief Construct an empty declaration reference expression. - static DeclRefExpr *CreateEmpty(ASTContext &Context, + static DeclRefExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier, bool HasFoundDecl, bool HasTemplateKWAndArgsInfo, @@ -1000,7 +999,7 @@ public: return getInternalQualifierLoc(); } - /// \brief Get the NamedDecl through which this reference occured. + /// \brief Get the NamedDecl through which this reference occurred. /// /// This Decl may be different from the ValueDecl actually referred to in the /// presence of using declarations, etc. It always returns non-NULL, and may @@ -1151,6 +1150,7 @@ public: Func, Function, LFunction, // Same as Function, but as wide string. + FuncDName, PrettyFunction, /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the /// 'virtual' keyword is omitted for virtual member functions. @@ -1221,13 +1221,15 @@ protected: else return llvm::APInt(BitWidth, VAL); } - void setIntValue(ASTContext &C, const llvm::APInt &Val); + void setIntValue(const ASTContext &C, const llvm::APInt &Val); }; class APIntStorage : private APNumericStorage { public: llvm::APInt getValue() const { return getIntValue(); } - void setValue(ASTContext &C, const llvm::APInt &Val) { setIntValue(C, Val); } + void setValue(const ASTContext &C, const llvm::APInt &Val) { + setIntValue(C, Val); + } }; class APFloatStorage : private APNumericStorage { @@ -1235,7 +1237,7 @@ public: llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const { return llvm::APFloat(Semantics, getIntValue()); } - void setValue(ASTContext &C, const llvm::APFloat &Val) { + void setValue(const ASTContext &C, const llvm::APFloat &Val) { setIntValue(C, Val.bitcastToAPInt()); } }; @@ -1250,17 +1252,17 @@ class IntegerLiteral : public Expr, public APIntStorage { public: // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy, // or UnsignedLongLongTy - IntegerLiteral(ASTContext &C, const llvm::APInt &V, QualType type, + IntegerLiteral(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l); /// \brief Returns a new integer literal with value 'V' and type 'type'. /// \param type - either IntTy, LongTy, LongLongTy, UnsignedIntTy, /// UnsignedLongTy, or UnsignedLongLongTy which should match the size of V /// \param V - the value that the returned integer literal contains. - static IntegerLiteral *Create(ASTContext &C, const llvm::APInt &V, + static IntegerLiteral *Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l); /// \brief Returns a new empty integer literal. - static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty); + static IntegerLiteral *Create(const ASTContext &C, EmptyShell Empty); SourceLocation getLocStart() const LLVM_READONLY { return Loc; } SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } @@ -1328,21 +1330,21 @@ public: class FloatingLiteral : public Expr, private APFloatStorage { SourceLocation Loc; - FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact, + FloatingLiteral(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L); /// \brief Construct an empty floating-point literal. - explicit FloatingLiteral(ASTContext &C, EmptyShell Empty); + explicit FloatingLiteral(const ASTContext &C, EmptyShell Empty); public: - static FloatingLiteral *Create(ASTContext &C, const llvm::APFloat &V, + static FloatingLiteral *Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L); - static FloatingLiteral *Create(ASTContext &C, EmptyShell Empty); + static FloatingLiteral *Create(const ASTContext &C, EmptyShell Empty); llvm::APFloat getValue() const { return APFloatStorage::getValue(getSemantics()); } - void setValue(ASTContext &C, const llvm::APFloat &Val) { + void setValue(const ASTContext &C, const llvm::APFloat &Val) { assert(&getSemantics() == &Val.getSemantics() && "Inconsistent semantics"); APFloatStorage::setValue(C, Val); } @@ -1420,7 +1422,7 @@ public: }; /// StringLiteral - This represents a string literal expression, e.g. "foo" -/// or L"bar" (wide strings). The actual string is returned by getStrData() +/// or L"bar" (wide strings). The actual string is returned by getBytes() /// is NOT null-terminated, and the length of the string is determined by /// calling getByteLength(). The C type for a string is always a /// ConstantArrayType. In C++, the char type is const qualified, in C it is @@ -1469,19 +1471,19 @@ private: public: /// This is the "fully general" constructor that allows representation of /// strings formed from multiple concatenated tokens. - static StringLiteral *Create(ASTContext &C, StringRef Str, StringKind Kind, - bool Pascal, QualType Ty, + static StringLiteral *Create(const ASTContext &C, StringRef Str, + StringKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumStrs); /// Simple constructor for string literals made from one token. - static StringLiteral *Create(ASTContext &C, StringRef Str, StringKind Kind, - bool Pascal, QualType Ty, + static StringLiteral *Create(const ASTContext &C, StringRef Str, + StringKind Kind, bool Pascal, QualType Ty, SourceLocation Loc) { return Create(C, Str, Kind, Pascal, Ty, &Loc, 1); } /// \brief Construct an empty string literal. - static StringLiteral *CreateEmpty(ASTContext &C, unsigned NumStrs); + static StringLiteral *CreateEmpty(const ASTContext &C, unsigned NumStrs); StringRef getString() const { assert(CharByteWidth==1 @@ -1520,7 +1522,7 @@ public: unsigned getCharByteWidth() const { return CharByteWidth; } /// \brief Sets the string data to the given string data. - void setString(ASTContext &C, StringRef Str, + void setString(const ASTContext &C, StringRef Str, StringKind Kind, bool IsPascal); StringKind getKind() const { return static_cast(Kind); } @@ -1853,7 +1855,7 @@ private: // Number of sub-expressions (i.e. array subscript expressions). unsigned NumExprs; - OffsetOfExpr(ASTContext &C, QualType type, + OffsetOfExpr(const ASTContext &C, QualType type, SourceLocation OperatorLoc, TypeSourceInfo *tsi, ArrayRef comps, ArrayRef exprs, SourceLocation RParenLoc); @@ -1864,12 +1866,12 @@ private: public: - static OffsetOfExpr *Create(ASTContext &C, QualType type, + static OffsetOfExpr *Create(const ASTContext &C, QualType type, SourceLocation OperatorLoc, TypeSourceInfo *tsi, ArrayRef comps, ArrayRef exprs, SourceLocation RParenLoc); - static OffsetOfExpr *CreateEmpty(ASTContext &C, + static OffsetOfExpr *CreateEmpty(const ASTContext &C, unsigned NumComps, unsigned NumExprs); /// getOperatorLoc - Return the location of the operator. @@ -2133,10 +2135,11 @@ class CallExpr : public Expr { protected: // These versions of the constructor are for derived classes. - CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, + CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, ArrayRef args, QualType t, ExprValueKind VK, SourceLocation rparenloc); - CallExpr(ASTContext &C, StmtClass SC, unsigned NumPreArgs, EmptyShell Empty); + CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs, + EmptyShell Empty); Stmt *getPreArg(unsigned i) { assert(i < getNumPreArgs() && "Prearg access out of range!"); @@ -2154,11 +2157,11 @@ protected: unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; } public: - CallExpr(ASTContext& C, Expr *fn, ArrayRef args, QualType t, + CallExpr(const ASTContext& C, Expr *fn, ArrayRef args, QualType t, ExprValueKind VK, SourceLocation rparenloc); /// \brief Build an empty call expression. - CallExpr(ASTContext &C, StmtClass SC, EmptyShell Empty); + CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty); const Expr *getCallee() const { return cast(SubExprs[FN]); } Expr *getCallee() { return cast(SubExprs[FN]); } @@ -2206,7 +2209,7 @@ public: /// setNumArgs - This changes the number of arguments present in this call. /// Any orphaned expressions are deleted by this, and any new operands are set /// to null. - void setNumArgs(ASTContext& C, unsigned NumArgs); + void setNumArgs(const ASTContext& C, unsigned NumArgs); typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; @@ -2360,7 +2363,7 @@ public: HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false), HadMultipleCandidates(false) {} - static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow, + static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *memberdecl, DeclAccessPair founddecl, @@ -2747,12 +2750,13 @@ public: : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) { } - static ImplicitCastExpr *Create(ASTContext &Context, QualType T, + static ImplicitCastExpr *Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat); - static ImplicitCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize); + static ImplicitCastExpr *CreateEmpty(const ASTContext &Context, + unsigned PathSize); SourceLocation getLocStart() const LLVM_READONLY { return getSubExpr()->getLocStart(); @@ -2838,13 +2842,14 @@ class CStyleCastExpr : public ExplicitCastExpr { : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { } public: - static CStyleCastExpr *Create(ASTContext &Context, QualType T, + static CStyleCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R); - static CStyleCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize); + static CStyleCastExpr *CreateEmpty(const ASTContext &Context, + unsigned PathSize); SourceLocation getLParenLoc() const { return LPLoc; } void setLParenLoc(SourceLocation L) { LPLoc = L; } @@ -3412,7 +3417,7 @@ class ShuffleVectorExpr : public Expr { unsigned NumExprs; public: - ShuffleVectorExpr(ASTContext &C, ArrayRef args, QualType Type, + ShuffleVectorExpr(const ASTContext &C, ArrayRef args, QualType Type, SourceLocation BLoc, SourceLocation RP); /// \brief Build an empty vector-shuffle expression. @@ -3450,11 +3455,11 @@ public: return cast(SubExprs[Index]); } - void setExprs(ASTContext &C, Expr ** Exprs, unsigned NumExprs); + void setExprs(const ASTContext &C, ArrayRef Exprs); - unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) const { + llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const { assert((N < NumExprs - 2) && "Shuffle idx out of range!"); - return getExpr(N+2)->EvaluateKnownConstInt(Ctx).getZExtValue(); + return getExpr(N+2)->EvaluateKnownConstInt(Ctx); } // Iterators @@ -3463,6 +3468,60 @@ public: } }; +/// ConvertVectorExpr - Clang builtin function __builtin_convertvector +/// This AST node provides support for converting a vector type to another +/// vector type of the same arity. +class ConvertVectorExpr : public Expr { +private: + Stmt *SrcExpr; + TypeSourceInfo *TInfo; + SourceLocation BuiltinLoc, RParenLoc; + + friend class ASTReader; + friend class ASTStmtReader; + explicit ConvertVectorExpr(EmptyShell Empty) : Expr(ConvertVectorExprClass, Empty) {} + +public: + ConvertVectorExpr(Expr* SrcExpr, TypeSourceInfo *TI, QualType DstType, + ExprValueKind VK, ExprObjectKind OK, + SourceLocation BuiltinLoc, SourceLocation RParenLoc) + : Expr(ConvertVectorExprClass, DstType, VK, OK, + DstType->isDependentType(), + DstType->isDependentType() || SrcExpr->isValueDependent(), + (DstType->isInstantiationDependentType() || + SrcExpr->isInstantiationDependent()), + (DstType->containsUnexpandedParameterPack() || + SrcExpr->containsUnexpandedParameterPack())), + SrcExpr(SrcExpr), TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {} + + /// getSrcExpr - Return the Expr to be converted. + Expr *getSrcExpr() const { return cast(SrcExpr); } + + /// getTypeSourceInfo - Return the destination type. + TypeSourceInfo *getTypeSourceInfo() const { + return TInfo; + } + void setTypeSourceInfo(TypeSourceInfo *ti) { + TInfo = ti; + } + + /// getBuiltinLoc - Return the location of the __builtin_convertvector token. + SourceLocation getBuiltinLoc() const { return BuiltinLoc; } + + /// getRParenLoc - Return the location of final right parenthesis. + SourceLocation getRParenLoc() const { return RParenLoc; } + + SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ConvertVectorExprClass; + } + + // Iterators + child_range children() { return child_range(&SrcExpr, &SrcExpr+1); } +}; + /// ChooseExpr - GNU builtin-in function __builtin_choose_expr. /// This AST node is similar to the conditional operator (?:) in C, with /// the following exceptions: @@ -3476,10 +3535,12 @@ class ChooseExpr : public Expr { enum { COND, LHS, RHS, END_EXPR }; Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. SourceLocation BuiltinLoc, RParenLoc; + bool CondIsTrue; public: ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t, ExprValueKind VK, ExprObjectKind OK, - SourceLocation RP, bool TypeDependent, bool ValueDependent) + SourceLocation RP, bool condIsTrue, + bool TypeDependent, bool ValueDependent) : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent, (cond->isInstantiationDependent() || lhs->isInstantiationDependent() || @@ -3487,7 +3548,7 @@ public: (cond->containsUnexpandedParameterPack() || lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), - BuiltinLoc(BLoc), RParenLoc(RP) { + BuiltinLoc(BLoc), RParenLoc(RP), CondIsTrue(condIsTrue) { SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; @@ -3498,12 +3559,21 @@ public: /// isConditionTrue - Return whether the condition is true (i.e. not /// equal to zero). - bool isConditionTrue(const ASTContext &C) const; + bool isConditionTrue() const { + assert(!isConditionDependent() && + "Dependent condition isn't true or false"); + return CondIsTrue; + } + void setIsConditionTrue(bool isTrue) { CondIsTrue = isTrue; } + + bool isConditionDependent() const { + return getCond()->isTypeDependent() || getCond()->isValueDependent(); + } /// getChosenSubExpr - Return the subexpression chosen according to the /// condition. - Expr *getChosenSubExpr(const ASTContext &C) const { - return isConditionTrue(C) ? getLHS() : getRHS(); + Expr *getChosenSubExpr() const { + return isConditionTrue() ? getLHS() : getRHS(); } Expr *getCond() const { return cast(SubExprs[COND]); } @@ -3663,7 +3733,7 @@ class InitListExpr : public Expr { SourceLocation LBraceLoc, RBraceLoc; /// The alternative form of the initializer list (if it exists). - /// The int part of the pair stores whether this initalizer list is + /// The int part of the pair stores whether this initializer list is /// in semantic form. If not null, the pointer points to: /// - the syntactic form, if this is in semantic form; /// - the semantic form, if this is in syntactic form. @@ -3679,7 +3749,7 @@ class InitListExpr : public Expr { llvm::PointerUnion ArrayFillerOrUnionFieldInit; public: - InitListExpr(ASTContext &C, SourceLocation lbraceloc, + InitListExpr(const ASTContext &C, SourceLocation lbraceloc, ArrayRef initExprs, SourceLocation rbraceloc); /// \brief Build an empty initializer list. @@ -3707,7 +3777,7 @@ public: } /// \brief Reserve space for some number of initializers. - void reserveInits(ASTContext &C, unsigned NumInits); + void reserveInits(const ASTContext &C, unsigned NumInits); /// @brief Specify the number of initializers /// @@ -3715,7 +3785,7 @@ public: /// initializers will be destroyed. If there are fewer than @p /// NumInits initializers, NULL expressions will be added for the /// unknown initializers. - void resizeInits(ASTContext &Context, unsigned NumInits); + void resizeInits(const ASTContext &Context, unsigned NumInits); /// @brief Updates the initializer at index @p Init with the new /// expression @p expr, and returns the old expression at that @@ -3724,7 +3794,7 @@ public: /// When @p Init is out of range for this initializer list, the /// initializer list will be extended with NULL expressions to /// accommodate the new entry. - Expr *updateInit(ASTContext &C, unsigned Init, Expr *expr); + Expr *updateInit(const ASTContext &C, unsigned Init, Expr *expr); /// \brief If this initializer list initializes an array with more elements /// than there are initializers in the list, specifies an expression to be @@ -3754,6 +3824,10 @@ public: return const_cast(this)->getInitializedFieldInUnion(); } void setInitializedFieldInUnion(FieldDecl *FD) { + assert((FD == 0 + || getInitializedFieldInUnion() == 0 + || getInitializedFieldInUnion() == FD) + && "Only one field of a union may be initialized at a time!"); ArrayFillerOrUnionFieldInit = FD; } @@ -3794,13 +3868,6 @@ public: InitListExprBits.HadArrayRangeDesignator = ARD; } - bool initializesStdInitializerList() const { - return InitListExprBits.InitializesStdInitializerList != 0; - } - void setInitializesStdInitializerList(bool ISIL = true) { - InitListExprBits.InitializesStdInitializerList = ISIL; - } - SourceLocation getLocStart() const LLVM_READONLY; SourceLocation getLocEnd() const LLVM_READONLY; @@ -3851,7 +3918,7 @@ public: /// The InitListExpr contains three DesignatedInitExprs, the first of /// which covers @c [2].y=1.0. This DesignatedInitExpr will have two /// designators, one array designator for @c [2] followed by one field -/// designator for @c .y. The initalization expression will be 1.0. +/// designator for @c .y. The initialization expression will be 1.0. class DesignatedInitExpr : public Expr { public: /// \brief Forward declaration of the Designator class. @@ -3879,7 +3946,7 @@ private: Designator *Designators; - DesignatedInitExpr(ASTContext &C, QualType Ty, unsigned NumDesignators, + DesignatedInitExpr(const ASTContext &C, QualType Ty, unsigned NumDesignators, const Designator *Designators, SourceLocation EqualOrColonLoc, bool GNUSyntax, ArrayRef IndexExprs, Expr *Init); @@ -4041,13 +4108,15 @@ public: } }; - static DesignatedInitExpr *Create(ASTContext &C, Designator *Designators, + static DesignatedInitExpr *Create(const ASTContext &C, + Designator *Designators, unsigned NumDesignators, ArrayRef IndexExprs, SourceLocation EqualOrColonLoc, bool GNUSyntax, Expr *Init); - static DesignatedInitExpr *CreateEmpty(ASTContext &C, unsigned NumIndexExprs); + static DesignatedInitExpr *CreateEmpty(const ASTContext &C, + unsigned NumIndexExprs); /// @brief Returns the number of designators in this initializer. unsigned size() const { return NumDesignators; } @@ -4085,7 +4154,7 @@ public: Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; } - void setDesignators(ASTContext &C, const Designator *Desigs, + void setDesignators(const ASTContext &C, const Designator *Desigs, unsigned NumDesigs); Expr *getArrayIndex(const Designator &D) const; @@ -4133,8 +4202,8 @@ public: /// \brief Replaces the designator at index @p Idx with the series /// of designators in [First, Last). - void ExpandDesignator(ASTContext &C, unsigned Idx, const Designator *First, - const Designator *Last); + void ExpandDesignator(const ASTContext &C, unsigned Idx, + const Designator *First, const Designator *Last); SourceRange getDesignatorsSourceRange() const; @@ -4188,8 +4257,8 @@ class ParenListExpr : public Expr { SourceLocation LParenLoc, RParenLoc; public: - ParenListExpr(ASTContext& C, SourceLocation lparenloc, ArrayRef exprs, - SourceLocation rparenloc); + ParenListExpr(const ASTContext& C, SourceLocation lparenloc, + ArrayRef exprs, SourceLocation rparenloc); /// \brief Build an empty paren list. explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { } @@ -4262,7 +4331,7 @@ class GenericSelectionExpr : public Expr { SourceLocation GenericLoc, DefaultLoc, RParenLoc; public: - GenericSelectionExpr(ASTContext &Context, + GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef AssocTypes, ArrayRef AssocExprs, @@ -4271,7 +4340,7 @@ public: unsigned ResultIndex); /// This constructor is used in the result-dependent case. - GenericSelectionExpr(ASTContext &Context, + GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef AssocTypes, ArrayRef AssocExprs, @@ -4450,7 +4519,7 @@ public: /// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] /// This AST node provides support for reinterpreting a type to another /// type of the same size. -class AsTypeExpr : public Expr { // Should this be an ExplicitCastExpr? +class AsTypeExpr : public Expr { private: Stmt *SrcExpr; SourceLocation BuiltinLoc, RParenLoc; @@ -4552,13 +4621,13 @@ class PseudoObjectExpr : public Expr { public: /// NoResult - A value for the result index indicating that there is /// no semantic result. - enum { NoResult = ~0U }; + enum LLVM_ENUM_INT_TYPE(unsigned) { NoResult = ~0U }; - static PseudoObjectExpr *Create(ASTContext &Context, Expr *syntactic, + static PseudoObjectExpr *Create(const ASTContext &Context, Expr *syntactic, ArrayRef semantic, unsigned resultIndex); - static PseudoObjectExpr *Create(ASTContext &Context, EmptyShell shell, + static PseudoObjectExpr *Create(const ASTContext &Context, EmptyShell shell, unsigned numSemanticExprs); /// Return the syntactic form of this expression, i.e. the diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h b/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h index 91e5b21..6356ee7 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h @@ -6,9 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines the Expr interface and subclasses for C++ expressions. -// +/// +/// \file +/// \brief Defines the clang::Expr interface and subclasses for C++ expressions. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_EXPRCXX_H @@ -74,15 +75,15 @@ public: CallExpr(C, CXXOperatorCallExprClass, Empty) { } - /// getOperator - Returns the kind of overloaded operator that this + /// \brief Returns the kind of overloaded operator that this /// expression refers to. OverloadedOperatorKind getOperator() const { return Operator; } - /// getOperatorLoc - Returns the location of the operator symbol in - /// the expression. When @c getOperator()==OO_Call, this is the - /// location of the right parentheses; when @c - /// getOperator()==OO_Subscript, this is the location of the right - /// bracket. + /// \brief Returns the location of the operator symbol in the expression. + /// + /// When \c getOperator()==OO_Call, this is the location of the right + /// parentheses; when \c getOperator()==OO_Subscript, this is the location + /// of the right bracket. SourceLocation getOperatorLoc() const { return getRParenLoc(); } SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } @@ -105,7 +106,7 @@ public: friend class ASTStmtWriter; }; -/// CXXMemberCallExpr - Represents a call to a member function that +/// Represents a call to a member function that /// may be written either with member call syntax (e.g., "obj.func()" /// or "objptr->func()") or with normal function-call syntax /// ("func()") within a member function that ends up calling a member @@ -122,18 +123,19 @@ public: CXXMemberCallExpr(ASTContext &C, EmptyShell Empty) : CallExpr(C, CXXMemberCallExprClass, Empty) { } - /// getImplicitObjectArgument - Retrieves the implicit object - /// argument for the member call. For example, in "x.f(5)", this - /// operation would return "x". + /// \brief Retrieves the implicit object argument for the member call. + /// + /// For example, in "x.f(5)", this returns the sub-expression "x". Expr *getImplicitObjectArgument() const; - /// Retrieves the declaration of the called method. + /// \brief Retrieves the declaration of the called method. CXXMethodDecl *getMethodDecl() const; - /// getRecordDecl - Retrieves the CXXRecordDecl for the underlying type of - /// the implicit object argument. Note that this is may not be the same - /// declaration as that of the class context of the CXXMethodDecl which this - /// function is calling. + /// \brief Retrieves the CXXRecordDecl for the underlying type of + /// the implicit object argument. + /// + /// Note that this is may not be the same declaration as that of the class + /// context of the CXXMethodDecl which this function is calling. /// FIXME: Returns 0 for member pointer call exprs. CXXRecordDecl *getRecordDecl() const; @@ -142,7 +144,7 @@ public: } }; -/// CUDAKernelCallExpr - Represents a call to a CUDA kernel function. +/// \brief Represents a call to a CUDA kernel function. class CUDAKernelCallExpr : public CallExpr { private: enum { CONFIG, END_PREARG }; @@ -169,13 +171,12 @@ public: } }; -/// CXXNamedCastExpr - Abstract class common to all of the C++ "named" -/// casts, @c static_cast, @c dynamic_cast, @c reinterpret_cast, or @c -/// const_cast. +/// \brief Abstract class common to all of the C++ "named"/"keyword" casts. /// /// This abstract class is inherited by all of the classes -/// representing "named" casts, e.g., CXXStaticCastExpr, -/// CXXDynamicCastExpr, CXXReinterpretCastExpr, and CXXConstCastExpr. +/// representing "named" casts: CXXStaticCastExpr for \c static_cast, +/// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for +/// reinterpret_cast, and CXXConstCastExpr for \c const_cast. class CXXNamedCastExpr : public ExplicitCastExpr { private: SourceLocation Loc; // the location of the casting op @@ -200,7 +201,7 @@ public: const char *getCastName() const; /// \brief Retrieve the location of the cast operator keyword, e.g., - /// "static_cast". + /// \c static_cast. SourceLocation getOperatorLoc() const { return Loc; } /// \brief Retrieve the location of the closing parenthesis. @@ -223,11 +224,10 @@ public: } }; -/// CXXStaticCastExpr - A C++ @c static_cast expression -/// (C++ [expr.static.cast]). +/// \brief A C++ \c static_cast expression (C++ [expr.static.cast]). /// /// This expression node represents a C++ static cast, e.g., -/// @c static_cast(1.0). +/// \c static_cast(1.0). class CXXStaticCastExpr : public CXXNamedCastExpr { CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, @@ -240,13 +240,13 @@ class CXXStaticCastExpr : public CXXNamedCastExpr { : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { } public: - static CXXStaticCastExpr *Create(ASTContext &Context, QualType T, + static CXXStaticCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets); - static CXXStaticCastExpr *CreateEmpty(ASTContext &Context, + static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context, unsigned PathSize); static bool classof(const Stmt *T) { @@ -254,12 +254,11 @@ public: } }; -/// CXXDynamicCastExpr - A C++ @c dynamic_cast expression -/// (C++ [expr.dynamic.cast]), which may perform a run-time check to -/// determine how to perform the type cast. +/// \brief A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]). /// /// This expression node represents a dynamic cast, e.g., -/// @c dynamic_cast(BasePtr). +/// \c dynamic_cast(BasePtr). Such a cast may perform a run-time +/// check to determine how to perform the type conversion. class CXXDynamicCastExpr : public CXXNamedCastExpr { CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind, Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, @@ -272,14 +271,14 @@ class CXXDynamicCastExpr : public CXXNamedCastExpr { : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { } public: - static CXXDynamicCastExpr *Create(ASTContext &Context, QualType T, + static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets); - static CXXDynamicCastExpr *CreateEmpty(ASTContext &Context, + static CXXDynamicCastExpr *CreateEmpty(const ASTContext &Context, unsigned pathSize); bool isAlwaysNull() const; @@ -289,12 +288,14 @@ public: } }; -/// CXXReinterpretCastExpr - A C++ @c reinterpret_cast expression (C++ -/// [expr.reinterpret.cast]), which provides a differently-typed view -/// of a value but performs no actual work at run time. +/// \brief A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]). /// /// This expression node represents a reinterpret cast, e.g., /// @c reinterpret_cast(VoidPtr). +/// +/// A reinterpret_cast provides a differently-typed view of a value but +/// (in Clang, as in most C++ implementations) performs no actual work at +/// run time. class CXXReinterpretCastExpr : public CXXNamedCastExpr { CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, unsigned pathSize, @@ -308,13 +309,13 @@ class CXXReinterpretCastExpr : public CXXNamedCastExpr { : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { } public: - static CXXReinterpretCastExpr *Create(ASTContext &Context, QualType T, + static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets); - static CXXReinterpretCastExpr *CreateEmpty(ASTContext &Context, + static CXXReinterpretCastExpr *CreateEmpty(const ASTContext &Context, unsigned pathSize); static bool classof(const Stmt *T) { @@ -322,11 +323,13 @@ public: } }; -/// CXXConstCastExpr - A C++ @c const_cast expression (C++ [expr.const.cast]), -/// which can remove type qualifiers but does not change the underlying value. +/// \brief A C++ \c const_cast expression (C++ [expr.const.cast]). /// /// This expression node represents a const cast, e.g., -/// @c const_cast(PtrToConstChar). +/// \c const_cast(PtrToConstChar). +/// +/// A const_cast can remove type qualifiers but does not change the underlying +/// value. class CXXConstCastExpr : public CXXNamedCastExpr { CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op, TypeSourceInfo *writtenTy, SourceLocation l, @@ -338,19 +341,19 @@ class CXXConstCastExpr : public CXXNamedCastExpr { : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { } public: - static CXXConstCastExpr *Create(ASTContext &Context, QualType T, + static CXXConstCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets); - static CXXConstCastExpr *CreateEmpty(ASTContext &Context); + static CXXConstCastExpr *CreateEmpty(const ASTContext &Context); static bool classof(const Stmt *T) { return T->getStmtClass() == CXXConstCastExprClass; } }; -/// UserDefinedLiteral - A call to a literal operator (C++11 [over.literal]) +/// \brief A call to a literal operator (C++11 [over.literal]) /// written as a user-defined literal (C++11 [lit.ext]). /// /// Represents a user-defined literal, e.g. "foo"_bar or 1.23_xyz. While this @@ -364,12 +367,12 @@ class UserDefinedLiteral : public CallExpr { SourceLocation UDSuffixLoc; public: - UserDefinedLiteral(ASTContext &C, Expr *Fn, ArrayRef Args, + UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef Args, QualType T, ExprValueKind VK, SourceLocation LitEndLoc, SourceLocation SuffixLoc) : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc), UDSuffixLoc(SuffixLoc) {} - explicit UserDefinedLiteral(ASTContext &C, EmptyShell Empty) + explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty) : CallExpr(C, UserDefinedLiteralClass, Empty) {} /// The kind of literal operator which is invoked. @@ -382,11 +385,11 @@ public: LOK_Character ///< operator "" X (CharT) }; - /// getLiteralOperatorKind - Returns the kind of literal operator invocation + /// \brief Returns the kind of literal operator invocation /// which this expression represents. LiteralOperatorKind getLiteralOperatorKind() const; - /// getCookedLiteral - If this is not a raw user-defined literal, get the + /// \brief If this is not a raw user-defined literal, get the /// underlying cooked literal (representing the literal with the suffix /// removed). Expr *getCookedLiteral(); @@ -402,12 +405,13 @@ public: SourceLocation getLocEnd() const { return getRParenLoc(); } - /// getUDSuffixLoc - Returns the location of a ud-suffix in the expression. + /// \brief Returns the location of a ud-suffix in the expression. + /// /// For a string literal, there may be multiple identical suffixes. This /// returns the first. SourceLocation getUDSuffixLoc() const { return UDSuffixLoc; } - /// getUDSuffix - Returns the ud-suffix specified for this literal. + /// \brief Returns the ud-suffix specified for this literal. const IdentifierInfo *getUDSuffix() const; static bool classof(const Stmt *S) { @@ -418,7 +422,7 @@ public: friend class ASTStmtWriter; }; -/// CXXBoolLiteralExpr - [C++ 2.13.5] C++ Boolean Literal. +/// \brief A boolean literal, per ([C++ lex.bool] Boolean literals). /// class CXXBoolLiteralExpr : public Expr { bool Value; @@ -449,7 +453,9 @@ public: child_range children() { return child_range(); } }; -/// CXXNullPtrLiteralExpr - [C++0x 2.14.7] C++ Pointer Literal +/// \brief The null pointer literal (C++11 [lex.nullptr]) +/// +/// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr. class CXXNullPtrLiteralExpr : public Expr { SourceLocation Loc; public: @@ -474,11 +480,50 @@ public: child_range children() { return child_range(); } }; -/// CXXTypeidExpr - A C++ @c typeid expression (C++ [expr.typeid]), which gets -/// the type_info that corresponds to the supplied type, or the (possibly +/// \brief Implicit construction of a std::initializer_list object from an +/// array temporary within list-initialization (C++11 [dcl.init.list]p5). +class CXXStdInitializerListExpr : public Expr { + Stmt *SubExpr; + + CXXStdInitializerListExpr(EmptyShell Empty) + : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(0) {} + +public: + CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr) + : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary, + Ty->isDependentType(), SubExpr->isValueDependent(), + SubExpr->isInstantiationDependent(), + SubExpr->containsUnexpandedParameterPack()), + SubExpr(SubExpr) {} + + Expr *getSubExpr() { return static_cast(SubExpr); } + const Expr *getSubExpr() const { return static_cast(SubExpr); } + + SourceLocation getLocStart() const LLVM_READONLY { + return SubExpr->getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { + return SubExpr->getLocEnd(); + } + SourceRange getSourceRange() const LLVM_READONLY { + return SubExpr->getSourceRange(); + } + + static bool classof(const Stmt *S) { + return S->getStmtClass() == CXXStdInitializerListExprClass; + } + + child_range children() { return child_range(&SubExpr, &SubExpr + 1); } + + friend class ASTReader; + friend class ASTStmtReader; +}; + +/// A C++ \c typeid expression (C++ [expr.typeid]), which gets +/// the \c type_info that corresponds to the supplied type, or the (possibly /// dynamic) type of the supplied expression. /// -/// This represents code like @c typeid(int) or @c typeid(*objPtr) +/// This represents code like \c typeid(int) or \c typeid(*objPtr) class CXXTypeidExpr : public Expr { private: llvm::PointerUnion Operand; @@ -521,7 +566,7 @@ public: /// \brief Retrieves the type operand of this typeid() expression after /// various required adjustments (removing reference types, cv-qualifiers). - QualType getTypeOperand() const; + QualType getTypeOperand(ASTContext &Context) const; /// \brief Retrieve source information for the type operand. TypeSourceInfo *getTypeOperandSourceInfo() const { @@ -561,10 +606,11 @@ public: } }; -/// A member reference to an MSPropertyDecl. This expression always -/// has pseudo-object type, and therefore it is typically not -/// encountered in a fully-typechecked expression except within the -/// syntactic form of a PseudoObjectExpr. +/// \brief A member reference to an MSPropertyDecl. +/// +/// This expression always has pseudo-object type, and therefore it is +/// typically not encountered in a fully-typechecked expression except +/// within the syntactic form of a PseudoObjectExpr. class MSPropertyRefExpr : public Expr { Expr *BaseExpr; MSPropertyDecl *TheDecl; @@ -619,7 +665,7 @@ public: friend class ASTStmtReader; }; -/// CXXUuidofExpr - A microsoft C++ @c __uuidof expression, which gets +/// A Microsoft C++ @c __uuidof expression, which gets /// the _GUID that corresponds to the supplied type or expression. /// /// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr) @@ -655,7 +701,7 @@ public: /// \brief Retrieves the type operand of this __uuidof() expression after /// various required adjustments (removing reference types, cv-qualifiers). - QualType getTypeOperand() const; + QualType getTypeOperand(ASTContext &Context) const; /// \brief Retrieve source information for the type operand. TypeSourceInfo *getTypeOperandSourceInfo() const { @@ -678,6 +724,8 @@ public: Operand = E; } + StringRef getUuidAsStringRef(ASTContext &Context) const; + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const LLVM_READONLY { return Range; } @@ -687,8 +735,10 @@ public: return T->getStmtClass() == CXXUuidofExprClass; } - /// Grabs __declspec(uuid()) off a type, or returns 0 if there is none. - static UuidAttr *GetUuidAttrOfType(QualType QT); + /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to + /// a single GUID. + static UuidAttr *GetUuidAttrOfType(QualType QT, + bool *HasMultipleGUIDsPtr = 0); // Iterators child_range children() { @@ -698,17 +748,18 @@ public: } }; -/// CXXThisExpr - Represents the "this" expression in C++, which is a -/// pointer to the object on which the current member function is +/// \brief Represents the \c this expression in C++. +/// +/// This is a pointer to the object on which the current member function is /// executing (C++ [expr.prim]p3). Example: /// -/// @code +/// \code /// class Foo { /// public: /// void bar(); /// void test() { this->bar(); } /// }; -/// @endcode +/// \endcode class CXXThisExpr : public Expr { SourceLocation Loc; bool Implicit : 1; @@ -742,10 +793,11 @@ public: child_range children() { return child_range(); } }; -/// CXXThrowExpr - [C++ 15] C++ Throw Expression. This handles -/// 'throw' and 'throw' assignment-expression. When -/// assignment-expression isn't present, Op will be null. +/// \brief A C++ throw-expression (C++ [except.throw]). /// +/// This handles 'throw' (for re-throwing the current exception) and +/// 'throw' assignment-expression. When assignment-expression isn't +/// present, Op will be null. class CXXThrowExpr : public Expr { Stmt *Op; SourceLocation ThrowLoc; @@ -755,8 +807,8 @@ class CXXThrowExpr : public Expr { friend class ASTStmtReader; public: - // Ty is the void type which is used as the result type of the - // exepression. The l is the location of the throw keyword. expr + // \p Ty is the void type which is used as the result type of the + // expression. The \p l is the location of the throw keyword. \p expr // can by null, if the optional expression to throw isn't present. CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l, bool IsThrownVariableInScope) : @@ -795,10 +847,11 @@ public: } }; -/// CXXDefaultArgExpr - C++ [dcl.fct.default]. This wraps up a -/// function call argument that was created from the corresponding -/// parameter's default argument, when the call did not explicitly -/// supply arguments for all of the parameters. +/// \brief A default argument (C++ [dcl.fct.default]). +/// +/// This wraps up a function call argument that was created from the +/// corresponding parameter's default argument, when the call did not +/// explicitly supply arguments for all of the parameters. class CXXDefaultArgExpr : public Expr { /// \brief The parameter whose default is being used. /// @@ -831,20 +884,17 @@ class CXXDefaultArgExpr : public Expr { public: CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {} - - // Param is the parameter whose default argument is used by this + // \p Param is the parameter whose default argument is used by this // expression. - static CXXDefaultArgExpr *Create(ASTContext &C, SourceLocation Loc, + static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc, ParmVarDecl *Param) { return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param); } - // Param is the parameter whose default argument is used by this - // expression, and SubExpr is the expression that will actually be used. - static CXXDefaultArgExpr *Create(ASTContext &C, - SourceLocation Loc, - ParmVarDecl *Param, - Expr *SubExpr); + // \p Param is the parameter whose default argument is used by this + // expression, and \p SubExpr is the expression that will actually be used. + static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc, + ParmVarDecl *Param, Expr *SubExpr); // Retrieve the parameter that the argument was created from. const ParmVarDecl *getParam() const { return Param.getPointer(); } @@ -866,8 +916,8 @@ public: /// used. SourceLocation getUsedLocation() const { return Loc; } - // Default argument expressions have no representation in the - // source, so they have an empty source range. + /// Default argument expressions have no representation in the + /// source, so they have an empty source range. SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); } SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); } @@ -884,7 +934,10 @@ public: friend class ASTStmtWriter; }; -/// \brief This wraps a use of a C++ default initializer (technically, +/// \brief A use of a default initializer in a constructor or in aggregate +/// initialization. +/// +/// This wraps a use of a C++ default initializer (technically, /// a brace-or-equal-initializer for a non-static data member) when it /// is implicitly used in a mem-initializer-list in a constructor /// (C++11 [class.base.init]p8) or in aggregate initialization @@ -896,24 +949,24 @@ class CXXDefaultInitExpr : public Expr { /// \brief The location where the default initializer expression was used. SourceLocation Loc; - CXXDefaultInitExpr(ASTContext &C, SourceLocation Loc, FieldDecl *Field, + CXXDefaultInitExpr(const ASTContext &C, SourceLocation Loc, FieldDecl *Field, QualType T); CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {} public: - // Field is the non-static data member whose default initializer is used - // by this expression. - static CXXDefaultInitExpr *Create(ASTContext &C, SourceLocation Loc, + /// \p Field is the non-static data member whose default initializer is used + /// by this expression. + static CXXDefaultInitExpr *Create(const ASTContext &C, SourceLocation Loc, FieldDecl *Field) { return new (C) CXXDefaultInitExpr(C, Loc, Field, Field->getType()); } - // Get the field whose initializer will be used. + /// \brief Get the field whose initializer will be used. FieldDecl *getField() { return Field; } const FieldDecl *getField() const { return Field; } - // Get the initialization expression that will be used. + /// \brief Get the initialization expression that will be used. const Expr *getExpr() const { return Field->getInClassInitializer(); } Expr *getExpr() { return Field->getInClassInitializer(); } @@ -931,16 +984,16 @@ public: friend class ASTStmtReader; }; -/// CXXTemporary - Represents a C++ temporary. +/// \brief Represents a C++ temporary. class CXXTemporary { - /// Destructor - The destructor that needs to be called. + /// \brief The destructor that needs to be called. const CXXDestructorDecl *Destructor; - CXXTemporary(const CXXDestructorDecl *destructor) + explicit CXXTemporary(const CXXDestructorDecl *destructor) : Destructor(destructor) { } public: - static CXXTemporary *Create(ASTContext &C, + static CXXTemporary *Create(const ASTContext &C, const CXXDestructorDecl *Destructor); const CXXDestructorDecl *getDestructor() const { return Destructor; } @@ -980,7 +1033,7 @@ public: CXXBindTemporaryExpr(EmptyShell Empty) : Expr(CXXBindTemporaryExprClass, Empty), Temp(0), SubExpr(0) {} - static CXXBindTemporaryExpr *Create(ASTContext &C, CXXTemporary *Temp, + static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp, Expr* SubExpr); CXXTemporary *getTemporary() { return Temp; } @@ -1019,7 +1072,7 @@ private: CXXConstructorDecl *Constructor; SourceLocation Loc; - SourceRange ParenRange; + SourceRange ParenOrBraceRange; unsigned NumArgs : 16; bool Elidable : 1; bool HadMultipleCandidates : 1; @@ -1029,7 +1082,7 @@ private: Stmt **Args; protected: - CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, + CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T, SourceLocation Loc, CXXConstructorDecl *d, bool elidable, ArrayRef Args, @@ -1037,7 +1090,7 @@ protected: bool ListInitialization, bool ZeroInitialization, ConstructionKind ConstructKind, - SourceRange ParenRange); + SourceRange ParenOrBraceRange); /// \brief Construct an empty C++ construction expression. CXXConstructExpr(StmtClass SC, EmptyShell Empty) @@ -1055,7 +1108,7 @@ public: ConstructKind(0), Args(0) { } - static CXXConstructExpr *Create(ASTContext &C, QualType T, + static CXXConstructExpr *Create(const ASTContext &C, QualType T, SourceLocation Loc, CXXConstructorDecl *D, bool Elidable, ArrayRef Args, @@ -1063,7 +1116,7 @@ public: bool ListInitialization, bool ZeroInitialization, ConstructionKind ConstructKind, - SourceRange ParenRange); + SourceRange ParenOrBraceRange); CXXConstructorDecl* getConstructor() const { return Constructor; } void setConstructor(CXXConstructorDecl *C) { Constructor = C; } @@ -1091,7 +1144,7 @@ public: ZeroInitialization = ZeroInit; } - /// \brief Determines whether this constructor is actually constructing + /// \brief Determine whether this constructor is actually constructing /// a base class (rather than a complete object). ConstructionKind getConstructionKind() const { return (ConstructionKind)ConstructKind; @@ -1111,7 +1164,7 @@ public: Expr **getArgs() const { return reinterpret_cast(Args); } unsigned getNumArgs() const { return NumArgs; } - /// getArg - Return the specified argument. + /// \brief Return the specified argument. Expr *getArg(unsigned Arg) { assert(Arg < NumArgs && "Arg access out of range!"); return cast(Args[Arg]); @@ -1121,7 +1174,7 @@ public: return cast(Args[Arg]); } - /// setArg - Set the specified argument. + /// \brief Set the specified argument. void setArg(unsigned Arg, Expr *ArgExpr) { assert(Arg < NumArgs && "Arg access out of range!"); Args[Arg] = ArgExpr; @@ -1129,8 +1182,8 @@ public: SourceLocation getLocStart() const LLVM_READONLY; SourceLocation getLocEnd() const LLVM_READONLY; - SourceRange getParenRange() const { return ParenRange; } - void setParenRange(SourceRange Range) { ParenRange = Range; } + SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; } + void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXConstructExprClass || @@ -1149,43 +1202,42 @@ public: /// notation (C++ [expr.type.conv]). /// /// Example: -/// @code +/// \code /// x = int(0.5); -/// @endcode +/// \endcode class CXXFunctionalCastExpr : public ExplicitCastExpr { - SourceLocation TyBeginLoc; + SourceLocation LParenLoc; SourceLocation RParenLoc; CXXFunctionalCastExpr(QualType ty, ExprValueKind VK, TypeSourceInfo *writtenTy, - SourceLocation tyBeginLoc, CastKind kind, - Expr *castExpr, unsigned pathSize, - SourceLocation rParenLoc) + CastKind kind, Expr *castExpr, unsigned pathSize, + SourceLocation lParenLoc, SourceLocation rParenLoc) : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind, castExpr, pathSize, writtenTy), - TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {} + LParenLoc(lParenLoc), RParenLoc(rParenLoc) {} explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize) : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { } public: - static CXXFunctionalCastExpr *Create(ASTContext &Context, QualType T, + static CXXFunctionalCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, TypeSourceInfo *Written, - SourceLocation TyBeginLoc, CastKind Kind, Expr *Op, const CXXCastPath *Path, + SourceLocation LPLoc, SourceLocation RPLoc); - static CXXFunctionalCastExpr *CreateEmpty(ASTContext &Context, + static CXXFunctionalCastExpr *CreateEmpty(const ASTContext &Context, unsigned PathSize); - SourceLocation getTypeBeginLoc() const { return TyBeginLoc; } - void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; } + SourceLocation getLParenLoc() const { return LParenLoc; } + void setLParenLoc(SourceLocation L) { LParenLoc = L; } SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceLocation getLocStart() const LLVM_READONLY { return TyBeginLoc; } - SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + SourceLocation getLocStart() const LLVM_READONLY; + SourceLocation getLocEnd() const LLVM_READONLY; static bool classof(const Stmt *T) { return T->getStmtClass() == CXXFunctionalCastExprClass; @@ -1200,21 +1252,21 @@ public: /// constructor to build a temporary object. With N == 1 arguments the /// functional cast expression will be represented by CXXFunctionalCastExpr. /// Example: -/// @code +/// \code /// struct X { X(int, float); } /// /// X create_X() { /// return X(1, 3.14f); // creates a CXXTemporaryObjectExpr /// }; -/// @endcode +/// \endcode class CXXTemporaryObjectExpr : public CXXConstructExpr { TypeSourceInfo *Type; public: - CXXTemporaryObjectExpr(ASTContext &C, CXXConstructorDecl *Cons, + CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons, TypeSourceInfo *Type, ArrayRef Args, - SourceRange parenRange, + SourceRange ParenOrBraceRange, bool HadMultipleCandidates, bool ListInitialization, bool ZeroInitialization); @@ -1244,26 +1296,35 @@ public: /// } /// \endcode /// -/// Lambda expressions can capture local variables, either by copying +/// C++11 lambda expressions can capture local variables, either by copying /// the values of those local variables at the time the function /// object is constructed (not when it is called!) or by holding a /// reference to the local variable. These captures can occur either /// implicitly or can be written explicitly between the square /// brackets ([...]) that start the lambda expression. +/// +/// C++1y introduces a new form of "capture" called an init-capture that +/// includes an initializing expression (rather than capturing a variable), +/// and which can never occur implicitly. class LambdaExpr : public Expr { enum { /// \brief Flag used by the Capture class to indicate that the given /// capture was implicit. Capture_Implicit = 0x01, - /// \brief Flag used by the Capture class to indciate that the + /// \brief Flag used by the Capture class to indicate that the /// given capture was by-copy. + /// + /// This includes the case of a non-reference init-capture. Capture_ByCopy = 0x02 }; /// \brief The source range that covers the lambda introducer ([...]). SourceRange IntroducerRange; + /// \brief The source location of this lambda's capture-default ('=' or '&'). + SourceLocation CaptureDefaultLoc; + /// \brief The number of captures. unsigned NumCaptures : 16; @@ -1297,9 +1358,10 @@ class LambdaExpr : public Expr { // array captures. public: - /// \brief Describes the capture of either a variable or 'this'. + /// \brief Describes the capture of a variable or of \c this, or of a + /// C++1y init-capture. class Capture { - llvm::PointerIntPair VarAndBits; + llvm::PointerIntPair DeclAndBits; SourceLocation Loc; SourceLocation EllipsisLoc; @@ -1307,15 +1369,17 @@ public: friend class ASTStmtWriter; public: - /// \brief Create a new capture. + /// \brief Create a new capture of a variable or of \c this. /// /// \param Loc The source location associated with this capture. /// - /// \param Kind The kind of capture (this, byref, bycopy). + /// \param Kind The kind of capture (this, byref, bycopy), which must + /// not be init-capture. /// /// \param Implicit Whether the capture was implicit or explicit. /// - /// \param Var The local variable being captured, or null if capturing this. + /// \param Var The local variable being captured, or null if capturing + /// \c this. /// /// \param EllipsisLoc The location of the ellipsis (...) for a /// capture that is a pack expansion, or an invalid source @@ -1327,36 +1391,43 @@ public: /// \brief Determine the kind of capture. LambdaCaptureKind getCaptureKind() const; - /// \brief Determine whether this capture handles the C++ 'this' + /// \brief Determine whether this capture handles the C++ \c this /// pointer. - bool capturesThis() const { return VarAndBits.getPointer() == 0; } + bool capturesThis() const { return DeclAndBits.getPointer() == 0; } /// \brief Determine whether this capture handles a variable. - bool capturesVariable() const { return VarAndBits.getPointer() != 0; } + bool capturesVariable() const { + return dyn_cast_or_null(DeclAndBits.getPointer()); + } + + /// \brief Determine whether this is an init-capture. + bool isInitCapture() const { + return capturesVariable() && getCapturedVar()->isInitCapture(); + } /// \brief Retrieve the declaration of the local variable being /// captured. /// - /// This operation is only valid if this capture does not capture - /// 'this'. - VarDecl *getCapturedVar() const { - assert(!capturesThis() && "No variable available for 'this' capture"); - return VarAndBits.getPointer(); + /// This operation is only valid if this capture is a variable capture + /// (other than a capture of \c this). + VarDecl *getCapturedVar() const { + assert(capturesVariable() && "No variable available for 'this' capture"); + return cast(DeclAndBits.getPointer()); } /// \brief Determine whether this was an implicit capture (not /// written between the square brackets introducing the lambda). - bool isImplicit() const { return VarAndBits.getInt() & Capture_Implicit; } + bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; } - /// \brief Determine whether this was an explicit capture, written - /// between the square brackets introducing the lambda. + /// \brief Determine whether this was an explicit capture (written + /// between the square brackets introducing the lambda). bool isExplicit() const { return !isImplicit(); } /// \brief Retrieve the source location of the capture. /// /// For an explicit capture, this returns the location of the /// explicit capture in the source. For an implicit capture, this - /// returns the location at which the variable or 'this' was first + /// returns the location at which the variable or \c this was first /// used. SourceLocation getLocation() const { return Loc; } @@ -1376,6 +1447,7 @@ private: /// \brief Construct a lambda expression. LambdaExpr(QualType T, SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault, + SourceLocation CaptureDefaultLoc, ArrayRef Captures, bool ExplicitParams, bool ExplicitResultType, @@ -1414,10 +1486,11 @@ private: public: /// \brief Construct a new lambda expression. - static LambdaExpr *Create(ASTContext &C, + static LambdaExpr *Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault, + SourceLocation CaptureDefaultLoc, ArrayRef Captures, bool ExplicitParams, bool ExplicitResultType, @@ -1429,14 +1502,20 @@ public: /// \brief Construct a new lambda expression that will be deserialized from /// an external source. - static LambdaExpr *CreateDeserialized(ASTContext &C, unsigned NumCaptures, + static LambdaExpr *CreateDeserialized(const ASTContext &C, + unsigned NumCaptures, unsigned NumArrayIndexVars); - + /// \brief Determine the default capture kind for this lambda. LambdaCaptureDefault getCaptureDefault() const { return static_cast(CaptureDefault); } + /// \brief Retrieve the location of this lambda's capture-default, if any. + SourceLocation getCaptureDefaultLoc() const { + return CaptureDefaultLoc; + } + /// \brief An iterator that walks over the captures of the lambda, /// both implicit and explicit. typedef const Capture *capture_iterator; @@ -1495,15 +1574,24 @@ public: /// brackets ([...]). SourceRange getIntroducerRange() const { return IntroducerRange; } - /// \brief Retrieve the class that corresponds to the lambda, which - /// stores the captures in its fields and provides the various - /// operations permitted on a lambda (copying, calling). + /// \brief Retrieve the class that corresponds to the lambda. + /// + /// This is the "closure type" (C++1y [expr.prim.lambda]), and stores the + /// captures in its fields and provides the various operations permitted + /// on a lambda (copying, calling). CXXRecordDecl *getLambdaClass() const; /// \brief Retrieve the function call operator associated with this /// lambda expression. CXXMethodDecl *getCallOperator() const; + /// \brief If this is a generic lambda expression, retrieve the template + /// parameter list associated with it, or else return null. + TemplateParameterList *getTemplateParameterList() const; + + /// \brief Whether this is a generic lambda. + bool isGenericLambda() const { return getTemplateParameterList(); } + /// \brief Retrieve the body of the lambda. CompoundStmt *getBody() const; @@ -1535,10 +1623,8 @@ public: friend class ASTStmtWriter; }; -/// CXXScalarValueInitExpr - [C++ 5.2.3p2] -/// Expression "T()" which creates a value-initialized rvalue of type -/// T, which is a non-class type. -/// +/// An expression "T()" which creates a value-initialized rvalue of type +/// T, which is a non-class type. See (C++98 [5.2.3p2]). class CXXScalarValueInitExpr : public Expr { SourceLocation RParenLoc; TypeSourceInfo *TypeInfo; @@ -1575,11 +1661,11 @@ public: child_range children() { return child_range(); } }; -/// @brief Represents a new-expression for memory allocation and constructor -// calls, e.g: "new CXXNewExpr(foo)". +/// \brief Represents a new-expression for memory allocation and constructor +/// calls, e.g: "new CXXNewExpr(foo)". class CXXNewExpr : public Expr { - // Contains an optional array size expression, an optional initialization - // expression, and any number of optional placement arguments, in that order. + /// Contains an optional array size expression, an optional initialization + /// expression, and any number of optional placement arguments, in that order. Stmt **SubExprs; /// \brief Points to the allocation function used. FunctionDecl *OperatorNew; @@ -1600,18 +1686,18 @@ class CXXNewExpr : public Expr { /// \brief Source-range of a paren-delimited initializer. SourceRange DirectInitRange; - // Was the usage ::new, i.e. is the global new to be used? + /// Was the usage ::new, i.e. is the global new to be used? bool GlobalNew : 1; - // Do we allocate an array? If so, the first SubExpr is the size expression. + /// Do we allocate an array? If so, the first SubExpr is the size expression. bool Array : 1; - // If this is an array allocation, does the usual deallocation - // function for the allocated type want to know the allocated size? + /// If this is an array allocation, does the usual deallocation + /// function for the allocated type want to know the allocated size? bool UsualArrayDeleteWantsSize : 1; - // The number of placement new arguments. + /// The number of placement new arguments. unsigned NumPlacementArgs : 13; - // What kind of initializer do we have? Could be none, parens, or braces. - // In storage, we distinguish between "none, and no initializer expr", and - // "none, but an implicit initializer expr". + /// What kind of initializer do we have? Could be none, parens, or braces. + /// In storage, we distinguish between "none, and no initializer expr", and + /// "none, but an implicit initializer expr". unsigned StoredInitializationStyle : 2; friend class ASTStmtReader; @@ -1623,7 +1709,7 @@ public: ListInit ///< New-expression has a C++11 list-initializer. }; - CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, + CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew, FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize, ArrayRef placementArgs, SourceRange typeIdParens, Expr *arraySize, @@ -1633,8 +1719,8 @@ public: explicit CXXNewExpr(EmptyShell Shell) : Expr(CXXNewExprClass, Shell), SubExprs(0) { } - void AllocateArgsArray(ASTContext &C, bool isArray, unsigned numPlaceArgs, - bool hasInitializer); + void AllocateArgsArray(const ASTContext &C, bool isArray, + unsigned numPlaceArgs, bool hasInitializer); QualType getAllocatedType() const { assert(getType()->isPointerType()); @@ -1646,15 +1732,17 @@ public: } /// \brief True if the allocation result needs to be null-checked. - /// C++0x [expr.new]p13: + /// + /// C++11 [expr.new]p13: /// If the allocation function returns null, initialization shall /// not be done, the deallocation function shall not be called, /// and the value of the new-expression shall be null. + /// /// An allocation function is not allowed to return null unless it /// has a non-throwing exception-specification. The '03 rule is /// identical except that the definition of a non-throwing /// exception specification is just "is it throw()?". - bool shouldNullCheckAllocation(ASTContext &Ctx) const; + bool shouldNullCheckAllocation(const ASTContext &Ctx) const; FunctionDecl *getOperatorNew() const { return OperatorNew; } void setOperatorNew(FunctionDecl *D) { OperatorNew = D; } @@ -1706,7 +1794,7 @@ public: return hasInitializer() ? cast(SubExprs[Array]) : 0; } - /// \brief Returns the CXXConstructExpr from this new-expression, or NULL. + /// \brief Returns the CXXConstructExpr from this new-expression, or null. const CXXConstructExpr* getConstructExpr() const { return dyn_cast_or_null(getInitializer()); } @@ -1768,22 +1856,22 @@ public: /// \brief Represents a \c delete expression for memory deallocation and /// destructor calls, e.g. "delete[] pArray". class CXXDeleteExpr : public Expr { - // Points to the operator delete overload that is used. Could be a member. + /// Points to the operator delete overload that is used. Could be a member. FunctionDecl *OperatorDelete; - // The pointer expression to be deleted. + /// The pointer expression to be deleted. Stmt *Argument; - // Location of the expression. + /// Location of the expression. SourceLocation Loc; - // Is this a forced global delete, i.e. "::delete"? + /// Is this a forced global delete, i.e. "::delete"? bool GlobalDelete : 1; - // Is this the array form of delete, i.e. "delete[]"? + /// Is this the array form of delete, i.e. "delete[]"? bool ArrayForm : 1; - // ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied - // to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm - // will be true). + /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied + /// to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm + /// will be true). bool ArrayFormAsWritten : 1; - // Does the usual deallocation function for the element type require - // a size_t argument? + /// Does the usual deallocation function for the element type require + /// a size_t argument? bool UsualArrayDeleteWantsSize : 1; public: CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm, @@ -1816,9 +1904,10 @@ public: Expr *getArgument() { return cast(Argument); } const Expr *getArgument() const { return cast(Argument); } - /// \brief Retrieve the type being destroyed. If the type being - /// destroyed is a dependent type which may or may not be a pointer, - /// return an invalid type. + /// \brief Retrieve the type being destroyed. + /// + /// If the type being destroyed is a dependent type which may or may not + /// be a pointer, return an invalid type. QualType getDestroyedType() const; SourceLocation getLocStart() const LLVM_READONLY { return Loc; } @@ -1918,7 +2007,7 @@ class CXXPseudoDestructorExpr : public Expr { friend class ASTStmtReader; public: - CXXPseudoDestructorExpr(ASTContext &Context, + CXXPseudoDestructorExpr(const ASTContext &Context, Expr *Base, bool isArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, TypeSourceInfo *ScopeType, @@ -1935,7 +2024,7 @@ public: /// \brief Determines whether this member expression actually had /// a C++ nested-name-specifier prior to the name of the member, e.g., /// x->Base::foo. - bool hasQualifier() const { return QualifierLoc; } + bool hasQualifier() const { return QualifierLoc.hasQualifier(); } /// \brief Retrieves the nested-name-specifier that qualifies the type name, /// with source-location information. @@ -1943,7 +2032,7 @@ public: /// \brief If the member name was qualified, retrieves the /// nested-name-specifier that precedes the member name. Otherwise, returns - /// NULL. + /// null. NestedNameSpecifier *getQualifier() const { return QualifierLoc.getNestedNameSpecifier(); } @@ -1978,7 +2067,7 @@ public: /// /// This type-source information is available for non-dependent /// pseudo-destructor expressions and some dependent pseudo-destructor - /// expressions. Returns NULL if we only have the identifier for a + /// expressions. Returns null if we only have the identifier for a /// dependent pseudo-destructor expression. TypeSourceInfo *getDestroyedTypeInfo() const { return DestroyedType.getTypeSourceInfo(); @@ -2025,23 +2114,23 @@ public: /// implementation of TR1/C++11 type trait templates. /// /// Example: -/// @code +/// \code /// __is_pod(int) == true /// __is_enum(std::string) == false -/// @endcode +/// \endcode class UnaryTypeTraitExpr : public Expr { - /// UTT - The trait. A UnaryTypeTrait enum in MSVC compat unsigned. + /// \brief The trait. A UnaryTypeTrait enum in MSVC compatible unsigned. unsigned UTT : 31; /// The value of the type trait. Unspecified if dependent. bool Value : 1; - /// Loc - The location of the type trait keyword. + /// \brief The location of the type trait keyword. SourceLocation Loc; - /// RParen - The location of the closing paren. + /// \brief The location of the closing paren. SourceLocation RParen; - /// The type being queried. + /// \brief The type being queried. TypeSourceInfo *QueriedType; public: @@ -2083,26 +2172,26 @@ public: /// implementation of TR1/C++11 type trait templates. /// /// Example: -/// @code +/// \code /// __is_base_of(Base, Derived) == true -/// @endcode +/// \endcode class BinaryTypeTraitExpr : public Expr { - /// BTT - The trait. A BinaryTypeTrait enum in MSVC compat unsigned. + /// \brief The trait. A BinaryTypeTrait enum in MSVC compatible unsigned. unsigned BTT : 8; /// The value of the type trait. Unspecified if dependent. bool Value : 1; - /// Loc - The location of the type trait keyword. + /// \brief The location of the type trait keyword. SourceLocation Loc; - /// RParen - The location of the closing paren. + /// \brief The location of the closing paren. SourceLocation RParen; - /// The lhs type being queried. + /// \brief The lhs type being queried. TypeSourceInfo *LhsType; - /// The rhs type being queried. + /// \brief The rhs type being queried. TypeSourceInfo *RhsType; public: @@ -2184,13 +2273,14 @@ class TypeTraitExpr : public Expr { public: /// \brief Create a new type trait expression. - static TypeTraitExpr *Create(ASTContext &C, QualType T, SourceLocation Loc, - TypeTrait Kind, + static TypeTraitExpr *Create(const ASTContext &C, QualType T, + SourceLocation Loc, TypeTrait Kind, ArrayRef Args, SourceLocation RParenLoc, bool Value); - static TypeTraitExpr *CreateDeserialized(ASTContext &C, unsigned NumArgs); + static TypeTraitExpr *CreateDeserialized(const ASTContext &C, + unsigned NumArgs); /// \brief Determine which type trait this expression uses. TypeTrait getTrait() const { @@ -2249,10 +2339,10 @@ public: /// __array_rank and __array_extent. /// /// Example: -/// @code +/// \code /// __array_rank(int[10][20]) == 2 /// __array_extent(int, 1) == 20 -/// @endcode +/// \endcode class ArrayTypeTraitExpr : public Expr { virtual void anchor(); @@ -2319,12 +2409,12 @@ public: /// \brief An expression trait intrinsic. /// /// Example: -/// @code +/// \code /// __is_lvalue_expr(std::cout) == true /// __is_lvalue_expr(1) == false -/// @endcode +/// \endcode class ExpressionTraitExpr : public Expr { - /// \brief The trait. A ExpressionTrait enum in MSVC compat unsigned. + /// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned. unsigned ET : 31; /// \brief The value of the type trait. Unspecified if dependent. bool Value : 1; @@ -2403,7 +2493,7 @@ protected: return const_cast(this)->getTemplateKWAndArgsInfo(); } - OverloadExpr(StmtClass K, ASTContext &C, + OverloadExpr(StmtClass K, const ASTContext &C, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, @@ -2417,7 +2507,7 @@ protected: : Expr(K, Empty), QualifierLoc(), Results(0), NumResults(0), HasTemplateKWAndArgsInfo(false) { } - void initializeResults(ASTContext &C, + void initializeResults(const ASTContext &C, UnresolvedSetIterator Begin, UnresolvedSetIterator End); @@ -2428,7 +2518,7 @@ public: bool HasFormOfMemberPointer; }; - /// Finds the overloaded expression in the given expression of + /// \brief Finds the overloaded expression in the given expression \p E of /// OverloadTy. /// /// \return the expression (which must be there) and true if it has @@ -2561,10 +2651,11 @@ public: /// parsing but could not resolve to a specific declaration. /// /// This arises in several ways: -/// * we might be waiting for argument-dependent lookup -/// * the name might resolve to an overloaded function +/// * we might be waiting for argument-dependent lookup; +/// * the name might resolve to an overloaded function; /// and eventually: -/// * the lookup might have included a function template +/// * the lookup might have included a function template. +/// /// These never include UnresolvedUsingValueDecls, which are always class /// members and therefore appear only in UnresolvedMemberLookupExprs. class UnresolvedLookupExpr : public OverloadExpr { @@ -2584,7 +2675,7 @@ class UnresolvedLookupExpr : public OverloadExpr { /// against the qualified-lookup bits. CXXRecordDecl *NamingClass; - UnresolvedLookupExpr(ASTContext &C, + UnresolvedLookupExpr(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, @@ -2606,7 +2697,7 @@ class UnresolvedLookupExpr : public OverloadExpr { friend class ASTStmtReader; public: - static UnresolvedLookupExpr *Create(ASTContext &C, + static UnresolvedLookupExpr *Create(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, @@ -2618,7 +2709,7 @@ public: ADL, Overloaded, 0, Begin, End); } - static UnresolvedLookupExpr *Create(ASTContext &C, + static UnresolvedLookupExpr *Create(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, @@ -2628,7 +2719,7 @@ public: UnresolvedSetIterator Begin, UnresolvedSetIterator End); - static UnresolvedLookupExpr *CreateEmpty(ASTContext &C, + static UnresolvedLookupExpr *CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); @@ -2671,7 +2762,7 @@ public: /// DependentScopeDeclRefExpr node is used only within C++ templates when /// the qualification (e.g., X::) refers to a dependent type. In /// this case, X::value cannot resolve to a declaration because the -/// declaration will differ from on instantiation of X to the +/// declaration will differ from one instantiation of X to the /// next. Therefore, DependentScopeDeclRefExpr keeps track of the /// qualifier (X::) and the name of the entity being referenced /// ("value"). Such expressions will instantiate to a DeclRefExpr once the @@ -2681,7 +2772,7 @@ class DependentScopeDeclRefExpr : public Expr { /// declaration name. NestedNameSpecifierLoc QualifierLoc; - /// The name of the entity we will be referencing. + /// \brief The name of the entity we will be referencing. DeclarationNameInfo NameInfo; /// \brief Whether the name includes info for explicit template @@ -2706,13 +2797,13 @@ class DependentScopeDeclRefExpr : public Expr { const TemplateArgumentListInfo *Args); public: - static DependentScopeDeclRefExpr *Create(ASTContext &C, + static DependentScopeDeclRefExpr *Create(const ASTContext &C, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs); - static DependentScopeDeclRefExpr *CreateEmpty(ASTContext &C, + static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); @@ -2723,13 +2814,14 @@ public: DeclarationName getDeclName() const { return NameInfo.getName(); } /// \brief Retrieve the location of the name within the expression. + /// + /// For example, in "X::value" this is the location of "value". SourceLocation getLocation() const { return NameInfo.getLoc(); } /// \brief Retrieve the nested-name-specifier that qualifies the /// name, with source location information. NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } - /// \brief Retrieve the nested-name-specifier that qualifies this /// declaration. NestedNameSpecifier *getQualifier() const { @@ -2779,6 +2871,7 @@ public: } /// \brief Retrieves the optional explicit template arguments. + /// /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { @@ -2800,6 +2893,8 @@ public: return getExplicitTemplateArgs().NumTemplateArgs; } + /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr, + /// and differs from getLocation().getStart(). SourceLocation getLocStart() const LLVM_READONLY { return QualifierLoc.getBeginLoc(); } @@ -2819,7 +2914,7 @@ public: friend class ASTStmtWriter; }; -/// Represents an expression --- generally a full-expression --- which +/// Represents an expression -- generally a full-expression -- that /// introduces cleanups to be run at the end of the sub-expression's /// evaluation. The most common source of expression-introduced /// cleanups is temporary objects in C++, but several other kinds of @@ -2852,10 +2947,10 @@ private: friend class ASTStmtReader; public: - static ExprWithCleanups *Create(ASTContext &C, EmptyShell empty, + static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty, unsigned numObjects); - static ExprWithCleanups *Create(ASTContext &C, Expr *subexpr, + static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr, ArrayRef objects); ArrayRef getObjects() const { @@ -2872,7 +2967,7 @@ public: Expr *getSubExpr() { return cast(SubExpr); } const Expr *getSubExpr() const { return cast(SubExpr); } - /// setSubExpr - As with any mutator of the AST, be very careful + /// As with any mutator of the AST, be very careful /// when modifying an existing AST to preserve its invariants. void setSubExpr(Expr *E) { SubExpr = E; } @@ -2935,13 +3030,13 @@ class CXXUnresolvedConstructExpr : public Expr { friend class ASTStmtReader; public: - static CXXUnresolvedConstructExpr *Create(ASTContext &C, + static CXXUnresolvedConstructExpr *Create(const ASTContext &C, TypeSourceInfo *Type, SourceLocation LParenLoc, ArrayRef Args, SourceLocation RParenLoc); - static CXXUnresolvedConstructExpr *CreateEmpty(ASTContext &C, + static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &C, unsigned NumArgs); /// \brief Retrieve the type that is being constructed, as specified @@ -2993,7 +3088,10 @@ public: } SourceLocation getLocStart() const LLVM_READONLY; - SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + assert(RParenLoc.isValid() || NumArgs == 1); + return RParenLoc.isValid() ? RParenLoc : getArg(0)->getLocEnd(); + } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXUnresolvedConstructExprClass; @@ -3047,6 +3145,7 @@ class CXXDependentScopeMemberExpr : public Expr { /// \brief The member to which this member expression refers, which /// can be name, overloaded operator, or destructor. + /// /// FIXME: could also be a template-id DeclarationNameInfo MemberNameInfo; @@ -3061,36 +3160,32 @@ class CXXDependentScopeMemberExpr : public Expr { ->getTemplateKWAndArgsInfo(); } - CXXDependentScopeMemberExpr(ASTContext &C, - Expr *Base, QualType BaseType, bool IsArrow, - SourceLocation OperatorLoc, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - NamedDecl *FirstQualifierFoundInScope, - DeclarationNameInfo MemberNameInfo, - const TemplateArgumentListInfo *TemplateArgs); + CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base, + QualType BaseType, bool IsArrow, + SourceLocation OperatorLoc, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, + NamedDecl *FirstQualifierFoundInScope, + DeclarationNameInfo MemberNameInfo, + const TemplateArgumentListInfo *TemplateArgs); public: - CXXDependentScopeMemberExpr(ASTContext &C, - Expr *Base, QualType BaseType, - bool IsArrow, + CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base, + QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo); static CXXDependentScopeMemberExpr * - Create(ASTContext &C, - Expr *Base, QualType BaseType, bool IsArrow, - SourceLocation OperatorLoc, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - NamedDecl *FirstQualifierFoundInScope, + Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, + SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs); static CXXDependentScopeMemberExpr * - CreateEmpty(ASTContext &C, bool HasTemplateKWAndArgsInfo, + CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); /// \brief True if this is an implicit access, i.e. one in which the @@ -3197,6 +3292,7 @@ public: } /// \brief Retrieves the optional explicit template arguments. + /// /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { @@ -3259,11 +3355,13 @@ public: /// produced a set of overloaded functions. /// /// The member access may be explicit or implicit: +/// \code /// struct A { /// int a, b; /// int explicitAccess() { return this->a + this->A::b; } /// int implicitAccess() { return a + A::b; } /// }; +/// \endcode /// /// In the final AST, an explicit access always becomes a MemberExpr. /// An implicit access may become either a MemberExpr or a @@ -3278,17 +3376,18 @@ class UnresolvedMemberExpr : public OverloadExpr { bool HasUnresolvedUsing : 1; /// \brief The expression for the base pointer or class reference, - /// e.g., the \c x in x.f. This can be null if this is an 'unbased' - /// member expression + /// e.g., the \c x in x.f. + /// + /// This can be null if this is an 'unbased' member expression. Stmt *Base; - /// \brief The type of the base expression; never null. + /// \brief The type of the base expression; never null. QualType BaseType; /// \brief The location of the '->' or '.' operator. SourceLocation OperatorLoc; - UnresolvedMemberExpr(ASTContext &C, bool HasUnresolvedUsing, + UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, @@ -3305,7 +3404,7 @@ class UnresolvedMemberExpr : public OverloadExpr { public: static UnresolvedMemberExpr * - Create(ASTContext &C, bool HasUnresolvedUsing, + Create(const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, @@ -3315,12 +3414,13 @@ public: UnresolvedSetIterator Begin, UnresolvedSetIterator End); static UnresolvedMemberExpr * - CreateEmpty(ASTContext &C, bool HasTemplateKWAndArgsInfo, + CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); - /// \brief True if this is an implicit access, i.e. one in which the - /// member being accessed was not written in the source. The source - /// location of the operator is invalid in this case. + /// \brief True if this is an implicit access, i.e., one in which the + /// member being accessed was not written in the source. + /// + /// The source location of the operator is invalid in this case. bool isImplicitAccess() const; /// \brief Retrieve the base object of this member expressions, @@ -3347,7 +3447,7 @@ public: /// \brief Retrieve the location of the '->' or '.' operator. SourceLocation getOperatorLoc() const { return OperatorLoc; } - /// \brief Retrieves the naming class of this lookup. + /// \brief Retrieve the naming class of this lookup. CXXRecordDecl *getNamingClass() const; /// \brief Retrieve the full name info for the member that this expression @@ -3362,6 +3462,10 @@ public: // expression refers to. SourceLocation getMemberLoc() const { return getNameLoc(); } + // \brief Return the preferred location (the member name) for the arrow when + // diagnosing a problem with this expression. + SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); } + SourceLocation getLocStart() const LLVM_READONLY { if (!isImplicitAccess()) return Base->getLocStart(); @@ -3386,7 +3490,7 @@ public: } }; -/// \brief Represents a C++0x noexcept expression (C++ [expr.unary.noexcept]). +/// \brief Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]). /// /// The noexcept expression tests whether a given expression might throw. Its /// result is a boolean constant. @@ -3428,7 +3532,7 @@ public: child_range children() { return child_range(&Operand, &Operand + 1); } }; -/// \brief Represents a C++0x pack expansion that produces a sequence of +/// \brief Represents a C++11 pack expansion that produces a sequence of /// expressions. /// /// A pack expansion expression contains a pattern (which itself is an @@ -3527,7 +3631,7 @@ inline ASTTemplateKWAndArgsInfo *OverloadExpr::getTemplateKWAndArgsInfo() { /// }; /// \endcode class SizeOfPackExpr : public Expr { - /// \brief The location of the 'sizeof' keyword. + /// \brief The location of the \c sizeof keyword. SourceLocation OperatorLoc; /// \brief The location of the name of the parameter pack. @@ -3550,7 +3654,7 @@ class SizeOfPackExpr : public Expr { friend class ASTStmtWriter; public: - /// \brief Creates a value-dependent expression that computes the length of + /// \brief Create a value-dependent expression that computes the length of /// the given parameter pack. SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc) @@ -3561,7 +3665,7 @@ public: OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), Length(0), Pack(Pack) { } - /// \brief Creates an expression that computes the length of + /// \brief Create an expression that computes the length of /// the given parameter pack, which is already known. SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc, @@ -3744,11 +3848,11 @@ class FunctionParmPackExpr : public Expr { friend class ASTStmtReader; public: - static FunctionParmPackExpr *Create(ASTContext &Context, QualType T, + static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T, ParmVarDecl *ParamPack, SourceLocation NameLoc, ArrayRef Params); - static FunctionParmPackExpr *CreateEmpty(ASTContext &Context, + static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context, unsigned NumParams); /// \brief Get the parameter pack which this expression refers to. @@ -3779,7 +3883,7 @@ public: child_range children() { return child_range(); } }; -/// \brief Represents a prvalue temporary that written into memory so that +/// \brief Represents a prvalue temporary that is written into memory so that /// a reference can bind to it. /// /// Prvalue expressions are materialized when they need to have an address @@ -3795,30 +3899,60 @@ public: /// binds to the temporary. \c MaterializeTemporaryExprs are always glvalues /// (either an lvalue or an xvalue, depending on the kind of reference binding /// to it), maintaining the invariant that references always bind to glvalues. +/// +/// Reference binding and copy-elision can both extend the lifetime of a +/// temporary. When either happens, the expression will also track the +/// declaration which is responsible for the lifetime extension. class MaterializeTemporaryExpr : public Expr { +public: /// \brief The temporary-generating expression whose value will be /// materialized. Stmt *Temporary; + /// \brief The declaration which lifetime-extended this reference, if any. + /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl. + const ValueDecl *ExtendingDecl; + friend class ASTStmtReader; friend class ASTStmtWriter; public: MaterializeTemporaryExpr(QualType T, Expr *Temporary, - bool BoundToLvalueReference) + bool BoundToLvalueReference, + const ValueDecl *ExtendedBy) : Expr(MaterializeTemporaryExprClass, T, BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary, Temporary->isTypeDependent(), Temporary->isValueDependent(), Temporary->isInstantiationDependent(), Temporary->containsUnexpandedParameterPack()), - Temporary(Temporary) { } + Temporary(Temporary), ExtendingDecl(ExtendedBy) { + } MaterializeTemporaryExpr(EmptyShell Empty) : Expr(MaterializeTemporaryExprClass, Empty) { } /// \brief Retrieve the temporary-generating subexpression whose value will /// be materialized into a glvalue. - Expr *GetTemporaryExpr() const { return reinterpret_cast(Temporary); } + Expr *GetTemporaryExpr() const { return static_cast(Temporary); } + + /// \brief Retrieve the storage duration for the materialized temporary. + StorageDuration getStorageDuration() const { + if (!ExtendingDecl) + return SD_FullExpression; + // FIXME: This is not necessarily correct for a temporary materialized + // within a default initializer. + if (isa(ExtendingDecl)) + return SD_Automatic; + return cast(ExtendingDecl)->getStorageDuration(); + } + + /// \brief Get the declaration which triggered the lifetime-extension of this + /// temporary, if any. + const ValueDecl *getExtendingDecl() const { return ExtendingDecl; } + + void setExtendingDecl(const ValueDecl *ExtendedBy) { + ExtendingDecl = ExtendedBy; + } /// \brief Determine whether this materialized temporary is bound to an /// lvalue reference; otherwise, it's bound to an rvalue reference. diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h b/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h index a94c69a..aeb55da 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h @@ -143,12 +143,13 @@ class ObjCArrayLiteral : public Expr { : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {} public: - static ObjCArrayLiteral *Create(ASTContext &C, + static ObjCArrayLiteral *Create(const ASTContext &C, ArrayRef Elements, QualType T, ObjCMethodDecl * Method, SourceRange SR); - static ObjCArrayLiteral *CreateEmpty(ASTContext &C, unsigned NumElements); + static ObjCArrayLiteral *CreateEmpty(const ASTContext &C, + unsigned NumElements); SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } @@ -289,13 +290,13 @@ class ObjCDictionaryLiteral : public Expr { } public: - static ObjCDictionaryLiteral *Create(ASTContext &C, + static ObjCDictionaryLiteral *Create(const ASTContext &C, ArrayRef VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *method, SourceRange SR); - static ObjCDictionaryLiteral *CreateEmpty(ASTContext &C, + static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C, unsigned NumElements, bool HasPackExpansions); @@ -807,7 +808,7 @@ public: explicit ObjCSubscriptRefExpr(EmptyShell Empty) : Expr(ObjCSubscriptRefExprClass, Empty) {} - static ObjCSubscriptRefExpr *Create(ASTContext &C, + static ObjCSubscriptRefExpr *Create(const ASTContext &C, Expr *base, Expr *key, QualType T, ObjCMethodDecl *getMethod, @@ -1003,13 +1004,13 @@ class ObjCMessageExpr : public Expr { return getNumSelectorLocs(); } - static ObjCMessageExpr *alloc(ASTContext &C, + static ObjCMessageExpr *alloc(const ASTContext &C, ArrayRef Args, SourceLocation RBraceLoc, ArrayRef SelLocs, Selector Sel, SelectorLocationsKind &SelLocsK); - static ObjCMessageExpr *alloc(ASTContext &C, + static ObjCMessageExpr *alloc(const ASTContext &C, unsigned NumArgs, unsigned NumStoredSelLocs); @@ -1051,7 +1052,7 @@ public: /// \param Args The message send arguments. /// /// \param RBracLoc The location of the closing square bracket ']'. - static ObjCMessageExpr *Create(ASTContext &Context, QualType T, + static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, @@ -1087,7 +1088,7 @@ public: /// \param Args The message send arguments. /// /// \param RBracLoc The location of the closing square bracket ']'. - static ObjCMessageExpr *Create(ASTContext &Context, QualType T, + static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, TypeSourceInfo *Receiver, @@ -1121,7 +1122,7 @@ public: /// \param Args The message send arguments. /// /// \param RBracLoc The location of the closing square bracket ']'. - static ObjCMessageExpr *Create(ASTContext &Context, QualType T, + static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, Expr *Receiver, @@ -1139,7 +1140,7 @@ public: /// /// \param NumArgs The number of message arguments, not including /// the receiver. - static ObjCMessageExpr *CreateEmpty(ASTContext &Context, + static ObjCMessageExpr *CreateEmpty(const ASTContext &Context, unsigned NumArgs, unsigned NumStoredSelLocs); diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h index 81fcf24..b077426 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h @@ -329,7 +329,12 @@ public: /// \brief Whether this pointer is non-NULL. /// /// This operation does not require the AST node to be deserialized. - operator bool() const { return Ptr != 0; } + LLVM_EXPLICIT operator bool() const { return Ptr != 0; } + + /// \brief Whether this pointer is non-NULL. + /// + /// This operation does not require the AST node to be deserialized. + bool isValid() const { return Ptr != 0; } /// \brief Whether this pointer is currently stored as an offset. bool isOffset() const { return Ptr & 0x01; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/GlobalDecl.h b/contrib/llvm/tools/clang/include/clang/AST/GlobalDecl.h index c43e44c..54c9d88 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/GlobalDecl.h +++ b/contrib/llvm/tools/clang/include/clang/AST/GlobalDecl.h @@ -41,6 +41,7 @@ public: GlobalDecl(const VarDecl *D) { Init(D);} GlobalDecl(const FunctionDecl *D) { Init(D); } GlobalDecl(const BlockDecl *D) { Init(D); } + GlobalDecl(const CapturedDecl *D) { Init(D); } GlobalDecl(const ObjCMethodDecl *D) { Init(D); } GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) diff --git a/contrib/llvm/tools/clang/include/clang/AST/LambdaMangleContext.h b/contrib/llvm/tools/clang/include/clang/AST/LambdaMangleContext.h deleted file mode 100644 index bbaee26..0000000 --- a/contrib/llvm/tools/clang/include/clang/AST/LambdaMangleContext.h +++ /dev/null @@ -1,38 +0,0 @@ -//===--- LambdaMangleContext.h - Context for mangling lambdas ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the LambdaMangleContext interface, which keeps track of -// the Itanium C++ ABI mangling numbers for lambda expressions. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LAMBDAMANGLECONTEXT_H -#define LLVM_CLANG_LAMBDAMANGLECONTEXT_H - -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" - -namespace clang { - -class CXXMethodDecl; -class FunctionProtoType; - -/// \brief Keeps track of the mangled names of lambda expressions within a -/// particular context. -class LambdaMangleContext : public RefCountedBase { - llvm::DenseMap ManglingNumbers; - -public: - /// \brief Retrieve the mangling number of a new lambda expression with the - /// given call operator within this lambda context. - unsigned getManglingNumber(CXXMethodDecl *CallOperator); -}; - -} // end namespace clang -#endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/Mangle.h b/contrib/llvm/tools/clang/include/clang/AST/Mangle.h index b6d22cf..c4d0d22 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Mangle.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Mangle.h @@ -19,6 +19,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" namespace clang { @@ -64,18 +65,29 @@ private: /// MangleContext - Context for tracking state which persists across multiple /// calls to the C++ name mangler. class MangleContext { +public: + enum ManglerKind { + MK_Itanium, + MK_Microsoft + }; + +private: virtual void anchor(); ASTContext &Context; DiagnosticsEngine &Diags; + const ManglerKind Kind; llvm::DenseMap GlobalBlockIds; llvm::DenseMap LocalBlockIds; - + public: + ManglerKind getKind() const { return Kind; } + explicit MangleContext(ASTContext &Context, - DiagnosticsEngine &Diags) - : Context(Context), Diags(Diags) { } + DiagnosticsEngine &Diags, + ManglerKind Kind) + : Context(Context), Diags(Diags), Kind(Kind) {} virtual ~MangleContext() { } @@ -96,8 +108,12 @@ public: /// @name Mangler Entry Points /// @{ - virtual bool shouldMangleDeclName(const NamedDecl *D) = 0; - virtual void mangleName(const NamedDecl *D, raw_ostream &)=0; + bool shouldMangleDeclName(const NamedDecl *D); + virtual bool shouldMangleCXXName(const NamedDecl *D) = 0; + + // FIXME: consider replacing raw_ostream & with something like SmallString &. + void mangleName(const NamedDecl *D, raw_ostream &); + virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0; virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &) = 0; @@ -106,13 +122,6 @@ public: raw_ostream &) = 0; virtual void mangleReferenceTemporary(const VarDecl *D, raw_ostream &) = 0; - virtual void mangleCXXVTable(const CXXRecordDecl *RD, - raw_ostream &) = 0; - virtual void mangleCXXVTT(const CXXRecordDecl *RD, - raw_ostream &) = 0; - virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, - const CXXRecordDecl *Type, - raw_ostream &) = 0; virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0; virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, @@ -129,36 +138,78 @@ public: const BlockDecl *BD, raw_ostream &Out); void mangleBlock(const DeclContext *DC, const BlockDecl *BD, raw_ostream &Out); - // Do the right thing. - void mangleBlock(const BlockDecl *BD, raw_ostream &Out, - const NamedDecl *ID=0); - void mangleObjCMethodName(const ObjCMethodDecl *MD, - raw_ostream &); + void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &); - // This is pretty lame. - virtual void mangleItaniumGuardVariable(const VarDecl *D, - raw_ostream &) { - llvm_unreachable("Target does not support mangling guard variables"); - } - // FIXME: Revisit this once we know what we need to do for MSVC compatibility. + virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0; + + virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0; + + virtual void mangleDynamicAtExitDestructor(const VarDecl *D, + raw_ostream &) = 0; + + /// Generates a unique string for an externally visible type for use with TBAA + /// or type uniquing. + /// TODO: Extend this to internal types by generating names that are unique + /// across translation units so it can be used with LTO. + virtual void mangleTypeName(QualType T, raw_ostream &) = 0; + + /// @} +}; + +class ItaniumMangleContext : public MangleContext { +public: + explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D) + : MangleContext(C, D, MK_Itanium) {} + + virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0; + virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0; + virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, + const CXXRecordDecl *Type, + raw_ostream &) = 0; virtual void mangleItaniumThreadLocalInit(const VarDecl *D, - raw_ostream &) { - llvm_unreachable("Target does not support mangling thread_local variables"); - } + raw_ostream &) = 0; virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D, - raw_ostream &) { - llvm_unreachable("Target does not support mangling thread_local variables"); + raw_ostream &) = 0; + + static bool classof(const MangleContext *C) { + return C->getKind() == MK_Itanium; } - /// @} + static ItaniumMangleContext *create(ASTContext &Context, + DiagnosticsEngine &Diags); }; -MangleContext *createItaniumMangleContext(ASTContext &Context, - DiagnosticsEngine &Diags); -MangleContext *createMicrosoftMangleContext(ASTContext &Context, - DiagnosticsEngine &Diags); +class MicrosoftMangleContext : public MangleContext { +public: + explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D) + : MangleContext(C, D, MK_Microsoft) {} + + /// \brief Mangle vftable symbols. Only a subset of the bases along the path + /// to the vftable are included in the name. It's up to the caller to pick + /// them correctly. + virtual void mangleCXXVFTable(const CXXRecordDecl *Derived, + ArrayRef BasePath, + raw_ostream &Out) = 0; + + /// \brief Mangle vbtable symbols. Only a subset of the bases along the path + /// to the vbtable are included in the name. It's up to the caller to pick + /// them correctly. + virtual void mangleCXXVBTable(const CXXRecordDecl *Derived, + ArrayRef BasePath, + raw_ostream &Out) = 0; + + virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, + uint64_t OffsetInVFTable, + raw_ostream &) = 0; + static bool classof(const MangleContext *C) { + return C->getKind() == MK_Microsoft; + } + + static MicrosoftMangleContext *create(ASTContext &Context, + DiagnosticsEngine &Diags); +}; } #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/MangleNumberingContext.h b/contrib/llvm/tools/clang/include/clang/AST/MangleNumberingContext.h new file mode 100644 index 0000000..5a227f2 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/MangleNumberingContext.h @@ -0,0 +1,59 @@ +//=== MangleNumberingContext.h - Context for mangling numbers ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the LambdaBlockMangleContext interface, which keeps track +// of the Itanium C++ ABI mangling numbers for lambda expressions and block +// literals. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_MANGLENUMBERINGCONTEXT_H +#define LLVM_CLANG_MANGLENUMBERINGCONTEXT_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" + +namespace clang { + +class BlockDecl; +class CXXMethodDecl; +class IdentifierInfo; +class TagDecl; +class Type; +class VarDecl; + +/// \brief Keeps track of the mangled names of lambda expressions and block +/// literals within a particular context. +class MangleNumberingContext + : public RefCountedBase { + llvm::DenseMap ManglingNumbers; + llvm::DenseMap TagManglingNumbers; + +public: + virtual ~MangleNumberingContext() {} + + /// \brief Retrieve the mangling number of a new lambda expression with the + /// given call operator within this context. + unsigned getManglingNumber(const CXXMethodDecl *CallOperator); + + /// \brief Retrieve the mangling number of a new block literal within this + /// context. + unsigned getManglingNumber(const BlockDecl *BD); + + /// \brief Retrieve the mangling number of a static local variable within + /// this context. + virtual unsigned getManglingNumber(const VarDecl *VD) = 0; + + /// \brief Retrieve the mangling number of a static local variable within + /// this context. + unsigned getManglingNumber(const TagDecl *TD); +}; + +} // end namespace clang +#endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h b/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h index 58f3986..b332b15 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h +++ b/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h @@ -231,7 +231,11 @@ public: /// \brief Evalutes true when this nested-name-specifier location is /// non-empty. - operator bool() const { return Qualifier; } + LLVM_EXPLICIT operator bool() const { return Qualifier; } + + /// \brief Evalutes true when this nested-name-specifier location is + /// empty. + bool hasQualifier() const { return Qualifier; } /// \brief Retrieve the nested-name-specifier to which this instance /// refers. diff --git a/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h b/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h index 62eae02..bd2ebf5 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h @@ -29,6 +29,11 @@ public: /// visited and updated or inserted but not the parents of S. void addStmt(Stmt* S); + /// Manually sets the parent of \p S to \p Parent. + /// + /// If \p S is already in the map, this method will update the mapping. + void setParent(const Stmt *S, const Stmt *Parent); + Stmt *getParent(Stmt*) const; Stmt *getParentIgnoreParens(Stmt *) const; Stmt *getParentIgnoreParenCasts(Stmt *) const; diff --git a/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h b/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h index e3c09e7..7642699 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h +++ b/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h @@ -39,8 +39,9 @@ struct PrintingPolicy { SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false), SuppressUnwrittenScope(false), SuppressInitializers(false), ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), - SuppressStrongLifetime(false), Bool(LO.Bool), - TerseOutput(false), PolishForDeclaration(false) { } + SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false), + Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false), + MSWChar(LO.MicrosoftExt && !LO.WChar) { } /// \brief What language we're printing. LangOptions LangOpts; @@ -131,6 +132,10 @@ struct PrintingPolicy { /// ARC. unsigned SuppressStrongLifetime : 1; + /// \brief When true, suppress printing of lifetime qualifier in + /// ARC. + unsigned SuppressLifetimeQualifiers : 1; + /// \brief Whether we can use 'bool' rather than '_Bool', even if the language /// doesn't actually have 'bool' (because, e.g., it is defined as a macro). unsigned Bool : 1; @@ -146,6 +151,10 @@ struct PrintingPolicy { /// declaration tag; such as, do not print attributes attached to the declaration. /// unsigned PolishForDeclaration : 1; + + /// \brief When true, print the built-in wchar_t type as __wchar_t. For use in + /// Microsoft mode when wchar_t is not available. + unsigned MSWChar : 1; }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/RawCommentList.h b/contrib/llvm/tools/clang/include/clang/AST/RawCommentList.h index 84a6e96..a4fcc10 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RawCommentList.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RawCommentList.h @@ -107,12 +107,9 @@ public: return RawText; } - SourceRange getSourceRange() const LLVM_READONLY { - return Range; - } - - unsigned getBeginLine(const SourceManager &SM) const; - unsigned getEndLine(const SourceManager &SM) const; + SourceRange getSourceRange() const LLVM_READONLY { return Range; } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } const char *getBriefText(const ASTContext &Context) const { if (BriefTextValid) @@ -146,11 +143,6 @@ private: /// considered as documentation comments. bool ParseAllComments : 1; - mutable bool BeginLineValid : 1; ///< True if BeginLine is valid - mutable bool EndLineValid : 1; ///< True if EndLine is valid - mutable unsigned BeginLine; ///< Cached line number - mutable unsigned EndLine; ///< Cached line number - /// \brief Constructor for AST deserialization. RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment, bool IsAlmostTrailingComment, @@ -158,8 +150,7 @@ private: Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K), IsAttached(false), IsTrailingComment(IsTrailingComment), IsAlmostTrailingComment(IsAlmostTrailingComment), - ParseAllComments(ParseAllComments), - BeginLineValid(false), EndLineValid(false) + ParseAllComments(ParseAllComments) { } StringRef getRawTextSlow(const SourceManager &SourceMgr) const; @@ -178,8 +169,7 @@ public: explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { } bool operator()(const RawComment &LHS, const RawComment &RHS) { - return SM.isBeforeInTranslationUnit(LHS.getSourceRange().getBegin(), - RHS.getSourceRange().getBegin()); + return SM.isBeforeInTranslationUnit(LHS.getLocStart(), RHS.getLocStart()); } bool operator()(const RawComment *LHS, const RawComment *RHS) { @@ -191,8 +181,7 @@ public: /// sorted in order of appearance in the translation unit. class RawCommentList { public: - RawCommentList(SourceManager &SourceMgr) : - SourceMgr(SourceMgr), OnlyWhitespaceSeen(true) { } + RawCommentList(SourceManager &SourceMgr) : SourceMgr(SourceMgr) {} void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator); @@ -203,15 +192,9 @@ public: private: SourceManager &SourceMgr; std::vector Comments; - SourceLocation PrevCommentEndLoc; - bool OnlyWhitespaceSeen; void addCommentsToFront(const std::vector &C) { - size_t OldSize = Comments.size(); - Comments.resize(C.size() + OldSize); - std::copy_backward(Comments.begin(), Comments.begin() + OldSize, - Comments.end()); - std::copy(C.begin(), C.end(), Comments.begin()); + Comments.insert(Comments.begin(), C.begin(), C.end()); } friend class ASTReader; diff --git a/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h b/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h index 3655646..7268b3a 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h @@ -93,10 +93,22 @@ private: /// HasOwnVFPtr - Does this class provide a virtual function table /// (vtable in Itanium, vftbl in Microsoft) that is independent from /// its base classes? - bool HasOwnVFPtr; // TODO: stash this somewhere more efficient + bool HasOwnVFPtr : 1; + + /// HasVFPtr - Does this class have a vftable that could be extended by + /// a derived class. The class may have inherited this pointer from + /// a primary base class. + bool HasExtendableVFPtr : 1; + + /// AlignAfterVBases - Force appropriate alignment after virtual bases are + /// laid out in MS-C++-ABI. + bool AlignAfterVBases : 1; /// PrimaryBase - The primary base info for this record. llvm::PointerIntPair PrimaryBase; + + /// BaseSharingVBPtr - The base we share vbptr with. + const CXXRecordDecl *BaseSharingVBPtr; /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :) typedef llvm::DenseMap BaseOffsetsMapTy; @@ -122,13 +134,16 @@ private: typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy; ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment, - bool hasOwnVFPtr, CharUnits vbptroffset, + bool hasOwnVFPtr, bool hasExtendableVFPtr, + CharUnits vbptroffset, CharUnits datasize, const uint64_t *fieldoffsets, unsigned fieldcount, CharUnits nonvirtualsize, CharUnits nonvirtualalign, CharUnits SizeOfLargestEmptySubobject, const CXXRecordDecl *PrimaryBase, bool IsPrimaryBaseVirtual, + const CXXRecordDecl *BaseSharingVBPtr, + bool ForceAlign, const BaseOffsetsMapTy& BaseOffsets, const VBaseOffsetsMapTy& VBaseOffsets); @@ -226,6 +241,37 @@ public: return CXXInfo->HasOwnVFPtr; } + /// hasVFPtr - Does this class have a virtual function table pointer + /// that can be extended by a derived class? This is synonymous with + /// this class having a VFPtr at offset zero. + bool hasExtendableVFPtr() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + return CXXInfo->HasExtendableVFPtr; + } + + /// hasOwnVBPtr - Does this class provide its own virtual-base + /// table pointer, rather than inheriting one from a primary base + /// class? + /// + /// This implies that the ABI has no primary base class, meaning + /// that it has no base classes that are suitable under the conditions + /// of the ABI. + bool hasOwnVBPtr() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + return hasVBPtr() && !CXXInfo->BaseSharingVBPtr; + } + + /// hasVBPtr - Does this class have a virtual function table pointer. + bool hasVBPtr() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + return !CXXInfo->VBPtrOffset.isNegative(); + } + + bool getAlignAfterVBases() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + return CXXInfo->AlignAfterVBases; + } + /// getVBPtrOffset - Get the offset for virtual base table pointer. /// This is only meaningful with the Microsoft ABI. CharUnits getVBPtrOffset() const { @@ -233,6 +279,11 @@ public: return CXXInfo->VBPtrOffset; } + const CXXRecordDecl *getBaseSharingVBPtr() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + return CXXInfo->BaseSharingVBPtr; + } + const VBaseOffsetsMapTy &getVBaseOffsetsMap() const { assert(CXXInfo && "Record layout does not have C++ specific info!"); return CXXInfo->VBaseOffsets; diff --git a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h index b5a4b5e..d09550f 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h @@ -27,6 +27,7 @@ #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" +#include "clang/AST/StmtOpenMP.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -108,7 +109,7 @@ namespace clang { /// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar /// is Foo's super class) before calling VisitFoo(), the result is /// that the Visit*() methods for a given node are called in the -/// top-down order (e.g. for a node of type NamedDecl, the order will +/// top-down order (e.g. for a node of type NamespaceDecl, the order will /// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()). /// /// This scheme guarantees that all Visit*() calls for the same AST @@ -243,8 +244,16 @@ public: /// \brief Recursively visit a lambda capture. /// /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseLambdaCapture(LambdaExpr::Capture C); - + bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaExpr::Capture *C); + + /// \brief Recursively visit the body of a lambda expression. + /// + /// This provides a hook for visitors that need more context when visiting + /// \c LE->getBody(). + /// + /// \returns false if the visitation was terminated early, true otherwise. + bool TraverseLambdaBody(LambdaExpr *LE); + // ---- Methods on Stmts ---- // Declare Traverse*() for all concrete Stmt classes. @@ -342,7 +351,7 @@ public: // ---- Methods on TypeLocs ---- // FIXME: this currently just calls the matching Type methods - // Declare Traverse*() for all concrete Type classes. + // Declare Traverse*() for all concrete TypeLoc classes. #define ABSTRACT_TYPELOC(CLASS, BASE) #define TYPELOC(CLASS, BASE) \ bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL); @@ -398,8 +407,12 @@ public: private: // These are helper methods used by more than one Traverse* method. bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL); - bool TraverseClassInstantiations(ClassTemplateDecl *D); - bool TraverseFunctionInstantiations(FunctionTemplateDecl *D) ; +#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \ + bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D); + DEF_TRAVERSE_TMPL_INST(Class) + DEF_TRAVERSE_TMPL_INST(Var) + DEF_TRAVERSE_TMPL_INST(Function) +#undef DEF_TRAVERSE_TMPL_INST bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL, unsigned Count); bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL); @@ -409,6 +422,13 @@ private: bool TraverseDeclContextHelper(DeclContext *DC); bool TraverseFunctionHelper(FunctionDecl *D); bool TraverseVarHelper(VarDecl *D); + bool TraverseOMPClause(OMPClause *C); +#define OPENMP_CLAUSE(Name, Class) \ + bool Visit##Class(Class *C); +#include "clang/Basic/OpenMPKinds.def" + /// \brief Process clauses with list of variables. + template + void VisitOMPClauseList(T *Node); struct EnqueueJob { Stmt *S; @@ -802,10 +822,20 @@ bool RecursiveASTVisitor::TraverseConstructorInitializer( } template -bool RecursiveASTVisitor::TraverseLambdaCapture(LambdaExpr::Capture C){ +bool RecursiveASTVisitor::TraverseLambdaCapture( + LambdaExpr *LE, const LambdaExpr::Capture *C) { + if (C->isInitCapture()) + TRY_TO(TraverseDecl(C->getCapturedVar())); + return true; +} + +template +bool RecursiveASTVisitor::TraverseLambdaBody(LambdaExpr *LE) { + TRY_TO(TraverseStmt(LE->getBody())); return true; } + // ----------------- Type traversal ----------------- // This macro makes available a variable T, the passed-in type. @@ -844,6 +874,10 @@ DEF_TRAVERSE_TYPE(MemberPointerType, { TRY_TO(TraverseType(T->getPointeeType())); }) +DEF_TRAVERSE_TYPE(DecayedType, { + TRY_TO(TraverseType(T->getOriginalType())); + }) + DEF_TRAVERSE_TYPE(ConstantArrayType, { TRY_TO(TraverseType(T->getElementType())); }) @@ -1050,6 +1084,10 @@ DEF_TRAVERSE_TYPELOC(MemberPointerType, { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) +DEF_TRAVERSE_TYPELOC(DecayedType, { + TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); + }) + template bool RecursiveASTVisitor::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) { // This isn't available for ArrayType, but is for the ArrayTypeLoc. @@ -1420,59 +1458,44 @@ bool RecursiveASTVisitor::TraverseTemplateParameterListHelper( return true; } -// A helper method for traversing the implicit instantiations of a -// class template. -template -bool RecursiveASTVisitor::TraverseClassInstantiations( - ClassTemplateDecl *D) { - ClassTemplateDecl::spec_iterator end = D->spec_end(); - for (ClassTemplateDecl::spec_iterator it = D->spec_begin(); it != end; ++it) { - ClassTemplateSpecializationDecl* SD = *it; - - switch (SD->getSpecializationKind()) { - // Visit the implicit instantiations with the requested pattern. - case TSK_Undeclared: - case TSK_ImplicitInstantiation: - TRY_TO(TraverseDecl(SD)); - break; - - // We don't need to do anything on an explicit instantiation - // or explicit specialization because there will be an explicit - // node for it elsewhere. - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - case TSK_ExplicitSpecialization: - break; - } - } - - return true; +#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \ +/* A helper method for traversing the implicit instantiations of a + class or variable template. */ \ +template \ +bool RecursiveASTVisitor::TraverseTemplateInstantiations( \ + TMPLDECLKIND##TemplateDecl *D) { \ + TMPLDECLKIND##TemplateDecl::spec_iterator end = D->spec_end(); \ + for (TMPLDECLKIND##TemplateDecl::spec_iterator it = D->spec_begin(); \ + it != end; ++it) { \ + TMPLDECLKIND##TemplateSpecializationDecl* SD = *it; \ + \ + switch (SD->getSpecializationKind()) { \ + /* Visit the implicit instantiations with the requested pattern. */ \ + case TSK_Undeclared: \ + case TSK_ImplicitInstantiation: \ + TRY_TO(TraverseDecl(SD)); \ + break; \ + \ + /* We don't need to do anything on an explicit instantiation + or explicit specialization because there will be an explicit + node for it elsewhere. */ \ + case TSK_ExplicitInstantiationDeclaration: \ + case TSK_ExplicitInstantiationDefinition: \ + case TSK_ExplicitSpecialization: \ + break; \ + } \ + } \ + \ + return true; \ } - -DEF_TRAVERSE_DECL(ClassTemplateDecl, { - CXXRecordDecl* TempDecl = D->getTemplatedDecl(); - TRY_TO(TraverseDecl(TempDecl)); - TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); - - // By default, we do not traverse the instantiations of - // class templates since they do not appear in the user code. The - // following code optionally traverses them. - // - // We only traverse the class instantiations when we see the canonical - // declaration of the template, to ensure we only visit them once. - if (getDerived().shouldVisitTemplateInstantiations() && - D == D->getCanonicalDecl()) - TRY_TO(TraverseClassInstantiations(D)); - - // Note that getInstantiatedFromMemberTemplate() is just a link - // from a template instantiation back to the template from which - // it was instantiated, and thus should not be traversed. - }) + +DEF_TRAVERSE_TMPL_INST(Class) +DEF_TRAVERSE_TMPL_INST(Var) // A helper method for traversing the instantiations of a // function while skipping its specializations. template -bool RecursiveASTVisitor::TraverseFunctionInstantiations( +bool RecursiveASTVisitor::TraverseTemplateInstantiations( FunctionTemplateDecl *D) { FunctionTemplateDecl::spec_iterator end = D->spec_end(); for (FunctionTemplateDecl::spec_iterator it = D->spec_begin(); it != end; @@ -1500,20 +1523,31 @@ bool RecursiveASTVisitor::TraverseFunctionInstantiations( return true; } -DEF_TRAVERSE_DECL(FunctionTemplateDecl, { - TRY_TO(TraverseDecl(D->getTemplatedDecl())); - TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); - - // By default, we do not traverse the instantiations of - // function templates since they do not appear in the user code. The - // following code optionally traverses them. - // - // We only traverse the function instantiations when we see the canonical - // declaration of the template, to ensure we only visit them once. - if (getDerived().shouldVisitTemplateInstantiations() && - D == D->getCanonicalDecl()) - TRY_TO(TraverseFunctionInstantiations(D)); - }) +// This macro unifies the traversal of class, variable and function +// template declarations. +#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \ +DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \ + TRY_TO(TraverseDecl(D->getTemplatedDecl())); \ + TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \ + \ + /* By default, we do not traverse the instantiations of + class templates since they do not appear in the user code. The + following code optionally traverses them. + + We only traverse the class instantiations when we see the canonical + declaration of the template, to ensure we only visit them once. */ \ + if (getDerived().shouldVisitTemplateInstantiations() && \ + D == D->getCanonicalDecl()) \ + TRY_TO(TraverseTemplateInstantiations(D)); \ + \ + /* Note that getInstantiatedFromMemberTemplate() is just a link + from a template instantiation back to the template from which + it was instantiated, and thus should not be traversed. */ \ + }) + +DEF_TRAVERSE_TMPL_DECL(Class) +DEF_TRAVERSE_TMPL_DECL(Var) +DEF_TRAVERSE_TMPL_DECL(Function) DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, { // D is the "T" in something like @@ -1607,26 +1641,30 @@ DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); }) -DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, { - // For implicit instantiations ("set x;"), we don't want to - // recurse at all, since the instatiated class isn't written in - // the source code anywhere. (Note the instatiated *type* -- - // set -- is written, and will still get a callback of - // TemplateSpecializationType). For explicit instantiations - // ("template set;"), we do need a callback, since this - // is the only callback that's made for this instantiation. - // We use getTypeAsWritten() to distinguish. - if (TypeSourceInfo *TSI = D->getTypeAsWritten()) - TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); - - if (!getDerived().shouldVisitTemplateInstantiations() && - D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) - // Returning from here skips traversing the - // declaration context of the ClassTemplateSpecializationDecl - // (embedded in the DEF_TRAVERSE_DECL() macro) - // which contains the instantiated members of the class. - return true; - }) +#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND) \ +DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \ + /* For implicit instantiations ("set x;"), we don't want to + recurse at all, since the instatiated template isn't written in + the source code anywhere. (Note the instatiated *type* -- + set -- is written, and will still get a callback of + TemplateSpecializationType). For explicit instantiations + ("template set;"), we do need a callback, since this + is the only callback that's made for this instantiation. + We use getTypeAsWritten() to distinguish. */ \ + if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \ + TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \ + \ + if (!getDerived().shouldVisitTemplateInstantiations() && \ + D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \ + /* Returning from here skips traversing the + declaration context of the *TemplateSpecializationDecl + (embedded in the DEF_TRAVERSE_DECL() macro) + which contains the instantiated members of the template. */ \ + return true; \ + }) + +DEF_TRAVERSE_TMPL_SPEC_DECL(Class) +DEF_TRAVERSE_TMPL_SPEC_DECL(Var) template bool RecursiveASTVisitor::TraverseTemplateArgumentLocsHelper( @@ -1637,25 +1675,30 @@ bool RecursiveASTVisitor::TraverseTemplateArgumentLocsHelper( return true; } -DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, { - // The partial specialization. - if (TemplateParameterList *TPL = D->getTemplateParameters()) { - for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); - I != E; ++I) { - TRY_TO(TraverseDecl(*I)); - } - } - // The args that remains unspecialized. - TRY_TO(TraverseTemplateArgumentLocsHelper( - D->getTemplateArgsAsWritten(), D->getNumTemplateArgsAsWritten())); - - // Don't need the ClassTemplatePartialSpecializationHelper, even - // though that's our parent class -- we already visit all the - // template args here. - TRY_TO(TraverseCXXRecordHelper(D)); - - // Instantiations will have been visited with the primary template. - }) +#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \ +DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \ + /* The partial specialization. */ \ + if (TemplateParameterList *TPL = D->getTemplateParameters()) { \ + for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \ + I != E; ++I) { \ + TRY_TO(TraverseDecl(*I)); \ + } \ + } \ + /* The args that remains unspecialized. */ \ + TRY_TO(TraverseTemplateArgumentLocsHelper( \ + D->getTemplateArgsAsWritten()->getTemplateArgs(), \ + D->getTemplateArgsAsWritten()->NumTemplateArgs)); \ + \ + /* Don't need the *TemplatePartialSpecializationHelper, even + though that's our parent class -- we already visit all the + template args here. */ \ + TRY_TO(Traverse##DECLKIND##Helper(D)); \ + \ + /* Instantiations will have been visited with the primary template. */ \ + }) + +DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord) +DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Var, Var) DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); @@ -1736,6 +1779,14 @@ bool RecursiveASTVisitor::TraverseFunctionHelper(FunctionDecl *D) { // including exception specifications. if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) { TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); + } else if (getDerived().shouldVisitImplicitCode()) { + // Visit parameter variable declarations of the implicit function + // if the traverser is visiting implicit code. Parameter variable + // declarations do not have valid TypeSourceInfo, so to visit them + // we need to traverse the declarations explicitly. + for (FunctionDecl::param_const_iterator I = D->param_begin(), + E = D->param_end(); I != E; ++I) + TRY_TO(TraverseDecl(*I)); } if (CXXConstructorDecl *Ctor = dyn_cast(D)) { @@ -2117,10 +2168,12 @@ DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, { // Walk only the visible parts of lambda expressions. template bool RecursiveASTVisitor::TraverseLambdaExpr(LambdaExpr *S) { + TRY_TO(WalkUpFromLambdaExpr(S)); + for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(), CEnd = S->explicit_capture_end(); C != CEnd; ++C) { - TRY_TO(TraverseLambdaCapture(*C)); + TRY_TO(TraverseLambdaCapture(S, C)); } if (S->hasExplicitParameters() || S->hasExplicitResultType()) { @@ -2140,7 +2193,7 @@ bool RecursiveASTVisitor::TraverseLambdaExpr(LambdaExpr *S) { } } - TRY_TO(TraverseStmt(S->getBody())); + TRY_TO(TraverseLambdaBody(S)); return true; } @@ -2174,6 +2227,7 @@ DEF_TRAVERSE_STMT(CXXDefaultInitExpr, { }) DEF_TRAVERSE_STMT(CXXDeleteExpr, { }) DEF_TRAVERSE_STMT(ExprWithCleanups, { }) DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { }) +DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { }) DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo()) @@ -2211,6 +2265,7 @@ DEF_TRAVERSE_STMT(ParenExpr, { }) DEF_TRAVERSE_STMT(ParenListExpr, { }) DEF_TRAVERSE_STMT(PredefinedExpr, { }) DEF_TRAVERSE_STMT(ShuffleVectorExpr, { }) +DEF_TRAVERSE_STMT(ConvertVectorExpr, { }) DEF_TRAVERSE_STMT(StmtExpr, { }) DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); @@ -2269,6 +2324,61 @@ DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, { }) // Traverse OpenCL: AsType, Convert. DEF_TRAVERSE_STMT(AsTypeExpr, { }) +// OpenMP directives. +DEF_TRAVERSE_STMT(OMPParallelDirective, { + ArrayRef Clauses = S->clauses(); + for (ArrayRef::iterator I = Clauses.begin(), E = Clauses.end(); + I != E; ++I) + if (!TraverseOMPClause(*I)) return false; +}) + +// OpenMP clauses. +template +bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) { + if (!C) return true; + switch (C->getClauseKind()) { +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_##Name: \ + return getDerived().Visit##Class(static_cast(C)); +#include "clang/Basic/OpenMPKinds.def" + default: break; + } + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPDefaultClause(OMPDefaultClause *C) { + return true; +} + +template +template +void RecursiveASTVisitor::VisitOMPClauseList(T *Node) { + for (typename T::varlist_iterator I = Node->varlist_begin(), + E = Node->varlist_end(); + I != E; ++I) + TraverseStmt(*I); +} + +template +bool RecursiveASTVisitor::VisitOMPPrivateClause(OMPPrivateClause *C) { + VisitOMPClauseList(C); + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPFirstprivateClause( + OMPFirstprivateClause *C) { + VisitOMPClauseList(C); + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPSharedClause(OMPSharedClause *C) { + VisitOMPClauseList(C); + return true; +} + // FIXME: look at the following tricky-seeming exprs to see if we // need to recurse on anything. These are ones that have methods // returning decls or qualtypes or nestednamespecifier -- though I'm diff --git a/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h b/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h index e3b340a..cfe5a90 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h @@ -75,7 +75,7 @@ public: /// \brief Return the first declaration of this declaration or itself if this /// is the only declaration. - decl_type *getFirstDeclaration() { + decl_type *getFirstDecl() { decl_type *D = static_cast(this); while (D->getPreviousDecl()) D = D->getPreviousDecl(); @@ -84,31 +84,29 @@ public: /// \brief Return the first declaration of this declaration or itself if this /// is the only declaration. - const decl_type *getFirstDeclaration() const { + const decl_type *getFirstDecl() const { const decl_type *D = static_cast(this); while (D->getPreviousDecl()) D = D->getPreviousDecl(); return D; } - /// \brief Returns true if this is the first declaration. - bool isFirstDeclaration() const { - return RedeclLink.NextIsLatest(); - } + /// \brief True if this is the first declaration in its redeclaration chain. + bool isFirstDecl() const { return RedeclLink.NextIsLatest(); } /// \brief Returns the most recent (re)declaration of this declaration. decl_type *getMostRecentDecl() { - return getFirstDeclaration()->RedeclLink.getNext(); + return getFirstDecl()->RedeclLink.getNext(); } /// \brief Returns the most recent (re)declaration of this declaration. const decl_type *getMostRecentDecl() const { - return getFirstDeclaration()->RedeclLink.getNext(); + return getFirstDecl()->RedeclLink.getNext(); } /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the /// first and only declaration. - void setPreviousDeclaration(decl_type *PrevDecl); + void setPreviousDecl(decl_type *PrevDecl); /// \brief Iterates through all the redeclarations of the same decl. class redecl_iterator { @@ -134,7 +132,7 @@ public: redecl_iterator& operator++() { assert(Current && "Advancing while iterator has reached end"); // Sanity check to avoid infinite loop on invalid redecl chain. - if (Current->isFirstDeclaration()) { + if (Current->isFirstDecl()) { if (PassedFirst) { assert(0 && "Passed first decl twice, invalid redecl chain!"); Current = 0; @@ -175,6 +173,40 @@ public: friend class ASTDeclWriter; }; +/// \brief Get the primary declaration for a declaration from an AST file. That +/// will be the first-loaded declaration. +Decl *getPrimaryMergedDecl(Decl *D); + +/// \brief Provides common interface for the Decls that cannot be redeclared, +/// but can be merged if the same declaration is brought in from multiple +/// modules. +template +class Mergeable { +public: + Mergeable() {} + + /// \brief Return the first declaration of this declaration or itself if this + /// is the only declaration. + decl_type *getFirstDecl() { + decl_type *D = static_cast(this); + if (!D->isFromASTFile()) + return D; + return cast(getPrimaryMergedDecl(const_cast(D))); + } + + /// \brief Return the first declaration of this declaration or itself if this + /// is the only declaration. + const decl_type *getFirstDecl() const { + const decl_type *D = static_cast(this); + if (!D->isFromASTFile()) + return D; + return cast(getPrimaryMergedDecl(const_cast(D))); + } + + /// \brief Returns true if this is the first declaration. + bool isFirstDecl() const { return getFirstDecl() == this; } +}; + } #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h index 74c9ec2..ace53d8 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h @@ -266,10 +266,6 @@ protected: /// Whether this initializer list originally had a GNU array-range /// designator in it. This is a temporary marker used by CodeGen. unsigned HadArrayRangeDesignator : 1; - - /// Whether this initializer list initializes a std::initializer_list - /// object. - unsigned InitializesStdInitializerList : 1; }; class TypeTraitExprBitfields { @@ -289,7 +285,7 @@ protected: /// \brief The number of arguments to this type trait. unsigned NumArgs : 32 - 8 - 1 - NumExprBits; }; - + union { // FIXME: this is wasteful on 64-bit platforms. void *Aligner; @@ -316,19 +312,21 @@ protected: public: // Only allow allocation of Stmts using the allocator in ASTContext // or by doing a placement new. - void* operator new(size_t bytes, ASTContext& C, - unsigned alignment = 8) throw(); + void* operator new(size_t bytes, const ASTContext& C, + unsigned alignment = 8); - void* operator new(size_t bytes, ASTContext* C, - unsigned alignment = 8) throw(); + void* operator new(size_t bytes, const ASTContext* C, + unsigned alignment = 8) { + return operator new(bytes, *C, alignment); + } void* operator new(size_t bytes, void* mem) throw() { return mem; } - void operator delete(void*, ASTContext&, unsigned) throw() { } - void operator delete(void*, ASTContext*, unsigned) throw() { } - void operator delete(void*, std::size_t) throw() { } + void operator delete(void*, const ASTContext&, unsigned) throw() { } + void operator delete(void*, const ASTContext*, unsigned) throw() { } + void operator delete(void*, size_t) throw() { } void operator delete(void*, void*) throw() { } public: @@ -382,7 +380,7 @@ public: /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST /// back to its original source language syntax. - void dumpPretty(ASTContext &Context) const; + void dumpPretty(const ASTContext &Context) const; void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation = 0) const; @@ -401,13 +399,6 @@ public: const_cast(this)->stripLabelLikeStatements()); } - /// hasImplicitControlFlow - Some statements (e.g. short circuited operations) - /// contain implicit control-flow in the order their subexpressions - /// are evaluated. This predicate returns true if this statement has - /// such implicit control-flow. Such statements are also specially handled - /// within CFGs. - bool hasImplicitControlFlow() const; - /// Child Iterators: All subclasses must implement 'children' /// to permit easy iteration over the substatements/subexpessions of an /// AST node. This permits easy iteration over all nodes in the AST. @@ -553,10 +544,10 @@ class CompoundStmt : public Stmt { Stmt** Body; SourceLocation LBracLoc, RBracLoc; public: - CompoundStmt(ASTContext &C, ArrayRef Stmts, + CompoundStmt(const ASTContext &C, ArrayRef Stmts, SourceLocation LB, SourceLocation RB); - // \brief Build an empty compound statment with a location. + // \brief Build an empty compound statement with a location. explicit CompoundStmt(SourceLocation Loc) : Stmt(CompoundStmtClass), Body(0), LBracLoc(Loc), RBracLoc(Loc) { CompoundStmtBits.NumStmts = 0; @@ -568,7 +559,7 @@ public: CompoundStmtBits.NumStmts = 0; } - void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts); + void setStmts(const ASTContext &C, Stmt **Stmts, unsigned NumStmts); bool body_empty() const { return CompoundStmtBits.NumStmts == 0; } unsigned size() const { return CompoundStmtBits.NumStmts; } @@ -827,10 +818,10 @@ class AttributedStmt : public Stmt { } public: - static AttributedStmt *Create(ASTContext &C, SourceLocation Loc, + static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc, ArrayRef Attrs, Stmt *SubStmt); // \brief Build an empty attributed statement. - static AttributedStmt *CreateEmpty(ASTContext &C, unsigned NumAttrs); + static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs); SourceLocation getAttrLoc() const { return AttrLoc; } ArrayRef getAttrs() const { @@ -860,7 +851,7 @@ class IfStmt : public Stmt { SourceLocation ElseLoc; public: - IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, + IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0); /// \brief Build an empty if/then/else statement @@ -875,7 +866,7 @@ public: /// } /// \endcode VarDecl *getConditionVariable() const; - void setConditionVariable(ASTContext &C, VarDecl *V); + void setConditionVariable(const ASTContext &C, VarDecl *V); /// If this IfStmt has a condition variable, return the faux DeclStmt /// associated with the creation of that condition variable. @@ -933,7 +924,7 @@ class SwitchStmt : public Stmt { unsigned AllEnumCasesCovered : 1; public: - SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond); + SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond); /// \brief Build a empty switch statement. explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { } @@ -948,7 +939,7 @@ public: /// } /// \endcode VarDecl *getConditionVariable() const; - void setConditionVariable(ASTContext &C, VarDecl *V); + void setConditionVariable(const ASTContext &C, VarDecl *V); /// If this SwitchStmt has a condition variable, return the faux DeclStmt /// associated with the creation of that condition variable. @@ -967,9 +958,6 @@ public: SwitchCase *getSwitchCaseList() { return FirstCase; } /// \brief Set the case list for this switch statement. - /// - /// The caller is responsible for incrementing the retain counts on - /// all of the SwitchCase statements in this list. void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; } SourceLocation getSwitchLoc() const { return SwitchLoc; } @@ -1021,7 +1009,7 @@ class WhileStmt : public Stmt { Stmt* SubExprs[END_EXPR]; SourceLocation WhileLoc; public: - WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, + WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL); /// \brief Build an empty while statement. @@ -1036,7 +1024,7 @@ public: /// } /// \endcode VarDecl *getConditionVariable() const; - void setConditionVariable(ASTContext &C, VarDecl *V); + void setConditionVariable(const ASTContext &C, VarDecl *V); /// If this WhileStmt has a condition variable, return the faux DeclStmt /// associated with the creation of that condition variable. @@ -1129,8 +1117,9 @@ class ForStmt : public Stmt { SourceLocation LParenLoc, RParenLoc; public: - ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, - Stmt *Body, SourceLocation FL, SourceLocation LP, SourceLocation RP); + ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, + Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP, + SourceLocation RP); /// \brief Build an empty for statement. explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { } @@ -1146,7 +1135,7 @@ public: /// } /// \endcode VarDecl *getConditionVariable() const; - void setConditionVariable(ASTContext &C, VarDecl *V); + void setConditionVariable(const ASTContext &C, VarDecl *V); /// If this ForStmt has a condition variable, return the faux DeclStmt /// associated with the creation of that condition variable. @@ -1417,7 +1406,7 @@ public: //===--- Asm String Analysis ---===// /// Assemble final IR asm string. - std::string generateAsmString(ASTContext &C) const; + std::string generateAsmString(const ASTContext &C) const; //===--- Output operands ---===// @@ -1520,7 +1509,7 @@ class GCCAsmStmt : public AsmStmt { friend class ASTStmtReader; public: - GCCAsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, + GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, unsigned numoutputs, unsigned numinputs, IdentifierInfo **names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, @@ -1586,10 +1575,10 @@ public: /// translation of strings from GCC syntax to LLVM IR syntax, and handles //// flattening of named references like %[foo] to Operand AsmStringPiece's. unsigned AnalyzeAsmString(SmallVectorImpl &Pieces, - ASTContext &C, unsigned &DiagOffs) const; + const ASTContext &C, unsigned &DiagOffs) const; /// Assemble final IR asm string. - std::string generateAsmString(ASTContext &C) const; + std::string generateAsmString(const ASTContext &C) const; //===--- Output operands ---===// @@ -1649,7 +1638,7 @@ public: } private: - void setOutputsAndInputsAndClobbers(ASTContext &C, + void setOutputsAndInputsAndClobbers(const ASTContext &C, IdentifierInfo **Names, StringLiteral **Constraints, Stmt **Exprs, @@ -1695,9 +1684,9 @@ class MSAsmStmt : public AsmStmt { friend class ASTStmtReader; public: - MSAsmStmt(ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc, - bool issimple, bool isvolatile, ArrayRef asmtoks, - unsigned numoutputs, unsigned numinputs, + MSAsmStmt(const ASTContext &C, SourceLocation asmloc, + SourceLocation lbraceloc, bool issimple, bool isvolatile, + ArrayRef asmtoks, unsigned numoutputs, unsigned numinputs, ArrayRef constraints, ArrayRef exprs, StringRef asmstr, ArrayRef clobbers, SourceLocation endloc); @@ -1720,7 +1709,7 @@ public: StringRef getAsmString() const { return AsmStr; } /// Assemble final IR asm string. - std::string generateAsmString(ASTContext &C) const; + std::string generateAsmString(const ASTContext &C) const; //===--- Output operands ---===// @@ -1765,12 +1754,9 @@ public: StringRef getClobber(unsigned i) const { return getClobbers()[i]; } private: - void initialize(ASTContext &C, - StringRef AsmString, - ArrayRef AsmToks, - ArrayRef Constraints, - ArrayRef Exprs, - ArrayRef Clobbers); + void initialize(const ASTContext &C, StringRef AsmString, + ArrayRef AsmToks, ArrayRef Constraints, + ArrayRef Exprs, ArrayRef Clobbers); public: SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; } @@ -1800,7 +1786,7 @@ class SEHExceptStmt : public Stmt { explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { } public: - static SEHExceptStmt* Create(ASTContext &C, + static SEHExceptStmt* Create(const ASTContext &C, SourceLocation ExceptLoc, Expr *FilterExpr, Stmt *Block); @@ -1841,7 +1827,7 @@ class SEHFinallyStmt : public Stmt { explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { } public: - static SEHFinallyStmt* Create(ASTContext &C, + static SEHFinallyStmt* Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block); @@ -1880,10 +1866,8 @@ class SEHTryStmt : public Stmt { explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { } public: - static SEHTryStmt* Create(ASTContext &C, - bool isCXXTry, - SourceLocation TryLoc, - Stmt *TryBlock, + static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry, + SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler); SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); } @@ -2006,13 +1990,13 @@ private: void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; } public: - static CapturedStmt *Create(ASTContext &Context, Stmt *S, + static CapturedStmt *Create(const ASTContext &Context, Stmt *S, CapturedRegionKind Kind, ArrayRef Captures, ArrayRef CaptureInits, CapturedDecl *CD, RecordDecl *RD); - static CapturedStmt *CreateDeserialized(ASTContext &Context, + static CapturedStmt *CreateDeserialized(const ASTContext &Context, unsigned NumCaptures); /// \brief Retrieve the statement being captured. diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h b/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h index 0112bef..df98d41 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h @@ -79,10 +79,10 @@ class CXXTryStmt : public Stmt { } public: - static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc, + static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc, Stmt *tryBlock, ArrayRef handlers); - static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty, + static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty, unsigned numHandlers); SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); } diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h b/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h index b933ed0..fbc8e5d 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_STMT_ITR_H #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Compiler.h" #include #include #include @@ -28,18 +29,14 @@ class VariableArrayType; class StmtIteratorBase { protected: - enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, DeclGroupMode = 0x3, + enum { StmtMode = 0x0, SizeOfTypeVAMode = 0x1, DeclGroupMode = 0x2, Flags = 0x3 }; Stmt **stmt; - union { Decl *decl; Decl **DGI; }; + Decl **DGI; uintptr_t RawVAPtr; Decl **DGE; - bool inDecl() const { - return (RawVAPtr & Flags) == DeclMode; - } - bool inDeclGroup() const { return (RawVAPtr & Flags) == DeclGroupMode; } @@ -49,7 +46,7 @@ protected: } bool inStmt() const { - return (RawVAPtr & Flags) == 0; + return (RawVAPtr & Flags) == StmtMode; } const VariableArrayType *getVAPtr() const { @@ -57,7 +54,7 @@ protected: } void setVAPtr(const VariableArrayType *P) { - assert (inDecl() || inDeclGroup() || inSizeOfTypeVA()); + assert (inDeclGroup() || inSizeOfTypeVA()); RawVAPtr = reinterpret_cast(P) | (RawVAPtr & Flags); } @@ -67,11 +64,10 @@ protected: Stmt*& GetDeclExpr() const; - StmtIteratorBase(Stmt **s) : stmt(s), decl(0), RawVAPtr(0) {} - StmtIteratorBase(Decl *d, Stmt **s); + StmtIteratorBase(Stmt **s) : stmt(s), DGI(0), RawVAPtr(0) {} StmtIteratorBase(const VariableArrayType *t); StmtIteratorBase(Decl **dgi, Decl **dge); - StmtIteratorBase() : stmt(0), decl(0), RawVAPtr(0) {} + StmtIteratorBase() : stmt(0), DGI(0), RawVAPtr(0) {} }; @@ -86,7 +82,6 @@ public: StmtIteratorImpl() {} StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {} StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {} - StmtIteratorImpl(Decl *d, Stmt **s) : StmtIteratorBase(d, s) {} StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {} DERIVED& operator++() { @@ -107,15 +102,15 @@ public: } bool operator==(const DERIVED& RHS) const { - return stmt == RHS.stmt && decl == RHS.decl && RawVAPtr == RHS.RawVAPtr; + return stmt == RHS.stmt && DGI == RHS.DGI && RawVAPtr == RHS.RawVAPtr; } bool operator!=(const DERIVED& RHS) const { - return stmt != RHS.stmt || decl != RHS.decl || RawVAPtr != RHS.RawVAPtr; + return stmt != RHS.stmt || DGI != RHS.DGI || RawVAPtr != RHS.RawVAPtr; } REFERENCE operator*() const { - return (REFERENCE) (inStmt() ? *stmt : GetDeclExpr()); + return inStmt() ? *stmt : GetDeclExpr(); } REFERENCE operator->() const { return operator*(); } @@ -131,9 +126,6 @@ struct StmtIterator : public StmtIteratorImpl { StmtIterator(const VariableArrayType *t) : StmtIteratorImpl(t) {} - - StmtIterator(Decl* D, Stmt **s = 0) - : StmtIteratorImpl(D, s) {} }; struct ConstStmtIterator : public StmtIteratorImpl { : std::pair(begin, end) {} bool empty() const { return first == second; } - operator bool() const { return !empty(); } + LLVM_EXPLICIT operator bool() const { return !empty(); } Stmt *operator->() const { return first.operator->(); } Stmt *&operator*() const { return first.operator*(); } @@ -199,7 +191,7 @@ struct ConstStmtRange : std::pair { : std::pair(begin, end) {} bool empty() const { return first == second; } - operator bool() const { return !empty(); } + LLVM_EXPLICIT operator bool() const { return !empty(); } const Stmt *operator->() const { return first.operator->(); } const Stmt *operator*() const { return first.operator*(); } diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h b/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h index e97c1a5..bfb4a9b 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h @@ -181,13 +181,12 @@ private: HasFinally(HasFinally) { } public: - static ObjCAtTryStmt *Create(ASTContext &Context, SourceLocation atTryLoc, - Stmt *atTryStmt, + static ObjCAtTryStmt *Create(const ASTContext &Context, + SourceLocation atTryLoc, Stmt *atTryStmt, Stmt **CatchStmts, unsigned NumCatchStmts, Stmt *atFinallyStmt); - static ObjCAtTryStmt *CreateEmpty(ASTContext &Context, - unsigned NumCatchStmts, - bool HasFinally); + static ObjCAtTryStmt *CreateEmpty(const ASTContext &Context, + unsigned NumCatchStmts, bool HasFinally); /// \brief Retrieve the location of the @ in the \@try. SourceLocation getAtTryLoc() const { return AtTryLoc; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtOpenMP.h b/contrib/llvm/tools/clang/include/clang/AST/StmtOpenMP.h new file mode 100644 index 0000000..8570d88 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtOpenMP.h @@ -0,0 +1,528 @@ +//===- StmtOpenMP.h - Classes for OpenMP directives and clauses --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// \brief This file defines OpenMP AST classes for executable directives and +/// clauses. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_STMTOPENMP_H +#define LLVM_CLANG_AST_STMTOPENMP_H + +#include "clang/Basic/OpenMPKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/AST/Expr.h" +#include "clang/AST/Stmt.h" + +namespace clang { + +//===----------------------------------------------------------------------===// +// AST classes for clauses. +//===----------------------------------------------------------------------===// + +/// \brief This is a basic class for representing single OpenMP clause. +/// +class OMPClause { + /// \brief Starting location of the clause (the clause keyword). + SourceLocation StartLoc; + /// \brief Ending location of the clause. + SourceLocation EndLoc; + /// \brief Kind of the clause. + OpenMPClauseKind Kind; +protected: + OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc) + : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {} + +public: + + /// \brief Returns the starting location of the clause. + SourceLocation getLocStart() const { return StartLoc; } + /// \brief Returns the ending location of the clause. + SourceLocation getLocEnd() const { return EndLoc; } + + /// \brief Sets the starting location of the clause. + void setLocStart(SourceLocation Loc) { StartLoc = Loc; } + /// \brief Sets the ending location of the clause. + void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } + + /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.). + OpenMPClauseKind getClauseKind() const { return Kind; } + + bool isImplicit() const { return StartLoc.isInvalid();} + + StmtRange children(); + ConstStmtRange children() const { + return const_cast(this)->children(); + } + static bool classof(const OMPClause *T) { + return true; + } +}; + +/// \brief This represents clauses with the list of variables like 'private', +/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the +/// '#pragma omp ...' directives. +template +class OMPVarList { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief Number of variables in the list. + unsigned NumVars; +protected: + /// \brief Fetches list of variables associated with this clause. + llvm::MutableArrayRef getVarRefs() { + return llvm::MutableArrayRef( + reinterpret_cast(static_cast(this) + 1), + NumVars); + } + + /// \brief Sets the list of variables for this clause. + void setVarRefs(ArrayRef VL) { + assert(VL.size() == NumVars && + "Number of variables is not the same as the preallocated buffer"); + std::copy(VL.begin(), VL.end(), + reinterpret_cast(static_cast(this) + 1)); + } + + /// \brief Build clause with number of variables \a N. + /// + /// \param N Number of the variables in the clause. + /// + OMPVarList(SourceLocation LParenLoc, unsigned N) + : LParenLoc(LParenLoc), NumVars(N) { } +public: + typedef llvm::MutableArrayRef::iterator varlist_iterator; + typedef ArrayRef::iterator varlist_const_iterator; + + unsigned varlist_size() const { return NumVars; } + bool varlist_empty() const { return NumVars == 0; } + varlist_iterator varlist_begin() { return getVarRefs().begin(); } + varlist_iterator varlist_end() { return getVarRefs().end(); } + varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); } + varlist_const_iterator varlist_end() const { return getVarRefs().end(); } + + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// \brief Fetches list of all variables in the clause. + ArrayRef getVarRefs() const { + return ArrayRef( + reinterpret_cast(static_cast(this) + 1), + NumVars); + } +}; + +/// \brief This represents 'default' clause in the '#pragma omp ...' directive. +/// +/// \code +/// #pragma omp parallel default(shared) +/// \endcode +/// In this example directive '#pragma omp parallel' has simple 'default' +/// clause with kind 'shared'. +/// +class OMPDefaultClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief A kind of the 'default' clause. + OpenMPDefaultClauseKind Kind; + /// \brief Start location of the kind in source code. + SourceLocation KindKwLoc; + + /// \brief Set kind of the clauses. + /// + /// \param K Argument of clause. + /// + void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; } + + /// \brief Set argument location. + /// + /// \param KLoc Argument location. + /// + void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; } +public: + /// \brief Build 'default' clause with argument \a A ('none' or 'shared'). + /// + /// \param A Argument of the clause ('none' or 'shared'). + /// \param ALoc Starting location of the argument. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// + OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc), + Kind(A), KindKwLoc(ALoc) { } + + /// \brief Build an empty clause. + /// + OMPDefaultClause() + : OMPClause(OMPC_default, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown), + KindKwLoc(SourceLocation()) { } + + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// \brief Returns kind of the clause. + OpenMPDefaultClauseKind getDefaultKind() const { return Kind; } + + /// \brief Returns location of clause kind. + SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_default; + } + + StmtRange children() { + return StmtRange(); + } +}; + +/// \brief This represents clause 'private' in the '#pragma omp ...' directives. +/// +/// \code +/// #pragma omp parallel private(a,b) +/// \endcode +/// In this example directive '#pragma omp parallel' has clause 'private' +/// with the variables 'a' and 'b'. +/// +class OMPPrivateClause : public OMPClause, public OMPVarList { + /// \brief Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + /// + OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPClause(OMPC_private, StartLoc, EndLoc), + OMPVarList(LParenLoc, N) { } + + /// \brief Build an empty clause. + /// + /// \param N Number of variables. + /// + explicit OMPPrivateClause(unsigned N) + : OMPClause(OMPC_private, SourceLocation(), SourceLocation()), + OMPVarList(SourceLocation(), N) { } +public: + /// \brief Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the variables. + /// + static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, + ArrayRef VL); + /// \brief Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + /// + static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N); + + StmtRange children() { + return StmtRange(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end())); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_private; + } +}; + +/// \brief This represents clause 'firstprivate' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp parallel firstprivate(a,b) +/// \endcode +/// In this example directive '#pragma omp parallel' has clause 'firstprivate' +/// with the variables 'a' and 'b'. +/// +class OMPFirstprivateClause : public OMPClause, + public OMPVarList { + /// \brief Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + /// + OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPClause(OMPC_firstprivate, StartLoc, EndLoc), + OMPVarList(LParenLoc, N) { } + + /// \brief Build an empty clause. + /// + /// \param N Number of variables. + /// + explicit OMPFirstprivateClause(unsigned N) + : OMPClause(OMPC_firstprivate, SourceLocation(), SourceLocation()), + OMPVarList(SourceLocation(), N) { } +public: + /// \brief Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the variables. + /// + static OMPFirstprivateClause *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, + ArrayRef VL); + /// \brief Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + /// + static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N); + + StmtRange children() { + return StmtRange(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end())); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_firstprivate; + } +}; + +/// \brief This represents clause 'shared' in the '#pragma omp ...' directives. +/// +/// \code +/// #pragma omp parallel shared(a,b) +/// \endcode +/// In this example directive '#pragma omp parallel' has clause 'shared' +/// with the variables 'a' and 'b'. +/// +class OMPSharedClause : public OMPClause, public OMPVarList { + /// \brief Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + /// + OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPClause(OMPC_shared, StartLoc, EndLoc), + OMPVarList(LParenLoc, N) { } + + /// \brief Build an empty clause. + /// + /// \param N Number of variables. + /// + explicit OMPSharedClause(unsigned N) + : OMPClause(OMPC_shared, SourceLocation(), SourceLocation()), + OMPVarList(SourceLocation(), N) { } +public: + /// \brief Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the variables. + /// + static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef VL); + /// \brief Creates an empty clause with \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + /// + static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N); + + StmtRange children() { + return StmtRange(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end())); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_shared; + } +}; + +//===----------------------------------------------------------------------===// +// AST classes for directives. +//===----------------------------------------------------------------------===// + +/// \brief This is a basic class for representing single OpenMP executable +/// directive. +/// +class OMPExecutableDirective : public Stmt { + friend class ASTStmtReader; + /// \brief Kind of the directive. + OpenMPDirectiveKind Kind; + /// \brief Starting location of the directive (directive keyword). + SourceLocation StartLoc; + /// \brief Ending location of the directive. + SourceLocation EndLoc; + /// \brief Pointer to the list of clauses. + llvm::MutableArrayRef Clauses; + /// \brief Associated statement (if any) and expressions. + llvm::MutableArrayRef StmtAndExpressions; +protected: + /// \brief Build instance of directive of class \a K. + /// + /// \param SC Statement class. + /// \param K Kind of OpenMP directive. + /// \param StartLoc Starting location of the directive (directive keyword). + /// \param EndLoc Ending location of the directive. + /// + template + OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K, + SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses, unsigned NumberOfExpressions) + : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc), + Clauses(reinterpret_cast(static_cast(this) + 1), + NumClauses), + StmtAndExpressions(reinterpret_cast(Clauses.end()), + NumberOfExpressions) { } + + /// \brief Sets the list of variables for this clause. + /// + /// \param Clauses The list of clauses for the directive. + /// + void setClauses(ArrayRef Clauses); + + /// \brief Set the associated statement for the directive. + /// + /// /param S Associated statement. + /// + void setAssociatedStmt(Stmt *S) { + StmtAndExpressions[0] = S; + } + +public: + /// \brief Returns starting location of directive kind. + SourceLocation getLocStart() const { return StartLoc; } + /// \brief Returns ending location of directive. + SourceLocation getLocEnd() const { return EndLoc; } + + /// \brief Set starting location of directive kind. + /// + /// \param Loc New starting location of directive. + /// + void setLocStart(SourceLocation Loc) { StartLoc = Loc; } + /// \brief Set ending location of directive. + /// + /// \param Loc New ending location of directive. + /// + void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } + + /// \brief Get number of clauses. + unsigned getNumClauses() const { return Clauses.size(); } + + /// \brief Returns specified clause. + /// + /// \param i Number of clause. + /// + OMPClause *getClause(unsigned i) const { + assert(i < Clauses.size() && "index out of bound!"); + return Clauses[i]; + } + + /// \brief Returns statement associated with the directive. + Stmt *getAssociatedStmt() const { + return StmtAndExpressions[0]; + } + + OpenMPDirectiveKind getDirectiveKind() const { return Kind; } + + static bool classof(const Stmt *S) { + return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && + S->getStmtClass() <= lastOMPExecutableDirectiveConstant; + } + + child_range children() { + return child_range(StmtAndExpressions.begin(), StmtAndExpressions.end()); + } + + ArrayRef clauses() { return Clauses; } + + ArrayRef clauses() const { return Clauses; } +}; + +/// \brief This represents '#pragma omp parallel' directive. +/// +/// \code +/// #pragma omp parallel private(a,b) reduction(+: c,d) +/// \endcode +/// In this example directive '#pragma omp parallel' has clauses 'private' +/// with the variables 'a' and 'b' and 'reduction' with operator '+' and +/// variables 'c' and 'd'. +/// +class OMPParallelDirective : public OMPExecutableDirective { + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive (directive keyword). + /// \param EndLoc Ending Location of the directive. + /// + OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned N) + : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, + StartLoc, EndLoc, N, 1) { } + + /// \brief Build an empty directive. + /// + /// \param N Number of clauses. + /// + explicit OMPParallelDirective(unsigned N) + : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, + SourceLocation(), SourceLocation(), N, 1) { } +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement associated with the directive. + /// + static OMPParallelDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef Clauses, + Stmt *AssociatedStmt); + + /// \brief Creates an empty directive with the place for \a N clauses. + /// + /// \param C AST context. + /// \param N The number of clauses. + /// + static OMPParallelDirective *CreateEmpty(const ASTContext &C, unsigned N, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPParallelDirectiveClass; + } +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h index 38c4c02..c71af38 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h @@ -18,6 +18,7 @@ #include "clang/AST/ExprObjC.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" +#include "clang/AST/StmtOpenMP.h" namespace clang { @@ -184,6 +185,41 @@ template class ConstStmtVisitor : public StmtVisitorBase {}; +/// \brief This class implements a simple visitor for OMPClause +/// subclasses. +template class Ptr, typename RetTy> +class OMPClauseVisitorBase { +public: +#define PTR(CLASS) typename Ptr::type +#define DISPATCH(CLASS) \ + return static_cast(this)->Visit##CLASS(static_cast(S)) + +#define OPENMP_CLAUSE(Name, Class) \ + RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); } +#include "clang/Basic/OpenMPKinds.def" + + RetTy Visit(PTR(OMPClause) S) { + // Top switch clause: visit each OMPClause. + switch (S->getClauseKind()) { + default: llvm_unreachable("Unknown clause kind!"); +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_ ## Name : return Visit ## Class(static_cast(S)); +#include "clang/Basic/OpenMPKinds.def" + } + } + // Base case, ignore it. :) + RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); } +#undef PTR +#undef DISPATCH +}; + +template +class OMPClauseVisitor : + public OMPClauseVisitorBase {}; +template +class ConstOMPClauseVisitor : + public OMPClauseVisitorBase {}; + } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h b/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h index 70b934f..6c40eb1 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h @@ -60,8 +60,8 @@ public: /// The template argument is a pack expansion of a template name that was /// provided for a template template parameter. TemplateExpansion, - /// The template argument is a value- or type-dependent expression - /// stored in an Expr*. + /// The template argument is a value- or type-dependent expression or a + /// non-dependent __uuidof expression stored in an Expr*. Expression, /// The template argument is actually a parameter pack. Arguments are stored /// in the Args struct. @@ -70,57 +70,68 @@ public: private: /// \brief The kind of template argument we're storing. - unsigned Kind; struct DA { - ValueDecl *D; + unsigned Kind; bool ForRefParam; + ValueDecl *D; }; struct I { + unsigned Kind; // We store a decomposed APSInt with the data allocated by ASTContext if // BitWidth > 64. The memory may be shared between multiple // TemplateArgument instances. + unsigned BitWidth : 31; + unsigned IsUnsigned : 1; union { uint64_t VAL; ///< Used to store the <= 64 bits integer value. const uint64_t *pVal; ///< Used to store the >64 bits integer value. }; - unsigned BitWidth : 31; - unsigned IsUnsigned : 1; void *Type; }; struct A { - const TemplateArgument *Args; + unsigned Kind; unsigned NumArgs; + const TemplateArgument *Args; }; struct TA { - void *Name; + unsigned Kind; unsigned NumExpansions; + void *Name; + }; + struct TV { + unsigned Kind; + uintptr_t V; }; union { struct DA DeclArg; struct I Integer; struct A Args; struct TA TemplateArg; - uintptr_t TypeOrValue; + struct TV TypeOrValue; }; TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION; public: /// \brief Construct an empty, invalid template argument. - TemplateArgument() : Kind(Null), TypeOrValue(0) { } + TemplateArgument() { + TypeOrValue.Kind = Null; + TypeOrValue.V = 0; + } /// \brief Construct a template type argument. - TemplateArgument(QualType T, bool isNullPtr = false) - : Kind(isNullPtr ? NullPtr : Type) { - TypeOrValue = reinterpret_cast(T.getAsOpaquePtr()); + TemplateArgument(QualType T, bool isNullPtr = false) { + TypeOrValue.Kind = isNullPtr ? NullPtr : Type; + TypeOrValue.V = reinterpret_cast(T.getAsOpaquePtr()); } /// \brief Construct a template argument that refers to a /// declaration, which is either an external declaration or a /// template declaration. - TemplateArgument(ValueDecl *D, bool ForRefParam) : Kind(Declaration) { + TemplateArgument(ValueDecl *D, bool ForRefParam) { assert(D && "Expected decl"); + DeclArg.Kind = Declaration; DeclArg.D = D; DeclArg.ForRefParam = ForRefParam; } @@ -131,8 +142,7 @@ public: /// \brief Construct an integral constant template argument with the same /// value as Other but a different type. - TemplateArgument(const TemplateArgument &Other, QualType Type) - : Kind(Integral) { + TemplateArgument(const TemplateArgument &Other, QualType Type) { Integer = Other.Integer; Integer.Type = Type.getAsOpaquePtr(); } @@ -145,8 +155,8 @@ public: /// is taken. /// /// \param Name The template name. - TemplateArgument(TemplateName Name) : Kind(Template) - { + TemplateArgument(TemplateName Name) { + TemplateArg.Kind = Template; TemplateArg.Name = Name.getAsVoidPointer(); TemplateArg.NumExpansions = 0; } @@ -162,9 +172,8 @@ public: /// /// \param NumExpansions The number of expansions that will be generated by /// instantiating - TemplateArgument(TemplateName Name, Optional NumExpansions) - : Kind(TemplateExpansion) - { + TemplateArgument(TemplateName Name, Optional NumExpansions) { + TemplateArg.Kind = TemplateExpansion; TemplateArg.Name = Name.getAsVoidPointer(); if (NumExpansions) TemplateArg.NumExpansions = *NumExpansions + 1; @@ -177,15 +186,17 @@ public: /// This form of template argument only occurs in template argument /// lists used for dependent types and for expression; it will not /// occur in a non-dependent, canonical template argument list. - TemplateArgument(Expr *E) : Kind(Expression) { - TypeOrValue = reinterpret_cast(E); + TemplateArgument(Expr *E) { + TypeOrValue.Kind = Expression; + TypeOrValue.V = reinterpret_cast(E); } /// \brief Construct a template argument that is a template argument pack. /// /// We assume that storage for the template arguments provided /// outlives the TemplateArgument itself. - TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) : Kind(Pack){ + TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) { + this->Args.Kind = Pack; this->Args.Args = Args; this->Args.NumArgs = NumArgs; } @@ -201,10 +212,10 @@ public: unsigned NumArgs); /// \brief Return the kind of stored template argument. - ArgKind getKind() const { return (ArgKind)Kind; } + ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; } /// \brief Determine whether this template argument has no value. - bool isNull() const { return Kind == Null; } + bool isNull() const { return getKind() == Null; } /// \brief Whether this template argument is dependent on a template /// parameter such that its result can change from one instantiation to @@ -224,40 +235,40 @@ public: /// \brief Retrieve the type for a type template argument. QualType getAsType() const { - assert(Kind == Type && "Unexpected kind"); - return QualType::getFromOpaquePtr(reinterpret_cast(TypeOrValue)); + assert(getKind() == Type && "Unexpected kind"); + return QualType::getFromOpaquePtr(reinterpret_cast(TypeOrValue.V)); } /// \brief Retrieve the declaration for a declaration non-type /// template argument. ValueDecl *getAsDecl() const { - assert(Kind == Declaration && "Unexpected kind"); + assert(getKind() == Declaration && "Unexpected kind"); return DeclArg.D; } /// \brief Retrieve whether a declaration is binding to a /// reference parameter in a declaration non-type template argument. bool isDeclForReferenceParam() const { - assert(Kind == Declaration && "Unexpected kind"); + assert(getKind() == Declaration && "Unexpected kind"); return DeclArg.ForRefParam; } /// \brief Retrieve the type for null non-type template argument. QualType getNullPtrType() const { - assert(Kind == NullPtr && "Unexpected kind"); - return QualType::getFromOpaquePtr(reinterpret_cast(TypeOrValue)); + assert(getKind() == NullPtr && "Unexpected kind"); + return QualType::getFromOpaquePtr(reinterpret_cast(TypeOrValue.V)); } /// \brief Retrieve the template name for a template name argument. TemplateName getAsTemplate() const { - assert(Kind == Template && "Unexpected kind"); + assert(getKind() == Template && "Unexpected kind"); return TemplateName::getFromVoidPointer(TemplateArg.Name); } /// \brief Retrieve the template argument as a template name; if the argument /// is a pack expansion, return the pattern as a template name. TemplateName getAsTemplateOrTemplatePattern() const { - assert((Kind == Template || Kind == TemplateExpansion) && + assert((getKind() == Template || getKind() == TemplateExpansion) && "Unexpected kind"); return TemplateName::getFromVoidPointer(TemplateArg.Name); @@ -270,7 +281,7 @@ public: /// \brief Retrieve the template argument as an integral value. // FIXME: Provide a way to read the integral data without copying the value. llvm::APSInt getAsIntegral() const { - assert(Kind == Integral && "Unexpected kind"); + assert(getKind() == Integral && "Unexpected kind"); using namespace llvm; if (Integer.BitWidth <= 64) return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); @@ -282,19 +293,19 @@ public: /// \brief Retrieve the type of the integral value. QualType getIntegralType() const { - assert(Kind == Integral && "Unexpected kind"); + assert(getKind() == Integral && "Unexpected kind"); return QualType::getFromOpaquePtr(Integer.Type); } void setIntegralType(QualType T) { - assert(Kind == Integral && "Unexpected kind"); + assert(getKind() == Integral && "Unexpected kind"); Integer.Type = T.getAsOpaquePtr(); } /// \brief Retrieve the template argument as an expression. Expr *getAsExpr() const { - assert(Kind == Expression && "Unexpected kind"); - return reinterpret_cast(TypeOrValue); + assert(getKind() == Expression && "Unexpected kind"); + return reinterpret_cast(TypeOrValue.V); } /// \brief Iterator that traverses the elements of a template argument pack. @@ -303,27 +314,27 @@ public: /// \brief Iterator referencing the first argument of a template argument /// pack. pack_iterator pack_begin() const { - assert(Kind == Pack); + assert(getKind() == Pack); return Args.Args; } /// \brief Iterator referencing one past the last argument of a template /// argument pack. pack_iterator pack_end() const { - assert(Kind == Pack); + assert(getKind() == Pack); return Args.Args + Args.NumArgs; } /// \brief The number of template arguments in the given template argument /// pack. unsigned pack_size() const { - assert(Kind == Pack); + assert(getKind() == Pack); return Args.NumArgs; } /// \brief Return the array of arguments in this template argument pack. llvm::ArrayRef getPackAsArray() const { - assert(Kind == Pack); + assert(getKind() == Pack); return llvm::ArrayRef(Args.Args, Args.NumArgs); } @@ -494,17 +505,6 @@ public: assert(Argument.getKind() == TemplateArgument::TemplateExpansion); return LocInfo.getTemplateEllipsisLoc(); } - - /// \brief When the template argument is a pack expansion, returns - /// the pattern of the pack expansion. - /// - /// \param Ellipsis Will be set to the location of the ellipsis. - /// - /// \param NumExpansions Will be set to the number of expansions that will - /// be generated from this pack expansion, if known a priori. - TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis, - Optional &NumExpansions, - ASTContext &Context) const; }; /// A convenient class for passing around template argument diff --git a/contrib/llvm/tools/clang/include/clang/AST/Type.h b/contrib/llvm/tools/clang/include/clang/AST/Type.h index 04d715c..fb829e4 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Type.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Type.h @@ -441,7 +441,7 @@ public: bool operator==(Qualifiers Other) const { return Mask == Other.Mask; } bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; } - operator bool() const { return hasQualifiers(); } + LLVM_EXPLICIT operator bool() const { return hasQualifiers(); } Qualifiers &operator+=(Qualifiers R) { addQualifiers(R); @@ -818,7 +818,7 @@ public: /// an lvalue. It removes a top-level reference (since there are no /// expressions of reference type) and deletes top-level cvr-qualifiers /// from non-class types (in C++) or all types (in C). - QualType getNonLValueExprType(ASTContext &Context) const; + QualType getNonLValueExprType(const ASTContext &Context) const; /// getDesugaredType - Return the specified type with any "sugar" removed from /// the type. This takes off typedefs, typeof's etc. If the outer level of @@ -1194,7 +1194,7 @@ private: mutable unsigned CacheValid : 1; /// \brief Linkage of this type. - mutable unsigned CachedLinkage : 2; + mutable unsigned CachedLinkage : 3; /// \brief Whether this type involves and local or unnamed types. mutable unsigned CachedLocalOrUnnamed : 1; @@ -1214,7 +1214,7 @@ private: return CachedLocalOrUnnamed; } }; - enum { NumTypeBits = 19 }; + enum { NumTypeBits = 18 }; protected: // These classes allow subclasses to somewhat cleanly pack bitfields @@ -1315,6 +1315,8 @@ protected: /// NumElements - The number of elements in the vector. unsigned NumElements : 29 - NumTypeBits; + + enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 }; }; class AttributedTypeBitfields { @@ -1454,7 +1456,7 @@ public: /// isLiteralType - Return true if this is a literal type /// (C++11 [basic.types]p10) - bool isLiteralType(ASTContext &Ctx) const; + bool isLiteralType(const ASTContext &Ctx) const; /// \brief Test if this type is a standard-layout type. /// (C++0x [basic.type]p9) @@ -1512,7 +1514,6 @@ public: bool isRealType() const; // C99 6.2.5p17 (real floating + integer) bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) bool isVoidType() const; // C99 6.2.5p19 - bool isDerivedType() const; // C99 6.2.5p20 bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers) bool isAggregateType() const; bool isFundamentalType() const; @@ -1811,6 +1812,10 @@ template <> const TypedefType *Type::getAs() const; /// non-sugared type. template <> const TemplateSpecializationType *Type::getAs() const; +/// \brief This will check for an AttributedType by removing any existing sugar +/// until it reaches an AttributedType or a non-sugared type. +template <> const AttributedType *Type::getAs() const; + // We can do canonical leaf types faster, because we don't have to // worry about preserving child type decoration. #define TYPE(Class, Base) @@ -1991,6 +1996,44 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } }; +/// \brief Represents a pointer type decayed from an array or function type. +class DecayedType : public Type, public llvm::FoldingSetNode { + QualType OriginalType; + QualType DecayedPointer; + + DecayedType(QualType OriginalType, QualType DecayedPointer, + QualType CanonicalPtr) + : Type(Decayed, CanonicalPtr, OriginalType->isDependentType(), + OriginalType->isInstantiationDependentType(), + OriginalType->isVariablyModifiedType(), + OriginalType->containsUnexpandedParameterPack()), + OriginalType(OriginalType), DecayedPointer(DecayedPointer) { + assert(isa(DecayedPointer)); + } + + friend class ASTContext; // ASTContext creates these. + +public: + QualType getDecayedType() const { return DecayedPointer; } + QualType getOriginalType() const { return OriginalType; } + + QualType getPointeeType() const { + return cast(DecayedPointer)->getPointeeType(); + } + + bool isSugared() const { return true; } + QualType desugar() const { return DecayedPointer; } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, OriginalType); + } + static void Profile(llvm::FoldingSetNodeID &ID, QualType OriginalType) { + ID.AddPointer(OriginalType.getAsOpaquePtr()); + } + + static bool classof(const Type *T) { return T->getTypeClass() == Decayed; } +}; + /// BlockPointerType - pointer to a block type. /// This type is to represent types syntactically represented as /// "void (^)(int)", etc. Pointee is required to always be a function type. @@ -2487,6 +2530,9 @@ public: QualType getElementType() const { return ElementType; } unsigned getNumElements() const { return VectorTypeBits.NumElements; } + static bool isVectorSizeTooLarge(unsigned NumElements) { + return NumElements > VectorTypeBitfields::MaxNumElements; + } bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2641,7 +2687,11 @@ class FunctionType : public Type { // Constructor with all defaults. Use when for example creating a // function know to use defaults. - ExtInfo() : Bits(0) {} + ExtInfo() : Bits(CC_C) { } + + // Constructor with just the calling convention, which is an important part + // of the canonical type. + ExtInfo(CallingConv CC) : Bits(CC) { } bool getNoReturn() const { return Bits & NoReturnMask; } bool getProducesResult() const { return Bits & ProducesResultMask; } @@ -2784,6 +2834,12 @@ public: ExceptionSpecDecl(0), ExceptionSpecTemplate(0), ConsumedArguments(0) {} + ExtProtoInfo(CallingConv CC) + : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0), + ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0), + Exceptions(0), NoexceptExpr(0), ExceptionSpecDecl(0), + ExceptionSpecTemplate(0), ConsumedArguments(0) {} + FunctionType::ExtInfo ExtInfo; bool Variadic : 1; bool HasTrailingReturn : 1; @@ -2928,7 +2984,7 @@ public: NR_Nothrow ///< The noexcept specifier evaluates to true. }; /// \brief Get the meaning of the noexcept spec on this function, if any. - NoexceptResult getNoexceptSpec(ASTContext &Ctx) const; + NoexceptResult getNoexceptSpec(const ASTContext &Ctx) const; unsigned getNumExceptions() const { return NumExceptions; } QualType getExceptionType(unsigned i) const { assert(i < NumExceptions && "Invalid exception number!"); @@ -2959,7 +3015,7 @@ public: return 0; return reinterpret_cast(arg_type_end())[1]; } - bool isNothrow(ASTContext &Ctx) const { + bool isNothrow(const ASTContext &Ctx) const { ExceptionSpecificationType EST = getExceptionSpecType(); assert(EST != EST_Unevaluated && EST != EST_Uninstantiated); if (EST == EST_DynamicNone || EST == EST_BasicNoexcept) @@ -3323,9 +3379,10 @@ public: attr_objc_gc, attr_objc_ownership, attr_pcs, + attr_pcs_vfp, FirstEnumOperandKind = attr_objc_gc, - LastEnumOperandKind = attr_pcs, + LastEnumOperandKind = attr_pcs_vfp, // No operand. attr_noreturn, @@ -3337,7 +3394,11 @@ public: attr_pnaclcall, attr_inteloclbicc, attr_ms_abi, - attr_sysv_abi + attr_sysv_abi, + attr_ptr32, + attr_ptr64, + attr_sptr, + attr_uptr }; private: @@ -3367,6 +3428,10 @@ public: bool isSugared() const { return true; } QualType desugar() const { return getEquivalentType(); } + bool isMSTypeSpec() const; + + bool isCallingConv() const; + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getAttrKind(), ModifiedType, EquivalentType); } @@ -3565,10 +3630,13 @@ public: /// is no deduced type and an auto type is canonical. In the latter case, it is /// also a dependent type. class AutoType : public Type, public llvm::FoldingSetNode { - AutoType(QualType DeducedType, bool IsDecltypeAuto, bool IsDependent) + AutoType(QualType DeducedType, bool IsDecltypeAuto, + bool IsDependent) : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType, /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent, - /*VariablyModified=*/false, /*ContainsParameterPack=*/false) { + /*VariablyModified=*/false, + /*ContainsParameterPack=*/DeducedType.isNull() + ? false : DeducedType->containsUnexpandedParameterPack()) { assert((DeducedType.isNull() || !IsDependent) && "auto deduced to dependent type"); AutoTypeBits.IsDecltypeAuto = IsDecltypeAuto; @@ -3592,7 +3660,8 @@ public: } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getDeducedType(), isDecltypeAuto(), isDependentType()); + Profile(ID, getDeducedType(), isDecltypeAuto(), + isDependentType()); } static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced, @@ -3656,10 +3725,6 @@ class TemplateSpecializationType public: /// \brief Determine whether any of the given template arguments are /// dependent. - static bool anyDependentTemplateArguments(const TemplateArgument *Args, - unsigned NumArgs, - bool &InstantiationDependent); - static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned NumArgs, bool &InstantiationDependent); @@ -4156,8 +4221,8 @@ public: return None; } - bool isSugared() const { return false; } - QualType desugar() const { return QualType(this, 0); } + bool isSugared() const { return !Pattern->isDependentType(); } + QualType desugar() const { return isSugared() ? Pattern : QualType(this, 0); } void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPattern(), getNumExpansions()); @@ -4191,11 +4256,11 @@ public: /// /// 'C

' is an ObjCObjectType with base C and protocol list [P]. /// -/// 'id' is a TypedefType which is sugar for an ObjCPointerType whose +/// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose /// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType /// and no protocols. /// -/// 'id

' is an ObjCPointerType whose pointee is an ObjCObjecType +/// 'id

' is an ObjCObjectPointerType whose pointee is an ObjCObjectType /// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually /// this should get its own sugar class to better represent the source. class ObjCObjectType : public Type { @@ -4233,7 +4298,7 @@ public: /// getBaseType - Gets the base type of this object type. This is /// always (possibly sugar for) one of: /// - the 'id' builtin type (as opposed to the 'id' type visible to the - /// user, which is a typedef for an ObjCPointerType) + /// user, which is a typedef for an ObjCObjectPointerType) /// - the 'Class' builtin type (same caveat) /// - an ObjCObjectType (currently always an ObjCInterfaceType) QualType getBaseType() const { return BaseType; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h index 11cad9b..8ddfac7 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h @@ -6,9 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines the TypeLoc interface and subclasses. -// +/// +/// \file +/// \brief Defines the clang::TypeLoc interface and its subclasses. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_TYPELOC_H @@ -34,8 +35,8 @@ namespace clang { /// \brief Base wrapper for a particular "section" of type source info. /// -/// A client should use the TypeLoc subclasses through cast/dyn_cast in order to -/// get at the actual information. +/// A client should use the TypeLoc subclasses through castAs()/getAs() +/// in order to get at the actual information. class TypeLoc { protected: // The correctness of this relies on the property that, for Type *Ty, @@ -46,6 +47,8 @@ protected: public: /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc /// is of the desired type. + /// + /// \pre T::isKind(*this) template T castAs() const { assert(T::isKind(*this)); @@ -90,11 +93,15 @@ public: } bool isNull() const { return !Ty; } - operator bool() const { return Ty; } + LLVM_EXPLICIT operator bool() const { return Ty; } /// \brief Returns the size of type source info data block for the given type. static unsigned getFullDataSizeForType(QualType Ty); + /// \brief Returns the alignment of type source info data block for + /// the given type. + static unsigned getLocalAlignmentForType(QualType Ty); + /// \brief Get the type for which this source info wrapper provides /// information. QualType getType() const { @@ -229,7 +236,11 @@ public: } UnqualTypeLoc getUnqualifiedLoc() const { - return UnqualTypeLoc(getTypePtr(), Data); + unsigned align = + TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0)); + uintptr_t dataInt = reinterpret_cast(Data); + dataInt = llvm::RoundUpToAlignment(dataInt, align); + return UnqualTypeLoc(getTypePtr(), reinterpret_cast(dataInt)); } /// Initializes the local data of this type source info block to @@ -250,10 +261,11 @@ public: return 0; } - /// \brief Returns the size of the type source info data block. - unsigned getFullDataSize() const { - return getLocalDataSize() + - getFullDataSizeForType(getType().getLocalUnqualifiedType()); + /// \brief Returns the alignment of the type source info data block that is + /// specific to this type. + unsigned getLocalDataAlignment() const { + // We don't preserve any location information. + return 1; } private: @@ -280,9 +292,6 @@ inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { /// \tparam LocalData the structure type of local location data for /// this type /// -/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or -/// else the world will end. -/// /// TypeLocs with non-constant amounts of local data should override /// getExtraLocalDataSize(); getExtraLocalData() will then point to /// this extra memory. @@ -309,7 +318,8 @@ class ConcreteTypeLoc : public Base { friend class TypeLoc; static bool isKind(const TypeLoc &TL) { - return Derived::classofType(TL.getTypePtr()); + return !TL.getType().hasLocalQualifiers() && + Derived::classofType(TL.getTypePtr()); } static bool classofType(const Type *Ty) { @@ -317,12 +327,16 @@ class ConcreteTypeLoc : public Base { } public: - unsigned getLocalDataSize() const { - return sizeof(LocalData) + asDerived()->getExtraLocalDataSize(); + unsigned getLocalDataAlignment() const { + return std::max(llvm::alignOf(), + asDerived()->getExtraLocalDataAlignment()); } - // Give a default implementation that's useful for leaf types. - unsigned getFullDataSize() const { - return asDerived()->getLocalDataSize() + getInnerTypeSize(); + unsigned getLocalDataSize() const { + unsigned size = sizeof(LocalData); + unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); + size = llvm::RoundUpToAlignment(size, extraAlign); + size += asDerived()->getExtraLocalDataSize(); + return size; } TypeLoc getNextTypeLoc() const { @@ -338,6 +352,10 @@ protected: return 0; } + unsigned getExtraLocalDataAlignment() const { + return 1; + } + LocalData *getLocalData() const { return static_cast(Base::Data); } @@ -346,11 +364,17 @@ protected: /// local data that can't be captured in the Info (e.g. because it's /// of variable size). void *getExtraLocalData() const { - return getLocalData() + 1; + unsigned size = sizeof(LocalData); + unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); + size = llvm::RoundUpToAlignment(size, extraAlign); + return reinterpret_cast(Base::Data) + size; } void *getNonLocalData() const { - return static_cast(Base::Data) + asDerived()->getLocalDataSize(); + uintptr_t data = reinterpret_cast(Base::Data); + data += asDerived()->getLocalDataSize(); + data = llvm::RoundUpToAlignment(data, getNextTypeAlign()); + return reinterpret_cast(data); } struct HasNoInnerType {}; @@ -373,6 +397,18 @@ private: return getInnerTypeLoc().getFullDataSize(); } + unsigned getNextTypeAlign() const { + return getNextTypeAlign(asDerived()->getInnerType()); + } + + unsigned getNextTypeAlign(HasNoInnerType _) const { + return 1; + } + + unsigned getNextTypeAlign(QualType T) const { + return TypeLoc::getLocalAlignmentForType(T); + } + TypeLoc getNextTypeLoc(HasNoInnerType _) const { return TypeLoc(); } @@ -393,7 +429,8 @@ class InheritingConcreteTypeLoc : public Base { } static bool isKind(const TypeLoc &TL) { - return Derived::classofType(TL.getTypePtr()); + return !TL.getType().hasLocalQualifiers() && + Derived::classofType(TL.getTypePtr()); } static bool isKind(const UnqualTypeLoc &TL) { return Derived::classofType(TL.getTypePtr()); @@ -417,7 +454,8 @@ class TypeSpecTypeLoc : public ConcreteTypeLoc { public: - enum { LocalDataSize = sizeof(TypeSpecLocInfo) }; + enum { LocalDataSize = sizeof(TypeSpecLocInfo), + LocalDataAlignment = llvm::AlignOf::Alignment }; SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; @@ -448,8 +486,6 @@ class BuiltinTypeLoc : public ConcreteTypeLoc { public: - enum { LocalDataSize = sizeof(BuiltinLocInfo) }; - SourceLocation getBuiltinLoc() const { return getLocalData()->BuiltinLoc; } @@ -478,6 +514,10 @@ public: return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; } + unsigned getExtraLocalDataAlignment() const { + return needsExtraLocalData() ? llvm::alignOf() : 1; + } + SourceRange getLocalSourceRange() const { return SourceRange(getBuiltinLoc(), getBuiltinLoc()); } @@ -840,6 +880,10 @@ public: return this->getNumProtocols() * sizeof(SourceLocation); } + unsigned getExtraLocalDataAlignment() const { + return llvm::alignOf(); + } + QualType getInnerType() const { return getTypePtr()->getBaseType(); } @@ -933,6 +977,40 @@ inline TypeLoc TypeLoc::IgnoreParens() const { return *this; } + +struct DecayedLocInfo { }; // Nothing. + +/// \brief Wrapper for source info for pointers decayed from arrays and +/// functions. +class DecayedTypeLoc : public ConcreteTypeLoc { +public: + TypeLoc getOriginalLoc() const { + return getInnerTypeLoc(); + } + + void initializeLocal(ASTContext &Context, SourceLocation Loc) { + // do nothing + } + + QualType getInnerType() const { + // The inner type is the undecayed type, since that's what we have source + // location information for. + return getTypePtr()->getOriginalType(); + } + + SourceRange getLocalSourceRange() const { + return SourceRange(); + } + + unsigned getLocalDataSize() const { + // sizeof(DecayedLocInfo) is 1, but we don't need its address to be unique + // anyway. TypeLocBuilder can't handle data sizes of 1. + return 0; // No data. + } +}; + + struct PointerLikeLocInfo { SourceLocation StarLoc; }; @@ -1166,6 +1244,10 @@ public: return getNumArgs() * sizeof(ParmVarDecl*); } + unsigned getExtraLocalDataAlignment() const { + return llvm::alignOf(); + } + QualType getInnerType() const { return getTypePtr()->getResultType(); } }; @@ -1357,6 +1439,10 @@ public: return getNumArgs() * sizeof(TemplateArgumentLocInfo); } + unsigned getExtraLocalDataAlignment() const { + return llvm::alignOf(); + } + private: TemplateArgumentLocInfo *getArgInfos() const { return static_cast(getExtraLocalData()); @@ -1761,6 +1847,10 @@ public: return getNumArgs() * sizeof(TemplateArgumentLocInfo); } + unsigned getExtraLocalDataAlignment() const { + return llvm::alignOf(); + } + private: TemplateArgumentLocInfo *getArgInfos() const { return static_cast(getExtraLocalData()); diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def b/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def index 840e07d..3126f48 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def @@ -81,6 +81,7 @@ TYPE(FunctionNoProto, FunctionType) DEPENDENT_TYPE(UnresolvedUsing, Type) NON_CANONICAL_TYPE(Paren, Type) NON_CANONICAL_TYPE(Typedef, Type) +NON_CANONICAL_TYPE(Decayed, Type) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type) @@ -98,7 +99,7 @@ TYPE(Auto, Type) DEPENDENT_TYPE(InjectedClassName, Type) DEPENDENT_TYPE(DependentName, Type) DEPENDENT_TYPE(DependentTemplateSpecialization, Type) -DEPENDENT_TYPE(PackExpansion, Type) +NON_CANONICAL_UNLESS_DEPENDENT_TYPE(PackExpansion, Type) TYPE(ObjCObject, Type) TYPE(ObjCInterface, ObjCObjectType) TYPE(ObjCObjectPointer, Type) diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeOrdering.h b/contrib/llvm/tools/clang/include/clang/AST/TypeOrdering.h index 59b59f5..9c9f15e 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeOrdering.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeOrdering.h @@ -6,11 +6,14 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file provides a function objects and specializations that -// allow QualType values to be sorted, used in std::maps, std::sets, -// llvm::DenseMaps, and llvm::DenseSets. -// +/// +/// \file +/// \brief Allows QualTypes to be sorted and hence used in maps and sets. +/// +/// Defines clang::QualTypeOrdering, a total ordering on clang::QualType, +/// and hence enables QualType values to be sorted and to be used in +/// std::maps, std::sets, llvm::DenseMaps, and llvm::DenseSets. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TYPE_ORDERING_H @@ -22,8 +25,7 @@ namespace clang { -/// QualTypeOrdering - Function object that provides a total ordering -/// on QualType values. +/// \brief Function object that provides a total ordering on QualType values. struct QualTypeOrdering : std::binary_function { bool operator()(QualType T1, QualType T2) const { return std::less()(T1.getAsOpaquePtr(), T2.getAsOpaquePtr()); diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h index 242aa58..11e5a47 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h @@ -22,9 +22,50 @@ namespace clang { return static_cast(this)-> \ Visit##CLASS(static_cast(T)) +/// \brief An operation on a type. +/// +/// \tparam ImplClass Class implementing the operation. Must be inherited from +/// TypeVisitor. +/// \tparam RetTy %Type of result produced by the operation. +/// +/// The class implements polymorphic operation on an object of type derived +/// from Type. The operation is performed by calling method Visit. It then +/// dispatches the call to function \c VisitFooType, if actual argument type +/// is \c FooType. +/// +/// The class implements static polymorphism using Curiously Recurring +/// Template Pattern. It is designed to be a base class for some concrete +/// class: +/// +/// \code +/// class SomeVisitor : public TypeVisitor { ... }; +/// ... +/// Type *atype = ... +/// ... +/// SomeVisitor avisitor; +/// sometype result = avisitor.Visit(atype); +/// \endcode +/// +/// Actual treatment is made by methods of the derived class, TypeVisitor only +/// dispatches call to the appropriate method. If the implementation class +/// \c ImplClass provides specific action for some type, say +/// \c ConstantArrayType, it should define method +/// VisitConstantArrayType(const ConstantArrayType*). Otherwise +/// \c TypeVisitor dispatches call to the method that handles parent type. In +/// this example handlers are tried in the sequence: +/// +/// \li ImplClass::VisitConstantArrayType(const ConstantArrayType*) +/// \li ImplClass::VisitArrayType(const ArrayType*) +/// \li ImplClass::VisitType(const Type*) +/// \li TypeVisitor::VisitType(const Type*) +/// +/// The first function of this sequence that is defined will handle object of +/// type \c ConstantArrayType. template class TypeVisitor { public: + + /// \brief Performs the operation associated with this visitor object. RetTy Visit(const Type *T) { // Top switch stmt: dispatch to VisitFooType for each FooType. switch (T->getTypeClass()) { @@ -42,7 +83,8 @@ public: } #include "clang/AST/TypeNodes.def" - // Base case, ignore it. :) + /// \brief Method called if \c ImpClass doesn't provide specific handler + /// for some type class. RetTy VisitType(const Type*) { return RetTy(); } }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h b/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h index d26065e..759af25 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h +++ b/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h @@ -51,6 +51,7 @@ public: typedef std::iterator_traits::iterator_category iterator_category; NamedDecl *getDecl() const { return ir->getDecl(); } + void setDecl(NamedDecl *ND) const { return ir->setDecl(ND); } AccessSpecifier getAccess() const { return ir->getAccess(); } void setAccess(AccessSpecifier AS) { ir->setAccess(AS); } DeclAccessPair getPair() const { return *ir; } @@ -88,7 +89,7 @@ public: bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; } }; -/// UnresolvedSet - A set of unresolved declarations. +/// \brief A set of unresolved declarations. class UnresolvedSetImpl { typedef SmallVectorImpl DeclsTy; @@ -139,15 +140,9 @@ public: I.ir->set(New, AS); } - void erase(unsigned I) { - decls()[I] = decls().back(); - decls().pop_back(); - } + void erase(unsigned I) { decls()[I] = decls().pop_back_val(); } - void erase(iterator I) { - *I.ir = decls().back(); - decls().pop_back(); - } + void erase(iterator I) { *I.ir = decls().pop_back_val(); } void setAccess(iterator I, AccessSpecifier AS) { I.ir->setAccess(AS); @@ -177,7 +172,7 @@ private: } }; -/// A set of unresolved declarations +/// \brief A set of unresolved declarations. template class UnresolvedSet : public UnresolvedSetImpl { SmallVector Decls; diff --git a/contrib/llvm/tools/clang/include/clang/AST/VTTBuilder.h b/contrib/llvm/tools/clang/include/clang/AST/VTTBuilder.h index f24bb3f..727bf51 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/VTTBuilder.h +++ b/contrib/llvm/tools/clang/include/clang/AST/VTTBuilder.h @@ -63,54 +63,50 @@ struct VTTComponent { : VTableIndex(VTableIndex), VTableBase(VTableBase) {} }; -/// VTT builder - Class for building VTT layout information. +/// \brief Class for building VTT layout information. class VTTBuilder { ASTContext &Ctx; - /// MostDerivedClass - The most derived class for which we're building this - /// vtable. + /// \brief The most derived class for which we're building this vtable. const CXXRecordDecl *MostDerivedClass; typedef SmallVector VTTVTablesVectorTy; - /// VTTVTables - The VTT vtables. + /// \brief The VTT vtables. VTTVTablesVectorTy VTTVTables; typedef SmallVector VTTComponentsVectorTy; - /// VTTComponents - The VTT components. + /// \brief The VTT components. VTTComponentsVectorTy VTTComponents; - /// MostDerivedClassLayout - the AST record layout of the most derived class. + /// \brief The AST record layout of the most derived class. const ASTRecordLayout &MostDerivedClassLayout; typedef llvm::SmallPtrSet VisitedVirtualBasesSetTy; typedef llvm::DenseMap AddressPointsMapTy; - /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived - /// class. + /// \brief The sub-VTT indices for the bases of the most derived class. llvm::DenseMap SubVTTIndicies; - /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of - /// all subobjects of the most derived class. + /// \brief The secondary virtual pointer indices of all subobjects of + /// the most derived class. llvm::DenseMap SecondaryVirtualPointerIndices; - /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for - /// the VTT. + /// \brief Whether the VTT builder should generate LLVM IR for the VTT. bool GenerateDefinition; - /// AddVTablePointer - Add a vtable pointer to the VTT currently being built. + /// \brief Add a vtable pointer to the VTT currently being built. void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex, const CXXRecordDecl *VTableClass); - /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base - /// subobject. + /// \brief Lay out the secondary VTTs of the given base subobject. void LayoutSecondaryVTTs(BaseSubobject Base); - /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers - /// for the given base subobject. + /// \brief Lay out the secondary virtual pointers for the given base + /// subobject. /// /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base /// or a direct or indirect base of a virtual base. @@ -120,17 +116,17 @@ class VTTBuilder { const CXXRecordDecl *VTableClass, VisitedVirtualBasesSetTy &VBases); - /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers - /// for the given base subobject. + /// \brief Lay out the secondary virtual pointers for the given base + /// subobject. void LayoutSecondaryVirtualPointers(BaseSubobject Base, uint64_t VTableIndex); - /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the - /// given record decl. + /// \brief Lay out the VTTs for the virtual base classes of the given + /// record declaration. void LayoutVirtualVTTs(const CXXRecordDecl *RD, VisitedVirtualBasesSetTy &VBases); - /// LayoutVTT - Will lay out the VTT for the given subobject, including any + /// \brief Lay out the VTT for the given subobject, including any /// secondary VTTs, secondary virtual pointers and virtual VTTs. void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual); @@ -138,23 +134,22 @@ public: VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass, bool GenerateDefinition); - // getVTTComponents - Returns a reference to the VTT components. + // \brief Returns a reference to the VTT components. const VTTComponentsVectorTy &getVTTComponents() const { return VTTComponents; } - // getVTTVTables - Returns a reference to the VTT vtables. + // \brief Returns a reference to the VTT vtables. const VTTVTablesVectorTy &getVTTVTables() const { return VTTVTables; } - /// getSubVTTIndicies - Returns a reference to the sub-VTT indices. + /// \brief Returns a reference to the sub-VTT indices. const llvm::DenseMap &getSubVTTIndicies() const { return SubVTTIndicies; } - /// getSecondaryVirtualPointerIndices - Returns a reference to the secondary - /// virtual pointer indices. + /// \brief Returns a reference to the secondary virtual pointer indices. const llvm::DenseMap & getSecondaryVirtualPointerIndices() const { return SecondaryVirtualPointerIndices; diff --git a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h index bcbe875..4e45132 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h +++ b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h @@ -20,12 +20,13 @@ #include "clang/AST/RecordLayout.h" #include "clang/Basic/ABI.h" #include "llvm/ADT/SetVector.h" +#include "llvm/ADT/DenseSet.h" #include namespace clang { class CXXRecordDecl; -/// VTableComponent - Represents a single component in a vtable. +/// \brief Represents a single component in a vtable. class VTableComponent { public: enum Kind { @@ -35,15 +36,17 @@ public: CK_RTTI, CK_FunctionPointer, - /// CK_CompleteDtorPointer - A pointer to the complete destructor. + /// \brief A pointer to the complete destructor. CK_CompleteDtorPointer, - /// CK_DeletingDtorPointer - A pointer to the deleting destructor. + /// \brief A pointer to the deleting destructor. CK_DeletingDtorPointer, - /// CK_UnusedFunctionPointer - In some cases, a vtable function pointer - /// will end up never being called. Such vtable function pointers are - /// represented as a CK_UnusedFunctionPointer. + /// \brief An entry that is never used. + /// + /// In some cases, a vtable function pointer will end up never being + /// called. Such vtable function pointers are represented as a + /// CK_UnusedFunctionPointer. CK_UnusedFunctionPointer }; @@ -94,7 +97,7 @@ public: return VTableComponent(I); } - /// getKind - Get the kind of this vtable component. + /// \brief Get the kind of this vtable component. Kind getKind() const { return (Kind)(Value & 0x7); } @@ -189,7 +192,7 @@ private: /// The kind is stored in the lower 3 bits of the value. For offsets, we /// make use of the facts that classes can't be larger than 2^55 bytes, - /// so we store the offset in the lower part of the 61 bytes that remain. + /// so we store the offset in the lower part of the 61 bits that remain. /// (The reason that we're not simply using a PointerIntPair here is that we /// need the offsets to be 64-bit, even when on a 32-bit machine). int64_t Value; @@ -198,7 +201,6 @@ private: class VTableLayout { public: typedef std::pair VTableThunkTy; - typedef SmallVector ThunkInfoVectorTy; typedef const VTableComponent *vtable_component_iterator; typedef const VTableThunkTy *vtable_thunk_iterator; @@ -208,11 +210,11 @@ private: uint64_t NumVTableComponents; llvm::OwningArrayPtr VTableComponents; - /// VTableThunks - Contains thunks needed by vtables. + /// \brief Contains thunks needed by vtables, sorted by indices. uint64_t NumVTableThunks; llvm::OwningArrayPtr VTableThunks; - /// Address points - Address points for all vtables. + /// \brief Address points for all vtables. AddressPointsMapTy AddressPoints; bool IsMicrosoftABI; @@ -231,23 +233,21 @@ public: } vtable_component_iterator vtable_component_begin() const { - return VTableComponents.get(); + return VTableComponents.get(); } vtable_component_iterator vtable_component_end() const { - return VTableComponents.get()+NumVTableComponents; + return VTableComponents.get() + NumVTableComponents; } - uint64_t getNumVTableThunks() const { - return NumVTableThunks; - } + uint64_t getNumVTableThunks() const { return NumVTableThunks; } vtable_thunk_iterator vtable_thunk_begin() const { - return VTableThunks.get(); + return VTableThunks.get(); } vtable_thunk_iterator vtable_thunk_end() const { - return VTableThunks.get()+NumVTableThunks; + return VTableThunks.get() + NumVTableThunks; } uint64_t getAddressPoint(BaseSubobject Base) const { @@ -266,19 +266,45 @@ public: } }; -class VTableContext { - ASTContext &Context; - +class VTableContextBase { public: - typedef SmallVector, 1> - VTableThunksTy; typedef SmallVector ThunkInfoVectorTy; +protected: + typedef llvm::DenseMap ThunksMapTy; + + /// \brief Contains all thunks that a given method decl will need. + ThunksMapTy Thunks; + + /// Compute and store all vtable related information (vtable layout, vbase + /// offset offsets, thunks etc) for the given record decl. + virtual void computeVTableRelatedInformation(const CXXRecordDecl *RD) = 0; + + virtual ~VTableContextBase() {} + +public: + virtual const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) { + const CXXMethodDecl *MD = cast(GD.getDecl()->getCanonicalDecl()); + computeVTableRelatedInformation(MD->getParent()); + + // This assumes that all the destructors present in the vtable + // use exactly the same set of thunks. + ThunksMapTy::const_iterator I = Thunks.find(MD); + if (I == Thunks.end()) { + // We did not find a thunk for this method. + return 0; + } + + return &I->second; + } +}; + +class ItaniumVTableContext : public VTableContextBase { private: bool IsMicrosoftABI; - /// MethodVTableIndices - Contains the index (relative to the vtable address - /// point) where the function pointer for a virtual function is stored. + /// \brief Contains the index (relative to the vtable address point) + /// where the function pointer for a virtual function is stored. typedef llvm::DenseMap MethodVTableIndicesTy; MethodVTableIndicesTy MethodVTableIndices; @@ -286,49 +312,25 @@ private: VTableLayoutMapTy; VTableLayoutMapTy VTableLayouts; - /// NumVirtualFunctionPointers - Contains the number of virtual function - /// pointers in the vtable for a given record decl. - llvm::DenseMap NumVirtualFunctionPointers; - typedef std::pair ClassPairTy; - /// VirtualBaseClassOffsetOffsets - Contains the vtable offset (relative to - /// the address point) in chars where the offsets for virtual bases of a class - /// are stored. + /// \brief vtable offsets for offsets of virtual bases of a class. + /// + /// Contains the vtable offset (relative to the address point) in chars + /// where the offsets for virtual bases of a class are stored. typedef llvm::DenseMap VirtualBaseClassOffsetOffsetsMapTy; VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets; - typedef llvm::DenseMap ThunksMapTy; - - /// Thunks - Contains all thunks that a given method decl will need. - ThunksMapTy Thunks; - - void ComputeMethodVTableIndices(const CXXRecordDecl *RD); - - /// ComputeVTableRelatedInformation - Compute and store all vtable related - /// information (vtable layout, vbase offset offsets, thunks etc) for the - /// given record decl. - void ComputeVTableRelatedInformation(const CXXRecordDecl *RD); - - /// ErrorUnsupported - Print out an error that the v-table layout code - /// doesn't support the particular C++ feature yet. - void ErrorUnsupported(StringRef Feature, SourceLocation Location); + void computeVTableRelatedInformation(const CXXRecordDecl *RD); public: - VTableContext(ASTContext &Context); - ~VTableContext(); - - bool isMicrosoftABI() const { - // FIXME: Currently, this method is only used in the VTableContext and - // VTableBuilder code which is ABI-specific. Probably we can remove it - // when we add a layer of abstraction for vtable generation. - return IsMicrosoftABI; - } + ItaniumVTableContext(ASTContext &Context); + ~ItaniumVTableContext(); const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) { - ComputeVTableRelatedInformation(RD); + computeVTableRelatedInformation(RD); assert(VTableLayouts.count(RD) && "No layout for this record decl!"); return *VTableLayouts[RD]; @@ -340,36 +342,177 @@ public: bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass); - const ThunkInfoVectorTy *getThunkInfo(const CXXMethodDecl *MD) { - ComputeVTableRelatedInformation(MD->getParent()); + /// \brief Locate a virtual function in the vtable. + /// + /// Return the index (relative to the vtable address point) where the + /// function pointer for the given virtual function is stored. + uint64_t getMethodVTableIndex(GlobalDecl GD); - ThunksMapTy::const_iterator I = Thunks.find(MD); - if (I == Thunks.end()) { - // We did not find a thunk for this method. - return 0; - } + /// Return the offset in chars (relative to the vtable address point) where + /// the offset of the virtual base that contains the given base is stored, + /// otherwise, if no virtual base contains the given class, return 0. + /// + /// Base must be a virtual base class or an unambiguous base. + CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, + const CXXRecordDecl *VBase); +}; - return &I->second; +struct VFPtrInfo { + typedef SmallVector BasePath; + + // Don't pass the PathToMangle as it should be calculated later. + VFPtrInfo(CharUnits VFPtrOffset, const BasePath &PathToBaseWithVFPtr) + : VBTableIndex(0), LastVBase(0), VFPtrOffset(VFPtrOffset), + PathToBaseWithVFPtr(PathToBaseWithVFPtr), VFPtrFullOffset(VFPtrOffset) { } - /// getNumVirtualFunctionPointers - Return the number of virtual function - /// pointers in the vtable for a given record decl. - uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD); + // Don't pass the PathToMangle as it should be calculated later. + VFPtrInfo(uint64_t VBTableIndex, const CXXRecordDecl *LastVBase, + CharUnits VFPtrOffset, const BasePath &PathToBaseWithVFPtr, + CharUnits VFPtrFullOffset) + : VBTableIndex(VBTableIndex), LastVBase(LastVBase), + VFPtrOffset(VFPtrOffset), PathToBaseWithVFPtr(PathToBaseWithVFPtr), + VFPtrFullOffset(VFPtrFullOffset) { + assert(VBTableIndex && "The full constructor should only be used " + "for vfptrs in virtual bases"); + assert(LastVBase); + } - /// getMethodVTableIndex - Return the index (relative to the vtable address - /// point) where the function pointer for the given virtual function is - /// stored. - uint64_t getMethodVTableIndex(GlobalDecl GD); + /// If nonzero, holds the vbtable index of the virtual base with the vfptr. + uint64_t VBTableIndex; - /// getVirtualBaseOffsetOffset - Return the offset in chars (relative to the - /// vtable address point) where the offset of the virtual base that contains - /// the given base is stored, otherwise, if no virtual base contains the given - /// class, return 0. Base must be a virtual base class or an unambigious - /// base. - CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, - const CXXRecordDecl *VBase); + /// Stores the last vbase on the path from the complete type to the vfptr. + const CXXRecordDecl *LastVBase; + + /// This is the offset of the vfptr from the start of the last vbase, + /// or the complete type if there are no virtual bases. + CharUnits VFPtrOffset; + + /// This holds the base classes path from the complete type to the first base + /// with the given vfptr offset, in the base-to-derived order. + BasePath PathToBaseWithVFPtr; + + /// This holds the subset of records that need to be mangled into the vftable + /// symbol name in order to get a unique name, in the derived-to-base order. + BasePath PathToMangle; + + /// This is the full offset of the vfptr from the start of the complete type. + CharUnits VFPtrFullOffset; }; +class MicrosoftVTableContext : public VTableContextBase { +public: + struct MethodVFTableLocation { + /// If nonzero, holds the vbtable index of the virtual base with the vfptr. + uint64_t VBTableIndex; + + /// If nonnull, holds the last vbase which contains the vfptr that the + /// method definition is adjusted to. + const CXXRecordDecl *VBase; + + /// This is the offset of the vfptr from the start of the last vbase, or the + /// complete type if there are no virtual bases. + CharUnits VFPtrOffset; + + /// Method's index in the vftable. + uint64_t Index; + + MethodVFTableLocation() + : VBTableIndex(0), VBase(0), VFPtrOffset(CharUnits::Zero()), + Index(0) {} + + MethodVFTableLocation(uint64_t VBTableIndex, const CXXRecordDecl *VBase, + CharUnits VFPtrOffset, uint64_t Index) + : VBTableIndex(VBTableIndex), VBase(VBase), + VFPtrOffset(VFPtrOffset), Index(Index) {} + + bool operator<(const MethodVFTableLocation &other) const { + if (VBTableIndex != other.VBTableIndex) { + assert(VBase != other.VBase); + return VBTableIndex < other.VBTableIndex; + } + if (VFPtrOffset != other.VFPtrOffset) + return VFPtrOffset < other.VFPtrOffset; + if (Index != other.Index) + return Index < other.Index; + return false; + } + }; + + typedef SmallVector VFPtrListTy; + +private: + ASTContext &Context; + + typedef llvm::DenseMap + MethodVFTableLocationsTy; + MethodVFTableLocationsTy MethodVFTableLocations; + + typedef llvm::DenseMap + VFPtrLocationsMapTy; + VFPtrLocationsMapTy VFPtrLocations; + + typedef std::pair VFTableIdTy; + typedef llvm::DenseMap VFTableLayoutMapTy; + VFTableLayoutMapTy VFTableLayouts; + + typedef llvm::SmallSetVector BasesSetVectorTy; + void enumerateVFPtrs(const CXXRecordDecl *MostDerivedClass, + const ASTRecordLayout &MostDerivedClassLayout, + BaseSubobject Base, const CXXRecordDecl *LastVBase, + const VFPtrInfo::BasePath &PathFromCompleteClass, + BasesSetVectorTy &VisitedVBases, + MicrosoftVTableContext::VFPtrListTy &Result); + + void enumerateVFPtrs(const CXXRecordDecl *ForClass, + MicrosoftVTableContext::VFPtrListTy &Result); + + void computeVTableRelatedInformation(const CXXRecordDecl *RD); + + void dumpMethodLocations(const CXXRecordDecl *RD, + const MethodVFTableLocationsTy &NewMethods, + raw_ostream &); + + typedef std::pair ClassPairTy; + typedef llvm::DenseMap VBTableIndicesTy; + VBTableIndicesTy VBTableIndices; + llvm::DenseSet ComputedVBTableIndices; + + void computeVBTableRelatedInformation(const CXXRecordDecl *RD); + +public: + MicrosoftVTableContext(ASTContext &Context) : Context(Context) {} + + ~MicrosoftVTableContext() { llvm::DeleteContainerSeconds(VFTableLayouts); } + + const VFPtrListTy &getVFPtrOffsets(const CXXRecordDecl *RD); + + const VTableLayout &getVFTableLayout(const CXXRecordDecl *RD, + CharUnits VFPtrOffset); + + const MethodVFTableLocation &getMethodVFTableLocation(GlobalDecl GD); + + const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) { + // Complete destructors don't have a slot in a vftable, so no thunks needed. + if (isa(GD.getDecl()) && + GD.getDtorType() == Dtor_Complete) + return 0; + return VTableContextBase::getThunkInfo(GD); + } + + /// \brief Returns the index of VBase in the vbtable of Derived. + /// VBase must be a morally virtual base of Derived. + /// The vbtable is an array of i32 offsets. The first entry is a self entry, + /// and the rest are offsets from the vbptr to virtual bases. + unsigned getVBTableIndex(const CXXRecordDecl *Derived, + const CXXRecordDecl *VBase) { + computeVBTableRelatedInformation(Derived); + ClassPairTy Pair(Derived, VBase); + assert(VBTableIndices.count(Pair) == 1 && + "VBase must be a vbase of Derived"); + return VBTableIndices[Pair]; + } +}; } #endif diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h index 870a39b..db0a83d 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h @@ -97,6 +97,11 @@ public: /// /// Optionally override to do per translation unit tasks. virtual void onStartOfTranslationUnit() {} + + /// \brief Called at the end of each translation unit. + /// + /// Optionally override to do per translation unit tasks. + virtual void onEndOfTranslationUnit() {} }; /// \brief Called when parsing is finished. Intended for testing only. @@ -131,6 +136,17 @@ public: MatchCallback *Action); /// @} + /// \brief Adds a matcher to execute when running over the AST. + /// + /// This is similar to \c addMatcher(), but it uses the dynamic interface. It + /// is more flexible, but the lost type information enables a caller to pass + /// a matcher that cannot match anything. + /// + /// \returns \c true if the matcher is a valid top-level matcher, \c false + /// otherwise. + bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, + MatchCallback *Action); + /// \brief Creates a clang ASTConsumer that finds all matches. clang::ASTConsumer *newASTConsumer(); @@ -147,6 +163,9 @@ public: ASTContext &Context); /// @} + /// \brief Finds all matches in the given AST. + void matchAST(ASTContext &Context); + /// \brief Registers a callback to notify the end of parsing. /// /// The provided closure is called after parsing is done, before the AST is @@ -157,7 +176,7 @@ public: private: /// \brief For each \c DynTypedMatcher a \c MatchCallback that will be called /// when it matches. - std::vector > + std::vector > MatcherCallbackPairs; /// \brief Called when parsing is done. diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h index ab62dd0..0a3157d 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -45,6 +45,7 @@ #ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H #define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H +#include "clang/AST/DeclFriend.h" #include "clang/AST/DeclTemplate.h" #include "clang/ASTMatchers/ASTMatchersInternal.h" #include "clang/ASTMatchers/ASTMatchersMacros.h" @@ -85,6 +86,16 @@ public: } /// @} + /// \brief Type of mapping from binding identifiers to bound nodes. This type + /// is an associative container with a key type of \c std::string and a value + /// type of \c clang::ast_type_traits::DynTypedNode + typedef internal::BoundNodesMap::IDToNodeMap IDToNodeMap; + + /// \brief Retrieve mapping from binding identifiers to bound nodes. + const IDToNodeMap &getMap() const { + return MyBoundNodes.getMap(); + } + private: /// \brief Create BoundNodes from a pre-filled map of bindings. BoundNodes(internal::BoundNodesMap &MyBoundNodes) @@ -92,7 +103,7 @@ private: internal::BoundNodesMap MyBoundNodes; - friend class internal::BoundNodesTree; + friend class internal::BoundNodesTreeBuilder; }; /// \brief If the provided matcher matches a node, binds the node to \c ID. @@ -204,6 +215,28 @@ const internal::VariadicDynCastAllOfMatcher< Decl, ClassTemplateSpecializationDecl> classTemplateSpecializationDecl; +/// \brief Matches declarator declarations (field, variable, function +/// and non-type template parameter declarations). +/// +/// Given +/// \code +/// class X { int y; }; +/// \endcode +/// declaratorDecl() +/// matches \c int y. +const internal::VariadicDynCastAllOfMatcher + declaratorDecl; + +/// \brief Matches parameter variable declarations. +/// +/// Given +/// \code +/// void f(int x); +/// \endcode +/// parmVarDecl() +/// matches \c int x. +const internal::VariadicDynCastAllOfMatcher parmVarDecl; + /// \brief Matches C++ access specifier declarations. /// /// Given @@ -219,6 +252,17 @@ const internal::VariadicDynCastAllOfMatcher< Decl, AccessSpecDecl> accessSpecDecl; +/// \brief Matches constructor initializers. +/// +/// Examples matches \c i(42). +/// \code +/// class C { +/// C() : i(42) {} +/// int i; +/// }; +/// \endcode +const internal::VariadicAllOfMatcher ctorInitializer; + /// \brief Matches public C++ declarations. /// /// Given @@ -281,12 +325,9 @@ AST_MATCHER(Decl, isPrivate) { /// matches the specialization \c A AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument, internal::Matcher, InnerMatcher) { - const TemplateArgumentList &List = Node.getTemplateArgs(); - for (unsigned i = 0; i < List.size(); ++i) { - if (InnerMatcher.matches(List.get(i), Finder, Builder)) - return true; - } - return false; + llvm::ArrayRef List = Node.getTemplateArgs().asArray(); + return matchesFirstInRange(InnerMatcher, List.begin(), List.end(), Finder, + Builder); } /// \brief Matches expressions that match InnerMatcher after any implicit casts @@ -520,6 +561,16 @@ const internal::VariadicDynCastAllOfMatcher< Decl, FunctionTemplateDecl> functionTemplateDecl; +/// \brief Matches friend declarations. +/// +/// Given +/// \code +/// class X { friend void foo(); }; +/// \endcode +/// friendDecl() +/// matches 'friend void foo()'. +const internal::VariadicDynCastAllOfMatcher friendDecl; + /// \brief Matches statements. /// /// Given @@ -607,6 +658,21 @@ const internal::VariadicDynCastAllOfMatcher initListExpr; /// matches \code using X::x \endcode const internal::VariadicDynCastAllOfMatcher usingDecl; +/// \brief Matches unresolved using value declarations. +/// +/// Given +/// \code +/// template +/// class C : private X { +/// using X::x; +/// }; +/// \endcode +/// unresolvedUsingValueDecl() +/// matches \code using X::x \endcode +const internal::VariadicDynCastAllOfMatcher< + Decl, + UnresolvedUsingValueDecl> unresolvedUsingValueDecl; + /// \brief Matches constructor call expressions (including implicit ones). /// /// Example matches string(ptr, n) and ptr within arguments of f @@ -621,6 +687,18 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CXXConstructExpr> constructExpr; +/// \brief Matches unresolved constructor call expressions. +/// +/// Example matches T(t) in return statement of f +/// (matcher = unresolvedConstructExpr()) +/// \code +/// template +/// void f(const T& t) { return T(t); } +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + CXXUnresolvedConstructExpr> unresolvedConstructExpr; + /// \brief Matches implicit and explicit this expressions. /// /// Example matches the implicit this expression in "return i". @@ -894,6 +972,26 @@ const internal::VariadicDynCastAllOfMatcher switchStmt; /// matches 'case 42: break;' and 'default: break;'. const internal::VariadicDynCastAllOfMatcher switchCase; +/// \brief Matches case statements inside switch statements. +/// +/// Given +/// \code +/// switch(a) { case 42: break; default: break; } +/// \endcode +/// caseStmt() +/// matches 'case 42: break;'. +const internal::VariadicDynCastAllOfMatcher caseStmt; + +/// \brief Matches default statements inside switch statements. +/// +/// Given +/// \code +/// switch(a) { case 42: break; default: break; } +/// \endcode +/// defaultStmt() +/// matches 'default: break;'. +const internal::VariadicDynCastAllOfMatcher defaultStmt; + /// \brief Matches compound statements. /// /// Example matches '{}' and '{{}}'in 'for (;;) {{}}' @@ -981,15 +1079,25 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CharacterLiteral> characterLiteral; -/// \brief Matches integer literals of all sizes / encodings. -/// -/// Not matching character-encoded integers such as L'a'. +/// \brief Matches integer literals of all sizes / encodings, e.g. +/// 1, 1L, 0x1 and 1U. /// -/// Example matches 1, 1L, 0x1, 1U +/// Does not match character-encoded integers such as L'a'. const internal::VariadicDynCastAllOfMatcher< Stmt, IntegerLiteral> integerLiteral; +/// \brief Matches float literals of all sizes / encodings, e.g. +/// 1.0, 1.0f, 1.0L and 1e10. +/// +/// Does not match implicit conversions such as +/// \code +/// float a = 10; +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + FloatingLiteral> floatLiteral; + /// \brief Matches user defined literal operator call. /// /// Example match: "foo"_suffix @@ -1171,6 +1279,16 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CXXFunctionalCastExpr> functionalCastExpr; +/// \brief Matches functional cast expressions having N != 1 arguments +/// +/// Example: Matches Foo(bar, bar) +/// \code +/// Foo h = Foo(bar, bar); +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + CXXTemporaryObjectExpr> temporaryObjectExpr; + /// \brief Matches \c QualTypes in the clang AST. const internal::VariadicAllOfMatcher qualType; @@ -1199,93 +1317,23 @@ const internal::VariadicAllOfMatcher typeLoc; /// \c b. /// /// Usable as: Any Matcher -template -internal::PolymorphicMatcherWithParam2 -eachOf(const M1 &P1, const M2 &P2) { - return internal::PolymorphicMatcherWithParam2(P1, P2); -} - -/// \brief Various overloads for the anyOf matcher. -/// @{ +const internal::VariadicOperatorMatcherFunc eachOf = { + internal::EachOfVariadicOperator +}; /// \brief Matches if any of the given matchers matches. /// /// Usable as: Any Matcher -template -internal::PolymorphicMatcherWithParam2 -anyOf(const M1 &P1, const M2 &P2) { - return internal::PolymorphicMatcherWithParam2(P1, P2); -} -template -internal::PolymorphicMatcherWithParam2 > -anyOf(const M1 &P1, const M2 &P2, const M3 &P3) { - return anyOf(P1, anyOf(P2, P3)); -} -template -internal::PolymorphicMatcherWithParam2 > > -anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) { - return anyOf(P1, anyOf(P2, anyOf(P3, P4))); -} -template -internal::PolymorphicMatcherWithParam2 > > > -anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5) { - return anyOf(P1, anyOf(P2, anyOf(P3, anyOf(P4, P5)))); -} - -/// @} - -/// \brief Various overloads for the allOf matcher. -/// @{ +const internal::VariadicOperatorMatcherFunc anyOf = { + internal::AnyOfVariadicOperator +}; /// \brief Matches if all given matchers match. /// /// Usable as: Any Matcher -template -internal::PolymorphicMatcherWithParam2 -allOf(const M1 &P1, const M2 &P2) { - return internal::PolymorphicMatcherWithParam2( - P1, P2); -} -template -internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M1, - internal::PolymorphicMatcherWithParam2 > -allOf(const M1 &P1, const M2 &P2, const M3 &P3) { - return allOf(P1, allOf(P2, P3)); -} -template -internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M1, - internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M2, internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M3, M4> > > -allOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) { - return allOf(P1, allOf(P2, P3, P4)); -} -template -internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M1, - internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M2, - internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M3, - internal::PolymorphicMatcherWithParam2 > > > -allOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5) { - return allOf(P1, allOf(P2, P3, P4, P5)); -} - -/// @} +const internal::VariadicOperatorMatcherFunc allOf = { + internal::AllOfVariadicOperator +}; /// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL) /// @@ -1412,10 +1460,13 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) { /// /// Usable as: Matcher, Matcher inline internal::PolymorphicMatcherWithParam1< - internal::HasOverloadedOperatorNameMatcher, StringRef> + internal::HasOverloadedOperatorNameMatcher, StringRef, + AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, CXXMethodDecl)> hasOverloadedOperatorName(const StringRef Name) { return internal::PolymorphicMatcherWithParam1< - internal::HasOverloadedOperatorNameMatcher, StringRef>(Name); + internal::HasOverloadedOperatorNameMatcher, StringRef, + AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, CXXMethodDecl)>( + Name); } /// \brief Matches C++ classes that are directly or indirectly derived from @@ -1445,24 +1496,25 @@ AST_MATCHER_P(CXXRecordDecl, isDerivedFrom, } /// \brief Overloaded method as shortcut for \c isDerivedFrom(hasName(...)). -inline internal::Matcher isDerivedFrom(StringRef BaseName) { +AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isDerivedFrom, StringRef, BaseName, 1) { assert(!BaseName.empty()); - return isDerivedFrom(hasName(BaseName)); + return isDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder); } /// \brief Similar to \c isDerivedFrom(), but also matches classes that directly /// match \c Base. -inline internal::Matcher isSameOrDerivedFrom( - internal::Matcher Base) { - return anyOf(Base, isDerivedFrom(Base)); +AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, + internal::Matcher, Base, 0) { + return Matcher(anyOf(Base, isDerivedFrom(Base))) + .matches(Node, Finder, Builder); } /// \brief Overloaded method as shortcut for /// \c isSameOrDerivedFrom(hasName(...)). -inline internal::Matcher isSameOrDerivedFrom( - StringRef BaseName) { +AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, StringRef, BaseName, + 1) { assert(!BaseName.empty()); - return isSameOrDerivedFrom(hasName(BaseName)); + return isSameOrDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder); } /// \brief Matches the first method of a class or struct that satisfies \c @@ -1478,12 +1530,8 @@ inline internal::Matcher isSameOrDerivedFrom( /// but not \c B. AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher, InnerMatcher) { - for (CXXRecordDecl::method_iterator I = Node.method_begin(), - E = Node.method_end(); - I != E; ++I) - if (InnerMatcher.matches(**I, Finder, Builder)) - return true; - return false; + return matchesFirstInPointerRange(InnerMatcher, Node.method_begin(), + Node.method_end(), Finder, Builder); } /// \brief Matches AST nodes that have child AST nodes that match the @@ -1499,12 +1547,8 @@ AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher, /// ChildT must be an AST base type. /// /// Usable as: Any Matcher -template -internal::ArgumentAdaptingMatcher has( - const internal::Matcher &ChildMatcher) { - return internal::ArgumentAdaptingMatcher(ChildMatcher); -} +const internal::ArgumentAdaptingMatcherFunc +LLVM_ATTRIBUTE_UNUSED has = {}; /// \brief Matches AST nodes that have descendant AST nodes that match the /// provided matcher. @@ -1520,13 +1564,8 @@ internal::ArgumentAdaptingMatcher has( /// DescendantT must be an AST base type. /// /// Usable as: Any Matcher -template -internal::ArgumentAdaptingMatcher -hasDescendant(const internal::Matcher &DescendantMatcher) { - return internal::ArgumentAdaptingMatcher< - internal::HasDescendantMatcher, - DescendantT>(DescendantMatcher); -} +const internal::ArgumentAdaptingMatcherFunc +LLVM_ATTRIBUTE_UNUSED hasDescendant = {}; /// \brief Matches AST nodes that have child AST nodes that match the /// provided matcher. @@ -1544,13 +1583,8 @@ hasDescendant(const internal::Matcher &DescendantMatcher) { /// matches instead of only on the first one. /// /// Usable as: Any Matcher -template -internal::ArgumentAdaptingMatcher forEach( - const internal::Matcher &ChildMatcher) { - return internal::ArgumentAdaptingMatcher< - internal::ForEachMatcher, - ChildT>(ChildMatcher); -} +const internal::ArgumentAdaptingMatcherFunc +LLVM_ATTRIBUTE_UNUSED forEach = {}; /// \brief Matches AST nodes that have descendant AST nodes that match the /// provided matcher. @@ -1576,15 +1610,8 @@ internal::ArgumentAdaptingMatcher forEach( /// \endcode /// /// Usable as: Any Matcher -template -internal::ArgumentAdaptingMatcher -forEachDescendant( - const internal::Matcher &DescendantMatcher) { - return internal::ArgumentAdaptingMatcher< - internal::ForEachDescendantMatcher, - DescendantT>(DescendantMatcher); -} +const internal::ArgumentAdaptingMatcherFunc +LLVM_ATTRIBUTE_UNUSED forEachDescendant = {}; /// \brief Matches if the node or any descendant matches. /// @@ -1602,10 +1629,7 @@ forEachDescendant( /// /// Usable as: Any Matcher template -internal::PolymorphicMatcherWithParam2< - internal::EachOfMatcher, internal::Matcher, - internal::ArgumentAdaptingMatcher > -findAll(const internal::Matcher &Matcher) { +internal::Matcher findAll(const internal::Matcher &Matcher) { return eachOf(Matcher, forEachDescendant(Matcher)); } @@ -1619,13 +1643,9 @@ findAll(const internal::Matcher &Matcher) { /// \c compoundStmt(hasParent(ifStmt())) matches "{ int x = 43; }". /// /// Usable as: Any Matcher -template -internal::ArgumentAdaptingMatcher -hasParent(const internal::Matcher &ParentMatcher) { - return internal::ArgumentAdaptingMatcher< - internal::HasParentMatcher, - ParentT>(ParentMatcher); -} +const internal::ArgumentAdaptingMatcherFunc< + internal::HasParentMatcher, internal::TypeList, + internal::TypeList > LLVM_ATTRIBUTE_UNUSED hasParent = {}; /// \brief Matches AST nodes that have an ancestor that matches the provided /// matcher. @@ -1638,13 +1658,9 @@ hasParent(const internal::Matcher &ParentMatcher) { /// \c expr(integerLiteral(hasAncestor(ifStmt()))) matches \c 42, but not 43. /// /// Usable as: Any Matcher -template -internal::ArgumentAdaptingMatcher -hasAncestor(const internal::Matcher &AncestorMatcher) { - return internal::ArgumentAdaptingMatcher< - internal::HasAncestorMatcher, - AncestorT>(AncestorMatcher); -} +const internal::ArgumentAdaptingMatcherFunc< + internal::HasAncestorMatcher, internal::TypeList, + internal::TypeList > LLVM_ATTRIBUTE_UNUSED hasAncestor = {}; /// \brief Matches if the provided matcher does not match. /// @@ -1662,22 +1678,31 @@ unless(const M &InnerMatcher) { internal::NotMatcher, M>(InnerMatcher); } -/// \brief Matches a type if the declaration of the type matches the given -/// matcher. +/// \brief Matches a node if the declaration associated with that node +/// matches the given matcher. +/// +/// The associated declaration is: +/// - for type nodes, the declaration of the underlying type +/// - for CallExpr, the declaration of the callee +/// - for MemberExpr, the declaration of the referenced member +/// - for CXXConstructExpr, the declaration of the constructor /// -/// In addition to being usable as Matcher, also usable as -/// Matcher for any T supporting the getDecl() member function. e.g. various -/// subtypes of clang::Type. +/// Also usable as Matcher for any T supporting the getDecl() member +/// function. e.g. various subtypes of clang::Type and various expressions. /// -/// Usable as: Matcher, Matcher, Matcher, -/// Matcher, Matcher, -/// Matcher -inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher, - internal::Matcher > - hasDeclaration(const internal::Matcher &InnerMatcher) { +/// Usable as: Matcher, Matcher, +/// Matcher, Matcher, Matcher, +/// Matcher, Matcher, Matcher, +/// Matcher, Matcher, +/// Matcher, Matcher, +/// Matcher, Matcher +inline internal::PolymorphicMatcherWithParam1< + internal::HasDeclarationMatcher, internal::Matcher, + void(internal::HasDeclarationSupportedTypes)> +hasDeclaration(const internal::Matcher &InnerMatcher) { return internal::PolymorphicMatcherWithParam1< - internal::HasDeclarationMatcher, - internal::Matcher >(InnerMatcher); + internal::HasDeclarationMatcher, internal::Matcher, + void(internal::HasDeclarationSupportedTypes)>(InnerMatcher); } /// \brief Matches on the implicit object argument of a member call expression. @@ -1728,9 +1753,9 @@ AST_MATCHER_P(CallExpr, callee, internal::Matcher, /// class Y { public: void x(); }; /// void z() { Y y; y.x(); /// \endcode -inline internal::Matcher callee( - const internal::Matcher &InnerMatcher) { - return callExpr(hasDeclaration(InnerMatcher)); +AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher, InnerMatcher, + 1) { + return callExpr(hasDeclaration(InnerMatcher)).matches(Node, Finder, Builder); } /// \brief Matches if the expression's or declaration's type matches a type @@ -1742,11 +1767,9 @@ inline internal::Matcher callee( /// class X {}; /// void y(X &x) { x; X z; } /// \endcode -AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher, - InnerMatcher) { - TOOLING_COMPILE_ASSERT((llvm::is_base_of::value || - llvm::is_base_of::value), - instantiated_with_wrong_types); +AST_POLYMORPHIC_MATCHER_P_OVERLOAD( + hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl), + internal::Matcher, InnerMatcher, 0) { return InnerMatcher.matches(Node.getType(), Finder, Builder); } @@ -1767,11 +1790,27 @@ AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher, /// \endcode /// /// Usable as: Matcher, Matcher -inline internal::PolymorphicMatcherWithParam1< - internal::matcher_hasType0Matcher, - internal::Matcher > -hasType(const internal::Matcher &InnerMatcher) { - return hasType(qualType(hasDeclaration(InnerMatcher))); +AST_POLYMORPHIC_MATCHER_P_OVERLOAD( + hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl), + internal::Matcher, InnerMatcher, 1) { + return qualType(hasDeclaration(InnerMatcher)) + .matches(Node.getType(), Finder, Builder); +} + +/// \brief Matches if the type location of the declarator decl's type matches +/// the inner matcher. +/// +/// Given +/// \code +/// int x; +/// \endcode +/// declaratorDecl(hasTypeLoc(loc(asString("int")))) +/// matches int x +AST_MATCHER_P(DeclaratorDecl, hasTypeLoc, internal::Matcher, Inner) { + if (!Node.getTypeSourceInfo()) + // This happens for example for implicit destructors. + return false; + return Inner.matches(Node.getTypeSourceInfo()->getTypeLoc(), Finder, Builder); } /// \brief Matches if the matched type is represented by the given string. @@ -1804,9 +1843,10 @@ AST_MATCHER_P( } /// \brief Overloaded to match the pointee type's declaration. -inline internal::Matcher pointsTo( - const internal::Matcher &InnerMatcher) { - return pointsTo(qualType(hasDeclaration(InnerMatcher))); +AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher, + InnerMatcher, 1) { + return pointsTo(qualType(hasDeclaration(InnerMatcher))) + .matches(Node, Finder, Builder); } /// \brief Matches if the matched type is a reference type and the referenced @@ -1841,13 +1881,16 @@ AST_MATCHER_P(QualType, references, internal::Matcher, /// varDecl(hasType(qualType(hasCanonicalType(referenceType())))))) does. AST_MATCHER_P(QualType, hasCanonicalType, internal::Matcher, InnerMatcher) { + if (Node.isNull()) + return false; return InnerMatcher.matches(Node.getCanonicalType(), Finder, Builder); } /// \brief Overloaded to match the referenced type's declaration. -inline internal::Matcher references( - const internal::Matcher &InnerMatcher) { - return references(qualType(hasDeclaration(InnerMatcher))); +AST_MATCHER_P_OVERLOAD(QualType, references, internal::Matcher, + InnerMatcher, 1) { + return references(qualType(hasDeclaration(InnerMatcher))) + .matches(Node, Finder, Builder); } AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument, @@ -1859,17 +1902,19 @@ AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument, /// \brief Matches if the expression's type either matches the specified /// matcher, or is a pointer to a type that matches the InnerMatcher. -inline internal::Matcher thisPointerType( - const internal::Matcher &InnerMatcher) { +AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, + internal::Matcher, InnerMatcher, 0) { return onImplicitObjectArgument( - anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))); + anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))) + .matches(Node, Finder, Builder); } /// \brief Overloaded to match the type's declaration. -inline internal::Matcher thisPointerType( - const internal::Matcher &InnerMatcher) { +AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, + internal::Matcher, InnerMatcher, 1) { return onImplicitObjectArgument( - anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))); + anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))) + .matches(Node, Finder, Builder); } /// \brief Matches a DeclRefExpr that refers to a declaration that matches the @@ -1953,11 +1998,9 @@ AST_MATCHER_P( /// void f(int x, int y); /// f(0, 0); /// \endcode -AST_POLYMORPHIC_MATCHER_P(argumentCountIs, unsigned, N) { - TOOLING_COMPILE_ASSERT((llvm::is_base_of::value || - llvm::is_base_of::value), - instantiated_with_wrong_types); +AST_POLYMORPHIC_MATCHER_P(argumentCountIs, AST_POLYMORPHIC_SUPPORTED_TYPES_2( + CallExpr, CXXConstructExpr), + unsigned, N) { return Node.getNumArgs() == N; } @@ -1970,11 +2013,9 @@ AST_POLYMORPHIC_MATCHER_P(argumentCountIs, unsigned, N) { /// void x(int) { int y; x(y); } /// \endcode AST_POLYMORPHIC_MATCHER_P2( - hasArgument, unsigned, N, internal::Matcher, InnerMatcher) { - TOOLING_COMPILE_ASSERT((llvm::is_base_of::value || - llvm::is_base_of::value), - instantiated_with_wrong_types); + hasArgument, + AST_POLYMORPHIC_SUPPORTED_TYPES_2(CallExpr, CXXConstructExpr), + unsigned, N, internal::Matcher, InnerMatcher) { return (N < Node.getNumArgs() && InnerMatcher.matches( *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder)); @@ -2037,13 +2078,8 @@ AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N, /// record matches Foo, hasAnyConstructorInitializer matches foo_(1) AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer, internal::Matcher, InnerMatcher) { - for (CXXConstructorDecl::init_const_iterator I = Node.init_begin(); - I != Node.init_end(); ++I) { - if (InnerMatcher.matches(**I, Finder, Builder)) { - return true; - } - } - return false; + return matchesFirstInPointerRange(InnerMatcher, Node.init_begin(), + Node.init_end(), Finder, Builder); } /// \brief Matches the field declaration of a constructor initializer. @@ -2086,7 +2122,7 @@ AST_MATCHER_P(CXXCtorInitializer, withInitializer, InnerMatcher.matches(*NodeAsExpr, Finder, Builder)); } -/// \brief Matches a contructor initializer if it is explicitly written in +/// \brief Matches a constructor initializer if it is explicitly written in /// code (as opposed to implicitly added by the compiler). /// /// Given @@ -2120,15 +2156,19 @@ AST_MATCHER(CXXConstructorDecl, isImplicit) { /// matches x(1, y, 42) /// with hasAnyArgument(...) /// matching y -AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, internal::Matcher, - InnerMatcher) { - TOOLING_COMPILE_ASSERT((llvm::is_base_of::value || - llvm::is_base_of::value), - instantiated_with_wrong_types); +/// +/// FIXME: Currently this will ignore parentheses and implicit casts on +/// the argument before applying the inner matcher. We'll want to remove +/// this to allow for greater control by the user once \c ignoreImplicit() +/// has been implemented. +AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, AST_POLYMORPHIC_SUPPORTED_TYPES_2( + CallExpr, CXXConstructExpr), + internal::Matcher, InnerMatcher) { for (unsigned I = 0; I < Node.getNumArgs(); ++I) { - if (InnerMatcher.matches(*Node.getArg(I)->IgnoreParenImpCasts(), - Finder, Builder)) { + BoundNodesTreeBuilder Result(*Builder); + if (InnerMatcher.matches(*Node.getArg(I)->IgnoreParenImpCasts(), Finder, + &Result)) { + *Builder = Result; return true; } } @@ -2167,12 +2207,8 @@ AST_MATCHER_P2(FunctionDecl, hasParameter, /// matching int y AST_MATCHER_P(FunctionDecl, hasAnyParameter, internal::Matcher, InnerMatcher) { - for (unsigned I = 0; I < Node.getNumParams(); ++I) { - if (InnerMatcher.matches(*Node.getParamDecl(I), Finder, Builder)) { - return true; - } - } - return false; + return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(), + Node.param_end(), Finder, Builder); } /// \brief Matches \c FunctionDecls that have a specific parameter count. @@ -2222,27 +2258,68 @@ AST_MATCHER(FunctionDecl, isExternC) { /// \code /// if (true) {} /// \endcode -AST_POLYMORPHIC_MATCHER_P(hasCondition, internal::Matcher, - InnerMatcher) { - TOOLING_COMPILE_ASSERT( - (llvm::is_base_of::value) || - (llvm::is_base_of::value) || - (llvm::is_base_of::value) || - (llvm::is_base_of::value) || - (llvm::is_base_of::value), - has_condition_requires_if_statement_conditional_operator_or_loop); +AST_POLYMORPHIC_MATCHER_P( + hasCondition, AST_POLYMORPHIC_SUPPORTED_TYPES_5( + IfStmt, ForStmt, WhileStmt, DoStmt, ConditionalOperator), + internal::Matcher, InnerMatcher) { const Expr *const Condition = Node.getCond(); return (Condition != NULL && InnerMatcher.matches(*Condition, Finder, Builder)); } +namespace internal { +struct NotEqualsBoundNodePredicate { + bool operator()(const internal::BoundNodesMap &Nodes) const { + return Nodes.getNode(ID) != Node; + } + std::string ID; + ast_type_traits::DynTypedNode Node; +}; +} // namespace internal + +/// \brief Matches if a node equals a previously bound node. +/// +/// Matches a node if it equals the node previously bound to \p ID. +/// +/// Given +/// \code +/// class X { int a; int b; }; +/// \endcode +/// recordDecl( +/// has(fieldDecl(hasName("a"), hasType(type().bind("t")))), +/// has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t")))))) +/// matches the class \c X, as \c a and \c b have the same type. +/// +/// Note that when multiple matches are involved via \c forEach* matchers, +/// \c equalsBoundNodes acts as a filter. +/// For example: +/// compoundStmt( +/// forEachDescendant(varDecl().bind("d")), +/// forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))) +/// will trigger a match for each combination of variable declaration +/// and reference to that variable declaration within a compound statement. +AST_POLYMORPHIC_MATCHER_P(equalsBoundNode, AST_POLYMORPHIC_SUPPORTED_TYPES_4( + Stmt, Decl, Type, QualType), + std::string, ID) { + // FIXME: Figure out whether it makes sense to allow this + // on any other node types. + // For *Loc it probably does not make sense, as those seem + // unique. For NestedNameSepcifier it might make sense, as + // those also have pointer identity, but I'm not sure whether + // they're ever reused. + internal::NotEqualsBoundNodePredicate Predicate; + Predicate.ID = ID; + Predicate.Node = ast_type_traits::DynTypedNode::create(Node); + return Builder->removeBindings(Predicate); +} + /// \brief Matches the condition variable statement in an if statement. /// /// Given /// \code /// if (A* a = GetAPointer()) {} /// \endcode -/// hasConditionVariableStatment(...) +/// hasConditionVariableStatement(...) /// matches 'A* a = GetAPointer()'. AST_MATCHER_P(IfStmt, hasConditionVariableStatement, internal::Matcher, InnerMatcher) { @@ -2296,13 +2373,9 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, /// matches 'for (;;) {}' /// with compoundStmt() /// matching '{}' -AST_POLYMORPHIC_MATCHER_P(hasBody, internal::Matcher, - InnerMatcher) { - TOOLING_COMPILE_ASSERT( - (llvm::is_base_of::value) || - (llvm::is_base_of::value) || - (llvm::is_base_of::value), - has_body_requires_for_while_or_do_statement); +AST_POLYMORPHIC_MATCHER_P( + hasBody, AST_POLYMORPHIC_SUPPORTED_TYPES_3(DoStmt, ForStmt, WhileStmt), + internal::Matcher, InnerMatcher) { const Stmt *const Statement = Node.getBody(); return (Statement != NULL && InnerMatcher.matches(*Statement, Finder, Builder)); @@ -2321,12 +2394,8 @@ AST_POLYMORPHIC_MATCHER_P(hasBody, internal::Matcher, /// matching '{}' AST_MATCHER_P(CompoundStmt, hasAnySubstatement, internal::Matcher, InnerMatcher) { - for (CompoundStmt::const_body_iterator It = Node.body_begin(); - It != Node.body_end(); - ++It) { - if (InnerMatcher.matches(**It, Finder, Builder)) return true; - } - return false; + return matchesFirstInPointerRange(InnerMatcher, Node.body_begin(), + Node.body_end(), Finder, Builder); } /// \brief Checks that a compound statement contains a specific number of @@ -2367,11 +2436,9 @@ equals(const ValueT &Value) { /// \code /// !(a || b) /// \endcode -AST_POLYMORPHIC_MATCHER_P(hasOperatorName, std::string, Name) { - TOOLING_COMPILE_ASSERT( - (llvm::is_base_of::value) || - (llvm::is_base_of::value), - has_condition_requires_if_statement_or_conditional_operator); +AST_POLYMORPHIC_MATCHER_P(hasOperatorName, AST_POLYMORPHIC_SUPPORTED_TYPES_2( + BinaryOperator, UnaryOperator), + std::string, Name) { return Name == Node.getOpcodeStr(Node.getOpcode()); } @@ -2493,12 +2560,8 @@ AST_MATCHER_P(ConditionalOperator, hasFalseExpression, /// \endcode /// /// Usable as: Matcher, Matcher, Matcher -AST_POLYMORPHIC_MATCHER(isDefinition) { - TOOLING_COMPILE_ASSERT( - (llvm::is_base_of::value) || - (llvm::is_base_of::value) || - (llvm::is_base_of::value), - is_definition_requires_isThisDeclarationADefinition_method); +AST_POLYMORPHIC_MATCHER(isDefinition, AST_POLYMORPHIC_SUPPORTED_TYPES_3( + TagDecl, VarDecl, FunctionDecl)) { return Node.isThisDeclarationADefinition(); } @@ -2540,6 +2603,21 @@ AST_MATCHER(CXXMethodDecl, isVirtual) { return Node.isVirtual(); } +/// \brief Matches if the given method declaration is const. +/// +/// Given +/// \code +/// struct A { +/// void foo() const; +/// void bar(); +/// }; +/// \endcode +/// +/// methodDecl(isConst()) matches A::foo() but not A::bar() +AST_MATCHER(CXXMethodDecl, isConst) { + return Node.isConst(); +} + /// \brief Matches if the given method declaration overrides another method. /// /// Given @@ -2672,12 +2750,8 @@ AST_MATCHER_P(MemberExpr, hasObjectExpression, /// matches \code using X::b \endcode AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl, internal::Matcher, InnerMatcher) { - for (UsingDecl::shadow_iterator II = Node.shadow_begin(); - II != Node.shadow_end(); ++II) { - if (InnerMatcher.matches(**II, Finder, Builder)) - return true; - } - return false; + return matchesFirstInPointerRange(InnerMatcher, Node.shadow_begin(), + Node.shadow_end(), Finder, Builder); } /// \brief Matches a using shadow declaration where the target declaration is @@ -2720,11 +2794,9 @@ AST_MATCHER_P(UsingShadowDecl, hasTargetDecl, /// does not match, as X is an explicit template specialization. /// /// Usable as: Matcher, Matcher, Matcher -AST_POLYMORPHIC_MATCHER(isTemplateInstantiation) { - TOOLING_COMPILE_ASSERT((llvm::is_base_of::value) || - (llvm::is_base_of::value) || - (llvm::is_base_of::value), - requires_getTemplateSpecializationKind_method); +AST_POLYMORPHIC_MATCHER( + isTemplateInstantiation, + AST_POLYMORPHIC_SUPPORTED_TYPES_3(FunctionDecl, VarDecl, CXXRecordDecl)) { return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation || Node.getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition); @@ -2742,11 +2814,9 @@ AST_POLYMORPHIC_MATCHER(isTemplateInstantiation) { /// matches the specialization A(). /// /// Usable as: Matcher, Matcher, Matcher -AST_POLYMORPHIC_MATCHER(isExplicitTemplateSpecialization) { - TOOLING_COMPILE_ASSERT((llvm::is_base_of::value) || - (llvm::is_base_of::value) || - (llvm::is_base_of::value), - requires_getTemplateSpecializationKind_method); +AST_POLYMORPHIC_MATCHER( + isExplicitTemplateSpecialization, + AST_POLYMORPHIC_SUPPORTED_TYPES_3(FunctionDecl, VarDecl, CXXRecordDecl)) { return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization); } @@ -2807,7 +2877,9 @@ AST_TYPE_MATCHER(ComplexType, complexType); /// matches "int b[7]" /// /// Usable as: Matcher, Matcher -AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement); +AST_TYPELOC_TRAVERSE_MATCHER( + hasElementType, getElement, + AST_POLYMORPHIC_SUPPORTED_TYPES_2(ArrayType, ComplexType)); /// \brief Matches C arrays with a specified constant size. /// @@ -2914,7 +2986,8 @@ AST_TYPE_MATCHER(AtomicType, atomicType); /// matches "_Atomic(int) i" /// /// Usable as: Matcher -AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue); +AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue, + AST_POLYMORPHIC_SUPPORTED_TYPES_1(AtomicType)); /// \brief Matches types nodes representing C++11 auto types. /// @@ -2942,7 +3015,8 @@ AST_TYPE_MATCHER(AutoType, autoType); /// matches "auto a" /// /// Usable as: Matcher -AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType); +AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType, + AST_POLYMORPHIC_SUPPORTED_TYPES_1(AutoType)); /// \brief Matches \c FunctionType nodes. /// @@ -2979,7 +3053,8 @@ AST_TYPE_MATCHER(ParenType, parenType); /// \c ptr_to_func but not \c ptr_to_array. /// /// Usable as: Matcher -AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType); +AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType, + AST_POLYMORPHIC_SUPPORTED_TYPES_1(ParenType)); /// \brief Matches block pointer types, i.e. types syntactically represented as /// "void (^)(int)". @@ -3073,7 +3148,10 @@ AST_TYPE_MATCHER(RValueReferenceType, rValueReferenceType); /// /// Usable as: Matcher, Matcher, /// Matcher, Matcher -AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee); +AST_TYPELOC_TRAVERSE_MATCHER( + pointee, getPointee, + AST_POLYMORPHIC_SUPPORTED_TYPES_4(BlockPointerType, MemberPointerType, + PointerType, ReferenceType)); /// \brief Matches typedef types. /// @@ -3100,6 +3178,16 @@ AST_TYPE_MATCHER(TypedefType, typedefType); /// instantiation in \c A and the type of the variable declaration in \c B. AST_TYPE_MATCHER(TemplateSpecializationType, templateSpecializationType); +/// \brief Matches types nodes representing unary type transformations. +/// +/// Given: +/// \code +/// typedef __underlying_type(T) type; +/// \endcode +/// unaryTransformType() +/// matches "__underlying_type(T)" +AST_TYPE_MATCHER(UnaryTransformType, unaryTransformType); + /// \brief Matches record types (e.g. structs, classes). /// /// Given @@ -3331,6 +3419,80 @@ AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, Stmt*, Other, 1) { /// @} +/// \brief Matches each case or default statement belonging to the given switch +/// statement. This matcher may produce multiple matches. +/// +/// Given +/// \code +/// switch (1) { case 1: case 2: default: switch (2) { case 3: case 4: ; } } +/// \endcode +/// switchStmt(forEachSwitchCase(caseStmt().bind("c"))).bind("s") +/// matches four times, with "c" binding each of "case 1:", "case 2:", +/// "case 3:" and "case 4:", and "s" respectively binding "switch (1)", +/// "switch (1)", "switch (2)" and "switch (2)". +AST_MATCHER_P(SwitchStmt, forEachSwitchCase, internal::Matcher, + InnerMatcher) { + BoundNodesTreeBuilder Result; + // FIXME: getSwitchCaseList() does not necessarily guarantee a stable + // iteration order. We should use the more general iterating matchers once + // they are capable of expressing this matcher (for example, it should ignore + // case statements belonging to nested switch statements). + bool Matched = false; + for (const SwitchCase *SC = Node.getSwitchCaseList(); SC; + SC = SC->getNextSwitchCase()) { + BoundNodesTreeBuilder CaseBuilder(*Builder); + bool CaseMatched = InnerMatcher.matches(*SC, Finder, &CaseBuilder); + if (CaseMatched) { + Matched = true; + Result.addMatch(CaseBuilder); + } + } + *Builder = Result; + return Matched; +} + +/// \brief Matches each constructor initializer in a constructor definition. +/// +/// Given +/// \code +/// class A { A() : i(42), j(42) {} int i; int j; }; +/// \endcode +/// constructorDecl(forEachConstructorInitializer(forField(decl().bind("x")))) +/// will trigger two matches, binding for 'i' and 'j' respectively. +AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer, + internal::Matcher, InnerMatcher) { + BoundNodesTreeBuilder Result; + bool Matched = false; + for (CXXConstructorDecl::init_const_iterator I = Node.init_begin(), + E = Node.init_end(); + I != E; ++I) { + BoundNodesTreeBuilder InitBuilder(*Builder); + if (InnerMatcher.matches(**I, Finder, &InitBuilder)) { + Matched = true; + Result.addMatch(InitBuilder); + } + } + *Builder = Result; + return Matched; +} + +/// \brief If the given case statement does not use the GNU case range +/// extension, matches the constant given in the statement. +/// +/// Given +/// \code +/// switch (1) { case 1: case 1+1: case 3 ... 4: ; } +/// \endcode +/// caseStmt(hasCaseConstant(integerLiteral())) +/// matches "case 1:" +AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher, + InnerMatcher) { + if (Node.getRHS()) + return false; + + return InnerMatcher.matches(*Node.getLHS(), Finder, Builder); +} + } // end namespace ast_matchers } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index 30691ad..69cee2e 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -36,12 +36,13 @@ #define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H #include "clang/AST/ASTTypeTraits.h" -#include "clang/AST/DeclCXX.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/ExprCXX.h" -#include "clang/AST/StmtCXX.h" #include "clang/AST/Stmt.h" +#include "clang/AST/StmtCXX.h" #include "clang/AST/Type.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/VariadicFunction.h" #include "llvm/Support/type_traits.h" #include @@ -60,7 +61,6 @@ class BoundNodes; namespace internal { -class BoundNodesTreeBuilder; /// \brief Internal version of BoundNodes. Holds all the bound nodes. class BoundNodesMap { public: @@ -71,9 +71,6 @@ public: void addNode(StringRef ID, const T* Node) { NodeMap[ID] = ast_type_traits::DynTypedNode::create(*Node); } - void addNode(StringRef ID, ast_type_traits::DynTypedNode Node) { - NodeMap[ID] = Node; - } /// \brief Returns the AST node bound to \c ID. /// @@ -88,29 +85,39 @@ public: return It->second.get(); } - /// \brief Copies all ID/Node pairs to BoundNodesTreeBuilder \c Builder. - void copyTo(BoundNodesTreeBuilder *Builder) const; + ast_type_traits::DynTypedNode getNode(StringRef ID) const { + IDToNodeMap::const_iterator It = NodeMap.find(ID); + if (It == NodeMap.end()) { + return ast_type_traits::DynTypedNode(); + } + return It->second; + } - /// \brief Copies all ID/Node pairs to BoundNodesMap \c Other. - void copyTo(BoundNodesMap *Other) const; + /// \brief Imposes an order on BoundNodesMaps. + bool operator<(const BoundNodesMap &Other) const { + return NodeMap < Other.NodeMap; + } -private: /// \brief A map from IDs to the bound nodes. + /// + /// Note that we're using std::map here, as for memoization: + /// - we need a comparison operator + /// - we need an assignment operator typedef std::map IDToNodeMap; + const IDToNodeMap &getMap() const { + return NodeMap; + } + +private: IDToNodeMap NodeMap; }; -/// \brief A tree of bound nodes in match results. -/// -/// If a match can contain multiple matches on the same node with different -/// matching subexpressions, BoundNodesTree contains a branch for each of -/// those matching subexpressions. +/// \brief Creates BoundNodesTree objects. /// -/// BoundNodesTree's are created during the matching process; when a match -/// is found, we iterate over the tree and create a BoundNodes object containing -/// the union of all bound nodes on the path from the root to a each leaf. -class BoundNodesTree { +/// The tree builder is used during the matching process to insert the bound +/// nodes from the Id matcher. +class BoundNodesTreeBuilder { public: /// \brief A visitor interface to visit all BoundNodes results for a /// BoundNodesTree. @@ -124,63 +131,36 @@ public: virtual void visitMatch(const BoundNodes& BoundNodesView) = 0; }; - BoundNodesTree(); - - /// \brief Create a BoundNodesTree from pre-filled maps of bindings. - BoundNodesTree(const BoundNodesMap& Bindings, - const std::vector RecursiveBindings); + /// \brief Add a binding from an id to a node. + template void setBinding(const std::string &Id, const T *Node) { + if (Bindings.empty()) + Bindings.push_back(BoundNodesMap()); + for (unsigned i = 0, e = Bindings.size(); i != e; ++i) + Bindings[i].addNode(Id, Node); + } - /// \brief Adds all bound nodes to \c Builder. - void copyTo(BoundNodesTreeBuilder* Builder) const; + /// \brief Adds a branch in the tree. + void addMatch(const BoundNodesTreeBuilder &Bindings); /// \brief Visits all matches that this BoundNodesTree represents. /// /// The ownership of 'ResultVisitor' remains at the caller. void visitMatches(Visitor* ResultVisitor); -private: - void visitMatchesRecursively( - Visitor* ResultVistior, - const BoundNodesMap& AggregatedBindings); - - // FIXME: Find out whether we want to use different data structures here - - // first benchmarks indicate that it doesn't matter though. - - BoundNodesMap Bindings; - - std::vector RecursiveBindings; -}; - -/// \brief Creates BoundNodesTree objects. -/// -/// The tree builder is used during the matching process to insert the bound -/// nodes from the Id matcher. -class BoundNodesTreeBuilder { -public: - BoundNodesTreeBuilder(); - - /// \brief Add a binding from an id to a node. - template - void setBinding(const std::string &Id, const T *Node) { - Bindings.addNode(Id, Node); - } - void setBinding(const std::string &Id, ast_type_traits::DynTypedNode Node) { - Bindings.addNode(Id, Node); + template + bool removeBindings(const ExcludePredicate &Predicate) { + Bindings.erase(std::remove_if(Bindings.begin(), Bindings.end(), Predicate), + Bindings.end()); + return !Bindings.empty(); } - /// \brief Adds a branch in the tree. - void addMatch(const BoundNodesTree& Bindings); - - /// \brief Returns a BoundNodes object containing all current bindings. - BoundNodesTree build() const; + /// \brief Imposes an order on BoundNodesTreeBuilders. + bool operator<(const BoundNodesTreeBuilder &Other) const { + return Bindings < Other.Bindings; + } private: - BoundNodesTreeBuilder(const BoundNodesTreeBuilder &) LLVM_DELETED_FUNCTION; - void operator=(const BoundNodesTreeBuilder &) LLVM_DELETED_FUNCTION; - - BoundNodesMap Bindings; - - std::vector RecursiveBindings; + SmallVector Bindings; }; class ASTMatchFinder; @@ -225,24 +205,6 @@ private: } }; -/// \brief Base class for all matchers that works on a \c DynTypedNode. -/// -/// Matcher implementations will check whether the \c DynTypedNode is -/// convertible into the respecitve types and then do the actual match -/// on the actual node, or return false if it is not convertible. -class DynTypedMatcher { -public: - virtual ~DynTypedMatcher() {} - - /// \brief Returns true if the matcher matches the given \c DynNode. - virtual bool matches(const ast_type_traits::DynTypedNode DynNode, - ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder) const = 0; - - /// \brief Returns a unique ID for the matcher. - virtual uint64_t getID() const = 0; -}; - /// \brief Wrapper of a MatcherInterface *that allows copying. /// /// A Matcher can be used anywhere a Matcher is @@ -252,7 +214,7 @@ public: /// operator rather than a type hierarchy to be able to templatize the /// type hierarchy instead of spelling it out. template -class Matcher : public DynTypedMatcher { +class Matcher { public: /// \brief Takes ownership of the provided implementation pointer. explicit Matcher(MatcherInterface *Implementation) @@ -282,7 +244,13 @@ public: bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { - return Implementation->matches(Node, Finder, Builder); + if (Implementation->matches(Node, Finder, Builder)) + return true; + // Delete all bindings when a matcher does not match. + // This prevents unexpected exposure of bound nodes in unmatches + // branches of the match tree. + *Builder = BoundNodesTreeBuilder(); + return false; } /// \brief Returns an ID that uniquely identifies the matcher. @@ -292,15 +260,6 @@ public: return reinterpret_cast(Implementation.getPtr()); } - /// \brief Returns whether the matcher matches on the given \c DynNode. - virtual bool matches(const ast_type_traits::DynTypedNode DynNode, - ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder) const { - const T *Node = DynNode.get(); - if (!Node) return false; - return matches(*Node, Finder, Builder); - } - /// \brief Allows the conversion of a \c Matcher to a \c /// Matcher. /// @@ -353,6 +312,217 @@ inline Matcher makeMatcher(MatcherInterface *Implementation) { return Matcher(Implementation); } +template class BindableMatcher; + +/// \brief Matcher that works on a \c DynTypedNode. +/// +/// It is constructed from a \c Matcher object and redirects most calls to +/// underlying matcher. +/// It checks whether the \c DynTypedNode is convertible into the type of the +/// underlying matcher and then do the actual match on the actual node, or +/// return false if it is not convertible. +class DynTypedMatcher { +public: + /// \brief Construct from a \c Matcher. Copies the matcher. + template inline DynTypedMatcher(const Matcher &M); + + /// \brief Construct from a bindable \c Matcher. Copies the matcher. + /// + /// This version enables \c tryBind() on the \c DynTypedMatcher. + template inline DynTypedMatcher(const BindableMatcher &M); + + /// \brief Returns true if the matcher matches the given \c DynNode. + bool matches(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { + return Storage->matches(DynNode, Finder, Builder); + } + + /// \brief Bind the specified \p ID to the matcher. + /// \return A new matcher with the \p ID bound to it if this matcher supports + /// binding. Otherwise, returns an empty \c Optional<>. + llvm::Optional tryBind(StringRef ID) const { + return Storage->tryBind(ID); + } + + /// \brief Returns a unique \p ID for the matcher. + uint64_t getID() const { return Storage->getID(); } + + /// \brief Returns the type this matcher works on. + /// + /// \c matches() will always return false unless the node passed is of this + /// or a derived type. + ast_type_traits::ASTNodeKind getSupportedKind() const { + return Storage->getSupportedKind(); + } + + /// \brief Returns \c true if the passed \c DynTypedMatcher can be converted + /// to a \c Matcher. + /// + /// This method verifies that the underlying matcher in \c Other can process + /// nodes of types T. + template bool canConvertTo() const { + return getSupportedKind().isBaseOf( + ast_type_traits::ASTNodeKind::getFromNodeKind()); + } + + /// \brief Construct a \c Matcher interface around the dynamic matcher. + /// + /// This method asserts that \c canConvertTo() is \c true. Callers + /// should call \c canConvertTo() first to make sure that \c this is + /// compatible with T. + template Matcher convertTo() const { + assert(canConvertTo()); + return unconditionalConvertTo(); + } + + /// \brief Same as \c convertTo(), but does not check that the underlying + /// matcher can handle a value of T. + /// + /// If it is not compatible, then this matcher will never match anything. + template Matcher unconditionalConvertTo() const { + return Matcher(new WrappedMatcher(*this)); + } + +private: + class MatcherStorage : public RefCountedBaseVPTR { + public: + MatcherStorage(ast_type_traits::ASTNodeKind SupportedKind, uint64_t ID) + : SupportedKind(SupportedKind), ID(ID) {} + virtual ~MatcherStorage(); + + virtual bool matches(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const = 0; + + virtual llvm::Optional tryBind(StringRef ID) const = 0; + + ast_type_traits::ASTNodeKind getSupportedKind() const { + return SupportedKind; + } + + uint64_t getID() const { return ID; } + + private: + const ast_type_traits::ASTNodeKind SupportedKind; + const uint64_t ID; + }; + + /// \brief Typed implementation of \c MatcherStorage. + template class TypedMatcherStorage; + + /// \brief Simple MatcherInterface wrapper around a DynTypedMatcher. + template class WrappedMatcher; + + IntrusiveRefCntPtr Storage; +}; + +template +class DynTypedMatcher::TypedMatcherStorage : public MatcherStorage { +public: + TypedMatcherStorage(const Matcher &Other, bool AllowBind) + : MatcherStorage(ast_type_traits::ASTNodeKind::getFromNodeKind(), + Other.getID()), + InnerMatcher(Other), AllowBind(AllowBind) {} + + bool matches(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const + LLVM_OVERRIDE { + if (const T *Node = DynNode.get()) { + return InnerMatcher.matches(*Node, Finder, Builder); + } + return false; + } + + llvm::Optional tryBind(StringRef ID) const LLVM_OVERRIDE { + if (!AllowBind) + return llvm::Optional(); + return DynTypedMatcher(BindableMatcher(InnerMatcher).bind(ID)); + } + +private: + const Matcher InnerMatcher; + const bool AllowBind; +}; + +template +inline DynTypedMatcher::DynTypedMatcher(const Matcher &M) + : Storage(new TypedMatcherStorage(M, false)) {} + +template +inline DynTypedMatcher::DynTypedMatcher(const BindableMatcher &M) + : Storage(new TypedMatcherStorage(M, true)) {} + +template +class DynTypedMatcher::WrappedMatcher : public MatcherInterface { +public: + explicit WrappedMatcher(const DynTypedMatcher &Matcher) : Inner(Matcher) {} + virtual ~WrappedMatcher() {} + + bool matches(const T &Node, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + return Inner.matches(ast_type_traits::DynTypedNode::create(Node), Finder, + Builder); + } + +private: + const DynTypedMatcher Inner; +}; + +/// \brief Specialization of the conversion functions for QualType. +/// +/// These specializations provide the Matcher->Matcher +/// conversion that the static API does. +template <> inline bool DynTypedMatcher::canConvertTo() const { + const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind(); + return SourceKind.isSame( + ast_type_traits::ASTNodeKind::getFromNodeKind()) || + SourceKind.isSame( + ast_type_traits::ASTNodeKind::getFromNodeKind()); +} + +template <> +inline Matcher DynTypedMatcher::convertTo() const { + assert(canConvertTo()); + const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind(); + if (SourceKind.isSame( + ast_type_traits::ASTNodeKind::getFromNodeKind())) { + // We support implicit conversion from Matcher to Matcher + return unconditionalConvertTo(); + } + return unconditionalConvertTo(); +} + +/// \brief Finds the first node in a range that matches the given matcher. +template +bool matchesFirstInRange(const MatcherT &Matcher, IteratorT Start, + IteratorT End, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) { + for (IteratorT I = Start; I != End; ++I) { + BoundNodesTreeBuilder Result(*Builder); + if (Matcher.matches(*I, Finder, &Result)) { + *Builder = Result; + return true; + } + } + return false; +} + +/// \brief Finds the first node in a pointer range that matches the given +/// matcher. +template +bool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start, + IteratorT End, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) { + for (IteratorT I = Start; I != End; ++I) { + BoundNodesTreeBuilder Result(*Builder); + if (Matcher.matches(**I, Finder, &Result)) { + *Builder = Result; + return true; + } + } + return false; +} + /// \brief Metafunction to determine if type T has a member called getDecl. template struct has_getDecl { struct Default { int getDecl; }; @@ -632,6 +802,94 @@ protected: AncestorMatchMode MatchMode) = 0; }; +/// \brief A type-list implementation. +/// +/// A list is declared as a tree of type list nodes, where the leafs are the +/// types. +/// However, it is used as a "linked list" of types, by using the ::head and +/// ::tail typedefs. +/// Each node supports up to 4 children (instead of just 2) to reduce the +/// nesting required by large lists. +template +struct TypeList { + /// \brief Implementation detail. Combined with the specializations below, + /// this typedef allows for flattening of nested structures. + typedef TypeList self; + + /// \brief The first type on the list. + typedef T1 head; + + /// \brief A sub list with the tail. ie everything but the head. + /// + /// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the + /// end of the list. + typedef typename TypeList::self tail; +}; + +/// \brief Template specialization to allow nested lists. +/// +/// First element is a typelist. Pop its first element. +template +struct TypeList, T2, T3, + T4> : public TypeList::self, + typename TypeList::self> {}; + +/// \brief Template specialization to allow nested lists. +/// +/// First element is an empty typelist. Skip it. +template +struct TypeList, T2, T3, T4> : public TypeList { +}; + +/// \brief The empty type list. +typedef TypeList<> EmptyTypeList; + +/// \brief Helper meta-function to determine if some type \c T is present or +/// a parent type in the list. +template +struct TypeListContainsSuperOf { + static const bool value = + llvm::is_base_of::value || + TypeListContainsSuperOf::value; +}; +template +struct TypeListContainsSuperOf { + static const bool value = false; +}; + +/// \brief A "type list" that contains all types. +/// +/// Useful for matchers like \c anything and \c unless. +typedef TypeList< + TypeList, + TypeList > AllNodeBaseTypes; + +/// \brief Helper meta-function to extract the argument out of a function of +/// type void(Arg). +/// +/// See AST_POLYMORPHIC_SUPPORTED_TYPES_* for details. +template struct ExtractFunctionArgMeta; +template struct ExtractFunctionArgMeta { + typedef T type; +}; + +/// \brief Default type lists for ArgumentAdaptingMatcher matchers. +typedef AllNodeBaseTypes AdaptativeDefaultFromTypes; +typedef TypeList, + TypeList > +AdaptativeDefaultToTypes; + +/// \brief All types that are supported by HasDeclarationMatcher above. +typedef TypeList, + TypeList, + TypeList, + TypeList > +HasDeclarationSupportedTypes; + /// \brief Converts a \c Matcher to a matcher of desired type \c To by /// "adapting" a \c To into a \c T. /// @@ -646,19 +904,33 @@ protected: /// If a matcher does not need knowledge about the inner type, prefer to use /// PolymorphicMatcherWithParam1. template