aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-12-01 14:53:08 -0800
committerStephen Hines <srhines@google.com>2014-12-01 14:53:08 -0800
commit176edba5311f6eff0cad2631449885ddf4fbc9ea (patch)
treef45baf023a7673970fc373bcdd0de5dc919905a1 /include
parent8b939a0498b8d24f4a5d7c6e6ac94ddba75ee933 (diff)
downloadclang-176edba5311f6eff0cad2631449885ddf4fbc9ea.tar.gz
Update aosp/master Clang for rebase to r222490.
Change-Id: Ic557ac55e97fbf6ee08771c7b7c3594777b0aefd
Diffstat (limited to 'include')
-rw-r--r--include/clang-c/BuildSystem.h4
-rw-r--r--include/clang-c/CXCompilationDatabase.h4
-rw-r--r--include/clang-c/CXErrorCode.h4
-rw-r--r--include/clang-c/CXString.h4
-rw-r--r--include/clang-c/Documentation.h4
-rw-r--r--include/clang-c/Index.h227
-rw-r--r--include/clang-c/Platform.h4
-rw-r--r--include/clang/ARCMigrate/ARCMTActions.h12
-rw-r--r--include/clang/ARCMigrate/FileRemapper.h4
-rw-r--r--include/clang/AST/ASTContext.h111
-rw-r--r--include/clang/AST/ASTDiagnostic.h4
-rw-r--r--include/clang/AST/ASTFwd.h5
-rw-r--r--include/clang/AST/ASTLambda.h6
-rw-r--r--include/clang/AST/ASTMutationListener.h6
-rw-r--r--include/clang/AST/ASTTypeTraits.h50
-rw-r--r--include/clang/AST/ASTVector.h23
-rw-r--r--include/clang/AST/Attr.h1
-rw-r--r--include/clang/AST/CanonicalType.h6
-rw-r--r--include/clang/AST/Comment.h10
-rw-r--r--include/clang/AST/CommentBriefParser.h4
-rw-r--r--include/clang/AST/CommentCommandTraits.h10
-rw-r--r--include/clang/AST/CommentDiagnostic.h4
-rw-r--r--include/clang/AST/CommentLexer.h4
-rw-r--r--include/clang/AST/CommentParser.h4
-rw-r--r--include/clang/AST/CommentSema.h6
-rw-r--r--include/clang/AST/DataRecursiveASTVisitor.h149
-rw-r--r--include/clang/AST/Decl.h153
-rw-r--r--include/clang/AST/DeclBase.h21
-rw-r--r--include/clang/AST/DeclCXX.h103
-rw-r--r--include/clang/AST/DeclFriend.h4
-rw-r--r--include/clang/AST/DeclObjC.h21
-rw-r--r--include/clang/AST/DeclOpenMP.h10
-rw-r--r--include/clang/AST/DeclTemplate.h8
-rw-r--r--include/clang/AST/DeclarationName.h1
-rw-r--r--include/clang/AST/DependentDiagnostic.h4
-rw-r--r--include/clang/AST/Expr.h102
-rw-r--r--include/clang/AST/ExprCXX.h117
-rw-r--r--include/clang/AST/ExternalASTSource.h6
-rw-r--r--include/clang/AST/LambdaCapture.h12
-rw-r--r--include/clang/AST/Mangle.h5
-rw-r--r--include/clang/AST/MangleNumberingContext.h17
-rw-r--r--include/clang/AST/NSAPI.h10
-rw-r--r--include/clang/AST/NestedNameSpecifier.h34
-rw-r--r--include/clang/AST/OpenMPClause.h429
-rw-r--r--include/clang/AST/OperationKinds.h4
-rw-r--r--include/clang/AST/ParentMap.h4
-rw-r--r--include/clang/AST/PrettyPrinter.h4
-rw-r--r--include/clang/AST/RawCommentList.h4
-rw-r--r--include/clang/AST/RecordLayout.h4
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h149
-rw-r--r--include/clang/AST/Stmt.h80
-rw-r--r--include/clang/AST/StmtGraphTraits.h4
-rw-r--r--include/clang/AST/StmtIterator.h4
-rw-r--r--include/clang/AST/StmtOpenMP.h1063
-rw-r--r--include/clang/AST/TemplateBase.h21
-rw-r--r--include/clang/AST/Type.h99
-rw-r--r--include/clang/AST/TypeLoc.h4
-rw-r--r--include/clang/AST/TypeOrdering.h4
-rw-r--r--include/clang/AST/UnresolvedSet.h2
-rw-r--r--include/clang/ASTMatchers/ASTMatchFinder.h69
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h250
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h612
-rw-r--r--include/clang/ASTMatchers/ASTMatchersMacros.h6
-rw-r--r--include/clang/ASTMatchers/Dynamic/Diagnostics.h4
-rw-r--r--include/clang/ASTMatchers/Dynamic/Parser.h130
-rw-r--r--include/clang/ASTMatchers/Dynamic/Registry.h51
-rw-r--r--include/clang/ASTMatchers/Dynamic/VariantValue.h184
-rw-r--r--include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h4
-rw-r--r--include/clang/Analysis/Analyses/Consumed.h4
-rw-r--r--include/clang/Analysis/Analyses/Dominators.h4
-rw-r--r--include/clang/Analysis/Analyses/FormatString.h10
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h4
-rw-r--r--include/clang/Analysis/Analyses/PostOrderCFGView.h12
-rw-r--r--include/clang/Analysis/Analyses/PseudoConstantAnalysis.h4
-rw-r--r--include/clang/Analysis/Analyses/ReachableCode.h4
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafety.h33
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyCommon.h139
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyLogical.h12
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyOps.def3
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTIL.h1104
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTraverse.h451
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyUtil.h63
-rw-r--r--include/clang/Analysis/Analyses/UninitializedValues.h4
-rw-r--r--include/clang/Analysis/AnalysisContext.h16
-rw-r--r--include/clang/Analysis/AnalysisDiagnostic.h4
-rw-r--r--include/clang/Analysis/CFG.h11
-rw-r--r--include/clang/Analysis/CFGStmtMap.h4
-rw-r--r--include/clang/Analysis/CallGraph.h4
-rw-r--r--include/clang/Analysis/CodeInjector.h46
-rw-r--r--include/clang/Analysis/DomainSpecific/CocoaConventions.h4
-rw-r--r--include/clang/Analysis/DomainSpecific/ObjCNoReturn.h4
-rw-r--r--include/clang/Analysis/ProgramPoint.h4
-rw-r--r--include/clang/Analysis/Support/BumpVector.h6
-rw-r--r--include/clang/Basic/ABI.h11
-rw-r--r--include/clang/Basic/AllDiagnostics.h4
-rw-r--r--include/clang/Basic/Attr.td186
-rw-r--r--include/clang/Basic/AttrDocs.td249
-rw-r--r--include/clang/Basic/AttrKinds.h4
-rw-r--r--include/clang/Basic/Attributes.h10
-rw-r--r--include/clang/Basic/Builtins.def20
-rw-r--r--include/clang/Basic/BuiltinsAArch64.def16
-rw-r--r--include/clang/Basic/BuiltinsARM.def5
-rw-r--r--include/clang/Basic/BuiltinsLe64.def19
-rw-r--r--include/clang/Basic/BuiltinsPPC.def19
-rw-r--r--include/clang/Basic/BuiltinsR600.def14
-rw-r--r--include/clang/Basic/BuiltinsX86.def171
-rw-r--r--include/clang/Basic/CharInfo.h4
-rw-r--r--include/clang/Basic/CommentOptions.h4
-rw-r--r--include/clang/Basic/Diagnostic.h28
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td7
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td14
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td21
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td55
-rw-r--r--include/clang/Basic/DiagnosticGroups.td63
-rw-r--r--include/clang/Basic/DiagnosticIDs.h26
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td18
-rw-r--r--include/clang/Basic/DiagnosticOptions.h4
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td123
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td450
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td7
-rw-r--r--include/clang/Basic/ExceptionSpecificationType.h3
-rw-r--r--include/clang/Basic/ExpressionTraits.h4
-rw-r--r--include/clang/Basic/FileManager.h24
-rw-r--r--include/clang/Basic/FileSystemStatCache.h12
-rw-r--r--include/clang/Basic/IdentifierTable.h62
-rw-r--r--include/clang/Basic/LLVM.h4
-rw-r--r--include/clang/Basic/Lambda.h3
-rw-r--r--include/clang/Basic/LangOptions.def69
-rw-r--r--include/clang/Basic/LangOptions.h26
-rw-r--r--include/clang/Basic/Module.h27
-rw-r--r--include/clang/Basic/ObjCRuntime.h4
-rw-r--r--include/clang/Basic/OpenMPKinds.def107
-rw-r--r--include/clang/Basic/OpenMPKinds.h6
-rw-r--r--include/clang/Basic/OperatorKinds.h4
-rw-r--r--include/clang/Basic/OperatorPrecedence.h4
-rw-r--r--include/clang/Basic/PartialDiagnostic.h4
-rw-r--r--include/clang/Basic/PlistSupport.h4
-rw-r--r--include/clang/Basic/PrettyStackTrace.h4
-rw-r--r--include/clang/Basic/SanitizerBlacklist.h45
-rw-r--r--include/clang/Basic/Sanitizers.def15
-rw-r--r--include/clang/Basic/Sanitizers.h47
-rw-r--r--include/clang/Basic/SourceLocation.h5
-rw-r--r--include/clang/Basic/SourceManager.h42
-rw-r--r--include/clang/Basic/SourceManagerInternals.h4
-rw-r--r--include/clang/Basic/Specifiers.h11
-rw-r--r--include/clang/Basic/StmtNodes.td22
-rw-r--r--include/clang/Basic/TargetBuiltins.h15
-rw-r--r--include/clang/Basic/TargetCXXABI.h4
-rw-r--r--include/clang/Basic/TargetInfo.h50
-rw-r--r--include/clang/Basic/TargetOptions.h4
-rw-r--r--include/clang/Basic/TemplateKinds.h4
-rw-r--r--include/clang/Basic/TokenKinds.def11
-rw-r--r--include/clang/Basic/TokenKinds.h10
-rw-r--r--include/clang/Basic/TypeTraits.h4
-rw-r--r--include/clang/Basic/VersionTuple.h29
-rw-r--r--include/clang/Basic/VirtualFileSystem.h34
-rw-r--r--include/clang/Basic/arm_neon.td51
-rw-r--r--include/clang/CodeGen/BackendUtil.h4
-rw-r--r--include/clang/CodeGen/CGFunctionInfo.h22
-rw-r--r--include/clang/CodeGen/CodeGenABITypes.h8
-rw-r--r--include/clang/CodeGen/CodeGenAction.h14
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h4
-rw-r--r--include/clang/Config/config.h2
-rw-r--r--include/clang/Config/config.h.cmake3
-rw-r--r--include/clang/Config/config.h.in6
-rw-r--r--include/clang/Driver/Action.h35
-rw-r--r--include/clang/Driver/CC1Options.td22
-rw-r--r--include/clang/Driver/CLCompatOptions.td19
-rw-r--r--include/clang/Driver/Compilation.h6
-rw-r--r--include/clang/Driver/Driver.h26
-rw-r--r--include/clang/Driver/DriverDiagnostic.h4
-rw-r--r--include/clang/Driver/Job.h70
-rw-r--r--include/clang/Driver/Multilib.h17
-rw-r--r--include/clang/Driver/Options.h4
-rw-r--r--include/clang/Driver/Options.td211
-rw-r--r--include/clang/Driver/Phases.h4
-rw-r--r--include/clang/Driver/SanitizerArgs.h126
-rw-r--r--include/clang/Driver/Tool.h61
-rw-r--r--include/clang/Driver/ToolChain.h21
-rw-r--r--include/clang/Driver/Types.h4
-rw-r--r--include/clang/Driver/Util.h11
-rw-r--r--include/clang/Format/Format.h92
-rw-r--r--include/clang/Frontend/ASTConsumers.h19
-rw-r--r--include/clang/Frontend/ASTUnit.h57
-rw-r--r--include/clang/Frontend/ChainedDiagnosticConsumer.h17
-rw-r--r--include/clang/Frontend/CodeGenOptions.def8
-rw-r--r--include/clang/Frontend/CodeGenOptions.h15
-rw-r--r--include/clang/Frontend/CompilerInstance.h35
-rw-r--r--include/clang/Frontend/DiagnosticRenderer.h4
-rw-r--r--include/clang/Frontend/FrontendAction.h41
-rw-r--r--include/clang/Frontend/FrontendActions.h51
-rw-r--r--include/clang/Frontend/FrontendDiagnostic.h4
-rw-r--r--include/clang/Frontend/FrontendOptions.h13
-rw-r--r--include/clang/Frontend/FrontendPluginRegistry.h7
-rw-r--r--include/clang/Frontend/LangStandard.h6
-rw-r--r--include/clang/Frontend/LangStandards.def22
-rw-r--r--include/clang/Frontend/LogDiagnosticPrinter.h15
-rw-r--r--include/clang/Frontend/MigratorOptions.h4
-rw-r--r--include/clang/Frontend/MultiplexConsumer.h14
-rw-r--r--include/clang/Frontend/SerializedDiagnosticPrinter.h45
-rw-r--r--include/clang/Frontend/SerializedDiagnosticReader.h131
-rw-r--r--include/clang/Frontend/SerializedDiagnostics.h59
-rw-r--r--include/clang/Frontend/TextDiagnostic.h4
-rw-r--r--include/clang/Frontend/TextDiagnosticBuffer.h4
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h4
-rw-r--r--include/clang/Frontend/Utils.h5
-rw-r--r--include/clang/Frontend/VerifyDiagnosticConsumer.h27
-rw-r--r--include/clang/Lex/ExternalPreprocessorSource.h6
-rw-r--r--include/clang/Lex/HeaderMap.h11
-rw-r--r--include/clang/Lex/HeaderSearch.h22
-rw-r--r--include/clang/Lex/LexDiagnostic.h4
-rw-r--r--include/clang/Lex/Lexer.h10
-rw-r--r--include/clang/Lex/LiteralSupport.h4
-rw-r--r--include/clang/Lex/MacroArgs.h4
-rw-r--r--include/clang/Lex/MacroInfo.h123
-rw-r--r--include/clang/Lex/ModuleLoader.h4
-rw-r--r--include/clang/Lex/ModuleMap.h68
-rw-r--r--include/clang/Lex/MultipleIncludeOpt.h4
-rw-r--r--include/clang/Lex/PPCallbacks.h11
-rw-r--r--include/clang/Lex/PTHLexer.h4
-rw-r--r--include/clang/Lex/PTHManager.h32
-rw-r--r--include/clang/Lex/Pragma.h4
-rw-r--r--include/clang/Lex/Preprocessor.h82
-rw-r--r--include/clang/Lex/PreprocessorLexer.h4
-rw-r--r--include/clang/Lex/ScratchBuffer.h4
-rw-r--r--include/clang/Lex/Token.h4
-rw-r--r--include/clang/Lex/TokenConcatenation.h4
-rw-r--r--include/clang/Lex/TokenLexer.h4
-rw-r--r--include/clang/Parse/ParseDiagnostic.h4
-rw-r--r--include/clang/Parse/Parser.h146
-rw-r--r--include/clang/Rewrite/Core/DeltaTree.h4
-rw-r--r--include/clang/Rewrite/Core/HTMLRewrite.h4
-rw-r--r--include/clang/Rewrite/Core/RewriteRope.h52
-rw-r--r--include/clang/Rewrite/Core/Rewriter.h14
-rw-r--r--include/clang/Rewrite/Core/TokenRewriter.h4
-rw-r--r--include/clang/Rewrite/Frontend/ASTConsumers.h32
-rw-r--r--include/clang/Rewrite/Frontend/FixItRewriter.h8
-rw-r--r--include/clang/Rewrite/Frontend/FrontendActions.h16
-rw-r--r--include/clang/Rewrite/Frontend/Rewriters.h4
-rw-r--r--include/clang/Sema/AnalysisBasedWarnings.h4
-rw-r--r--include/clang/Sema/AttributeList.h14
-rw-r--r--include/clang/Sema/DeclSpec.h41
-rw-r--r--include/clang/Sema/DelayedDiagnostic.h4
-rw-r--r--include/clang/Sema/ExternalSemaSource.h17
-rw-r--r--include/clang/Sema/IdentifierResolver.h4
-rw-r--r--include/clang/Sema/Initialization.h18
-rw-r--r--include/clang/Sema/Lookup.h27
-rw-r--r--include/clang/Sema/LoopHint.h22
-rw-r--r--include/clang/Sema/MultiplexExternalSemaSource.h15
-rw-r--r--include/clang/Sema/ObjCMethodList.h12
-rw-r--r--include/clang/Sema/Overload.h26
-rw-r--r--include/clang/Sema/PrettyDeclStackTrace.h4
-rw-r--r--include/clang/Sema/Scope.h3
-rw-r--r--include/clang/Sema/ScopeInfo.h41
-rw-r--r--include/clang/Sema/Sema.h468
-rw-r--r--include/clang/Sema/SemaDiagnostic.h4
-rw-r--r--include/clang/Sema/SemaFixItUtils.h6
-rw-r--r--include/clang/Sema/SemaInternal.h212
-rw-r--r--include/clang/Sema/SemaLambda.h6
-rw-r--r--include/clang/Sema/TemplateDeduction.h4
-rw-r--r--include/clang/Sema/TypoCorrection.h42
-rw-r--r--include/clang/Serialization/ASTBitCodes.h43
-rw-r--r--include/clang/Serialization/ASTDeserializationListener.h4
-rw-r--r--include/clang/Serialization/ASTReader.h120
-rw-r--r--include/clang/Serialization/ASTWriter.h42
-rw-r--r--include/clang/Serialization/ContinuousRangeMap.h12
-rw-r--r--include/clang/Serialization/GlobalModuleIndex.h6
-rw-r--r--include/clang/Serialization/Module.h15
-rw-r--r--include/clang/Serialization/ModuleManager.h23
-rw-r--r--include/clang/Serialization/SerializationDiagnostic.h4
-rw-r--r--include/clang/StaticAnalyzer/Checkers/LocalCheckers.h4
-rw-r--r--include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h14
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h12
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h21
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h30
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugType.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h12
-rw-r--r--include/clang/StaticAnalyzer/Core/Checker.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h9
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h9
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h23
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h15
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h19
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h11
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h10
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h14
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h4
-rw-r--r--include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h12
-rw-r--r--include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h12
-rw-r--r--include/clang/StaticAnalyzer/Frontend/FrontendActions.h33
-rw-r--r--include/clang/StaticAnalyzer/Frontend/ModelConsumer.h44
-rw-r--r--include/clang/Tooling/ArgumentsAdjusters.h19
-rw-r--r--include/clang/Tooling/CommonOptionsParser.h6
-rw-r--r--include/clang/Tooling/CompilationDatabase.h22
-rw-r--r--include/clang/Tooling/CompilationDatabasePluginRegistry.h6
-rw-r--r--include/clang/Tooling/Core/Replacement.h229
-rw-r--r--include/clang/Tooling/FileMatchTrie.h6
-rw-r--r--include/clang/Tooling/JSONCompilationDatabase.h19
-rw-r--r--include/clang/Tooling/Refactoring.h176
-rw-r--r--include/clang/Tooling/RefactoringCallbacks.h6
-rw-r--r--include/clang/Tooling/ReplacementsYaml.h6
-rw-r--r--include/clang/Tooling/Tooling.h29
-rw-r--r--include/clang/module.modulemap25
324 files changed, 9490 insertions, 3601 deletions
diff --git a/include/clang-c/BuildSystem.h b/include/clang-c/BuildSystem.h
index ed3e8d9a28..7aa01914cf 100644
--- a/include/clang-c/BuildSystem.h
+++ b/include/clang-c/BuildSystem.h
@@ -11,8 +11,8 @@
|* *|
\*===----------------------------------------------------------------------===*/
-#ifndef CLANG_C_BUILD_SYSTEM_H
-#define CLANG_C_BUILD_SYSTEM_H
+#ifndef LLVM_CLANG_C_BUILDSYSTEM_H
+#define LLVM_CLANG_C_BUILDSYSTEM_H
#include "clang-c/Platform.h"
#include "clang-c/CXErrorCode.h"
diff --git a/include/clang-c/CXCompilationDatabase.h b/include/clang-c/CXCompilationDatabase.h
index fd65418f60..068a677a95 100644
--- a/include/clang-c/CXCompilationDatabase.h
+++ b/include/clang-c/CXCompilationDatabase.h
@@ -12,8 +12,8 @@
|* *|
\*===----------------------------------------------------------------------===*/
-#ifndef CLANG_CXCOMPILATIONDATABASE_H
-#define CLANG_CXCOMPILATIONDATABASE_H
+#ifndef LLVM_CLANG_C_CXCOMPILATIONDATABASE_H
+#define LLVM_CLANG_C_CXCOMPILATIONDATABASE_H
#include "clang-c/Platform.h"
#include "clang-c/CXString.h"
diff --git a/include/clang-c/CXErrorCode.h b/include/clang-c/CXErrorCode.h
index a026c95a5b..aff73b7467 100644
--- a/include/clang-c/CXErrorCode.h
+++ b/include/clang-c/CXErrorCode.h
@@ -11,8 +11,8 @@
|* *|
\*===----------------------------------------------------------------------===*/
-#ifndef CLANG_C_CXERRORCODE_H
-#define CLANG_C_CXERRORCODE_H
+#ifndef LLVM_CLANG_C_CXERRORCODE_H
+#define LLVM_CLANG_C_CXERRORCODE_H
#include "clang-c/Platform.h"
diff --git a/include/clang-c/CXString.h b/include/clang-c/CXString.h
index cf198cbf5d..a649cdf82f 100644
--- a/include/clang-c/CXString.h
+++ b/include/clang-c/CXString.h
@@ -11,8 +11,8 @@
|* *|
\*===----------------------------------------------------------------------===*/
-#ifndef CLANG_CXSTRING_H
-#define CLANG_CXSTRING_H
+#ifndef LLVM_CLANG_C_CXSTRING_H
+#define LLVM_CLANG_C_CXSTRING_H
#include "clang-c/Platform.h"
diff --git a/include/clang-c/Documentation.h b/include/clang-c/Documentation.h
index ad2da07783..89373b1145 100644
--- a/include/clang-c/Documentation.h
+++ b/include/clang-c/Documentation.h
@@ -12,8 +12,8 @@
|* *|
\*===----------------------------------------------------------------------===*/
-#ifndef CLANG_C_DOCUMENTATION_H
-#define CLANG_C_DOCUMENTATION_H
+#ifndef LLVM_CLANG_C_DOCUMENTATION_H
+#define LLVM_CLANG_C_DOCUMENTATION_H
#include "clang-c/Index.h"
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index f6709f1af7..6e3bd07b7a 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -13,8 +13,8 @@
|* *|
\*===----------------------------------------------------------------------===*/
-#ifndef CLANG_C_INDEX_H
-#define CLANG_C_INDEX_H
+#ifndef LLVM_CLANG_C_INDEX_H
+#define LLVM_CLANG_C_INDEX_H
#include <time.h>
@@ -32,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 27
+#define CINDEX_VERSION_MINOR 29
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -336,6 +336,12 @@ CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu,
const char *file_name);
/**
+ * \brief Returns non-zero if the \c file1 and \c file2 point to the same file,
+ * or they are both NULL.
+ */
+CINDEX_LINKAGE int clang_File_isEqual(CXFile file1, CXFile file2);
+
+/**
* @}
*/
@@ -2163,11 +2169,63 @@ enum CXCursorKind {
*/
CXCursor_OMPParallelSectionsDirective = 239,
+ /** \brief OpenMP task directive.
+ */
+ CXCursor_OMPTaskDirective = 240,
+
+ /** \brief OpenMP master directive.
+ */
+ CXCursor_OMPMasterDirective = 241,
+
+ /** \brief OpenMP critical directive.
+ */
+ CXCursor_OMPCriticalDirective = 242,
+
+ /** \brief OpenMP taskyield directive.
+ */
+ CXCursor_OMPTaskyieldDirective = 243,
+
+ /** \brief OpenMP barrier directive.
+ */
+ CXCursor_OMPBarrierDirective = 244,
+
+ /** \brief OpenMP taskwait directive.
+ */
+ CXCursor_OMPTaskwaitDirective = 245,
+
+ /** \brief OpenMP flush directive.
+ */
+ CXCursor_OMPFlushDirective = 246,
+
/** \brief Windows Structured Exception Handling's leave statement.
*/
- CXCursor_SEHLeaveStmt = 240,
+ CXCursor_SEHLeaveStmt = 247,
+
+ /** \brief OpenMP ordered directive.
+ */
+ CXCursor_OMPOrderedDirective = 248,
+
+ /** \brief OpenMP atomic directive.
+ */
+ CXCursor_OMPAtomicDirective = 249,
+
+ /** \brief OpenMP for simd directive.
+ */
+ CXCursor_OMPForSimdDirective = 250,
+
+ /** \brief OpenMP parallel for simd directive.
+ */
+ CXCursor_OMPParallelForSimdDirective = 251,
- CXCursor_LastStmt = CXCursor_SEHLeaveStmt,
+ /** \brief OpenMP target directive.
+ */
+ CXCursor_OMPTargetDirective = 252,
+
+ /** \brief OpenMP teams directive.
+ */
+ CXCursor_OMPTeamsDirective = 253,
+
+ CXCursor_LastStmt = CXCursor_OMPTeamsDirective,
/**
* \brief Cursor that represents the translation unit itself.
@@ -2200,7 +2258,8 @@ enum CXCursorKind {
CXCursor_CUDADeviceAttr = 413,
CXCursor_CUDAGlobalAttr = 414,
CXCursor_CUDAHostAttr = 415,
- CXCursor_LastAttr = CXCursor_CUDAHostAttr,
+ CXCursor_CUDASharedAttr = 416,
+ CXCursor_LastAttr = CXCursor_CUDASharedAttr,
/* Preprocessing */
CXCursor_PreprocessingDirective = 500,
@@ -2794,6 +2853,7 @@ enum CXCallingConv {
CXCallingConv_IntelOclBicc = 9,
CXCallingConv_X86_64Win64 = 10,
CXCallingConv_X86_64SysV = 11,
+ CXCallingConv_X86VectorCall = 12,
CXCallingConv_Invalid = 100,
CXCallingConv_Unexposed = 200
@@ -2884,6 +2944,124 @@ CINDEX_LINKAGE int clang_Cursor_getNumArguments(CXCursor C);
CINDEX_LINKAGE CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i);
/**
+ * \brief Describes the kind of a template argument.
+ *
+ * See the definition of llvm::clang::TemplateArgument::ArgKind for full
+ * element descriptions.
+ */
+enum CXTemplateArgumentKind {
+ CXTemplateArgumentKind_Null,
+ CXTemplateArgumentKind_Type,
+ CXTemplateArgumentKind_Declaration,
+ CXTemplateArgumentKind_NullPtr,
+ CXTemplateArgumentKind_Integral,
+ CXTemplateArgumentKind_Template,
+ CXTemplateArgumentKind_TemplateExpansion,
+ CXTemplateArgumentKind_Expression,
+ CXTemplateArgumentKind_Pack,
+ /* Indicates an error case, preventing the kind from being deduced. */
+ CXTemplateArgumentKind_Invalid
+};
+
+/**
+ *\brief Returns the number of template args of a function decl representing a
+ * template specialization.
+ *
+ * If the argument cursor cannot be converted into a template function
+ * declaration, -1 is returned.
+ *
+ * For example, for the following declaration and specialization:
+ * template <typename T, int kInt, bool kBool>
+ * void foo() { ... }
+ *
+ * template <>
+ * void foo<float, -7, true>();
+ *
+ * The value 3 would be returned from this call.
+ */
+CINDEX_LINKAGE int clang_Cursor_getNumTemplateArguments(CXCursor C);
+
+/**
+ * \brief Retrieve the kind of the I'th template argument of the CXCursor C.
+ *
+ * If the argument CXCursor does not represent a FunctionDecl, an invalid
+ * template argument kind is returned.
+ *
+ * For example, for the following declaration and specialization:
+ * template <typename T, int kInt, bool kBool>
+ * void foo() { ... }
+ *
+ * template <>
+ * void foo<float, -7, true>();
+ *
+ * For I = 0, 1, and 2, Type, Integral, and Integral will be returned,
+ * respectively.
+ */
+CINDEX_LINKAGE enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(
+ CXCursor C, unsigned I);
+
+/**
+ * \brief Retrieve a CXType representing the type of a TemplateArgument of a
+ * function decl representing a template specialization.
+ *
+ * If the argument CXCursor does not represent a FunctionDecl whose I'th
+ * template argument has a kind of CXTemplateArgKind_Integral, an invalid type
+ * is returned.
+ *
+ * For example, for the following declaration and specialization:
+ * template <typename T, int kInt, bool kBool>
+ * void foo() { ... }
+ *
+ * template <>
+ * void foo<float, -7, true>();
+ *
+ * If called with I = 0, "float", will be returned.
+ * Invalid types will be returned for I == 1 or 2.
+ */
+CINDEX_LINKAGE CXType clang_Cursor_getTemplateArgumentType(CXCursor C,
+ unsigned I);
+
+/**
+ * \brief Retrieve the value of an Integral TemplateArgument (of a function
+ * decl representing a template specialization) as a signed long long.
+ *
+ * It is undefined to call this function on a CXCursor that does not represent a
+ * FunctionDecl or whose I'th template argument is not an integral value.
+ *
+ * For example, for the following declaration and specialization:
+ * template <typename T, int kInt, bool kBool>
+ * void foo() { ... }
+ *
+ * template <>
+ * void foo<float, -7, true>();
+ *
+ * If called with I = 1 or 2, -7 or true will be returned, respectively.
+ * For I == 0, this function's behavior is undefined.
+ */
+CINDEX_LINKAGE long long clang_Cursor_getTemplateArgumentValue(CXCursor C,
+ unsigned I);
+
+/**
+ * \brief Retrieve the value of an Integral TemplateArgument (of a function
+ * decl representing a template specialization) as an unsigned long long.
+ *
+ * It is undefined to call this function on a CXCursor that does not represent a
+ * FunctionDecl or whose I'th template argument is not an integral value.
+ *
+ * For example, for the following declaration and specialization:
+ * template <typename T, int kInt, bool kBool>
+ * void foo() { ... }
+ *
+ * template <>
+ * void foo<float, 2147483649, true>();
+ *
+ * If called with I = 1 or 2, 2147483649 or true will be returned, respectively.
+ * For I == 0, this function's behavior is undefined.
+ */
+CINDEX_LINKAGE unsigned long long clang_Cursor_getTemplateArgumentUnsignedValue(
+ CXCursor C, unsigned I);
+
+/**
* \brief Determine whether two CXTypes represent the same type.
*
* \returns non-zero if the CXTypes represent the same type and
@@ -3166,6 +3344,29 @@ enum CX_CXXAccessSpecifier {
CINDEX_LINKAGE enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor);
/**
+ * \brief Represents the storage classes as declared in the source. CX_SC_Invalid
+ * was added for the clase that the passed cursor in not a declaration.
+ */
+enum CX_StorageClass {
+ CX_SC_Invalid,
+ CX_SC_None,
+ CX_SC_Extern,
+ CX_SC_Static,
+ CX_SC_PrivateExtern,
+ CX_SC_OpenCLWorkGroupLocal,
+ CX_SC_Auto,
+ CX_SC_Register
+};
+
+/**
+ * \brief Returns the storage class for a function or variable declaration.
+ *
+ * If the passed in Cursor is not a function or variable declaration,
+ * CX_SC_Invalid is returned else the storage class.
+ */
+CINDEX_LINKAGE enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor);
+
+/**
* \brief Determine the number of overloaded declarations referenced by a
* \c CXCursor_OverloadedDeclRef cursor.
*
@@ -3603,6 +3804,20 @@ CINDEX_LINKAGE CXString clang_Cursor_getBriefCommentText(CXCursor C);
* @}
*/
+/** \defgroup CINDEX_MANGLE Name Mangling API Functions
+ *
+ * @{
+ */
+
+/**
+ * \brief Retrieve the CXString representing the mangled name of the cursor.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getMangling(CXCursor);
+
+/**
+ * @}
+ */
+
/**
* \defgroup CINDEX_MODULE Module introspection
*
diff --git a/include/clang-c/Platform.h b/include/clang-c/Platform.h
index 0f866c6456..e2a4dccbda 100644
--- a/include/clang-c/Platform.h
+++ b/include/clang-c/Platform.h
@@ -11,8 +11,8 @@
|* *|
\*===----------------------------------------------------------------------===*/
-#ifndef CLANG_C_PLATFORM_H
-#define CLANG_C_PLATFORM_H
+#ifndef LLVM_CLANG_C_PLATFORM_H
+#define LLVM_CLANG_C_PLATFORM_H
#ifdef __cplusplus
extern "C" {
diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h
index b3e74b9966..c830aa3d78 100644
--- a/include/clang/ARCMigrate/ARCMTActions.h
+++ b/include/clang/ARCMigrate/ARCMTActions.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
-#define LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
+#ifndef LLVM_CLANG_ARCMIGRATE_ARCMTACTIONS_H
+#define LLVM_CLANG_ARCMIGRATE_ARCMTACTIONS_H
#include "clang/ARCMigrate/FileRemapper.h"
#include "clang/Frontend/FrontendAction.h"
@@ -37,8 +37,8 @@ class MigrateSourceAction : public ASTFrontendAction {
FileRemapper Remapper;
protected:
bool BeginInvocation(CompilerInstance &CI) override;
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class MigrateAction : public WrapperFrontendAction {
@@ -65,8 +65,8 @@ public:
unsigned migrateAction);
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
bool BeginInvocation(CompilerInstance &CI) override;
};
diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h
index e094301ae6..53b88e9eb5 100644
--- a/include/clang/ARCMigrate/FileRemapper.h
+++ b/include/clang/ARCMigrate/FileRemapper.h
@@ -52,14 +52,14 @@ public:
bool overwriteOriginal(DiagnosticsEngine &Diag,
StringRef outputDir = StringRef());
- void remap(StringRef filePath, llvm::MemoryBuffer *memBuf);
+ void remap(StringRef filePath, std::unique_ptr<llvm::MemoryBuffer> memBuf);
void applyMappings(PreprocessorOptions &PPOpts) const;
void clear(StringRef outputDir = StringRef());
private:
- void remap(const FileEntry *file, llvm::MemoryBuffer *memBuf);
+ void remap(const FileEntry *file, std::unique_ptr<llvm::MemoryBuffer> memBuf);
void remap(const FileEntry *file, const FileEntry *newfile);
const FileEntry *getOriginalFile(StringRef filePath);
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 0a991cc4ce..ef87fa6dd9 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -30,6 +30,7 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SanitizerBlacklist.h"
#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
@@ -74,6 +75,15 @@ namespace clang {
class FullComment;
}
+ struct TypeInfo {
+ uint64_t Width;
+ unsigned Align;
+ bool AlignIsRequired : 1;
+ TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {}
+ TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
+ : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
+ };
+
/// \brief Holds long-lived AST nodes (such as types and decls) that can be
/// referred to throughout the semantic analysis of a file.
class ASTContext : public RefCountedBase<ASTContext> {
@@ -144,8 +154,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
ObjCLayouts;
/// \brief A cache from types to size and alignment information.
- typedef llvm::DenseMap<const Type*,
- std::pair<uint64_t, unsigned> > TypeInfoMap;
+ typedef llvm::DenseMap<const Type *, struct TypeInfo> TypeInfoMap;
mutable TypeInfoMap MemoizedTypeInfo;
/// \brief A cache mapping from CXXRecordDecls to key functions.
@@ -384,6 +393,10 @@ private:
/// this ASTContext object.
LangOptions &LangOpts;
+ /// \brief Blacklist object that is used by sanitizers to decide which
+ /// entities should not be instrumented.
+ std::unique_ptr<SanitizerBlacklist> SanitizerBL;
+
/// \brief The allocator used to create AST objects.
///
/// AST objects are never destructed; rather, all memory associated with the
@@ -453,11 +466,12 @@ public:
/// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc,
/// NestedNameSpecifier or NestedNameSpecifierLoc.
template <typename NodeT>
- ParentVector getParents(const NodeT &Node) {
+ ArrayRef<ast_type_traits::DynTypedNode> getParents(const NodeT &Node) {
return getParents(ast_type_traits::DynTypedNode::create(Node));
}
- ParentVector getParents(const ast_type_traits::DynTypedNode &Node);
+ ArrayRef<ast_type_traits::DynTypedNode>
+ getParents(const ast_type_traits::DynTypedNode &Node);
const clang::PrintingPolicy &getPrintingPolicy() const {
return PrintingPolicy;
@@ -508,6 +522,10 @@ public:
const LangOptions& getLangOpts() const { return LangOpts; }
+ const SanitizerBlacklist &getSanitizerBlacklist() const {
+ return *SanitizerBL;
+ }
+
DiagnosticsEngine &getDiagnostics() const;
FullSourceLoc getFullLoc(SourceLocation Loc) const {
@@ -912,6 +930,12 @@ public:
/// \brief Change the result type of a function type once it is deduced.
void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
+ /// \brief Change the exception specification on a function once it is
+ /// delay-parsed, instantiated, or computed.
+ void adjustExceptionSpec(FunctionDecl *FD,
+ const FunctionProtoType::ExceptionSpecInfo &ESI,
+ bool AsWritten = false);
+
/// \brief Return the uniqued reference to the type for a complex
/// number with the specified element type.
QualType getComplexType(QualType T) const;
@@ -1371,7 +1395,8 @@ public:
///
/// If \p Field is specified then record field names are also encoded.
void getObjCEncodingForType(QualType T, std::string &S,
- const FieldDecl *Field=nullptr) const;
+ const FieldDecl *Field=nullptr,
+ QualType *NotEncodedT=nullptr) const;
/// \brief Emit the Objective-C property type encoding for the given
/// type \p T into \p S.
@@ -1581,7 +1606,7 @@ public:
private:
CanQualType getFromTargetType(unsigned Type) const;
- std::pair<uint64_t, unsigned> getTypeInfoImpl(const Type *T) const;
+ TypeInfo getTypeInfoImpl(const Type *T) const;
//===--------------------------------------------------------------------===//
// Type Predicates.
@@ -1614,18 +1639,12 @@ public:
const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const;
/// \brief Get the size and alignment of the specified complete type in bits.
- std::pair<uint64_t, unsigned> getTypeInfo(const Type *T) const;
- std::pair<uint64_t, unsigned> getTypeInfo(QualType T) const {
- return getTypeInfo(T.getTypePtr());
- }
+ TypeInfo getTypeInfo(const Type *T) const;
+ TypeInfo getTypeInfo(QualType T) const { return getTypeInfo(T.getTypePtr()); }
/// \brief Return the size of the specified (complete) type \p T, in bits.
- uint64_t getTypeSize(QualType T) const {
- return getTypeInfo(T).first;
- }
- uint64_t getTypeSize(const Type *T) const {
- return getTypeInfo(T).first;
- }
+ uint64_t getTypeSize(QualType T) const { return getTypeInfo(T).Width; }
+ uint64_t getTypeSize(const Type *T) const { return getTypeInfo(T).Width; }
/// \brief Return the size of the character type, in bits.
uint64_t getCharWidth() const {
@@ -1645,12 +1664,8 @@ public:
/// \brief Return the ABI-specified alignment of a (complete) type \p T, in
/// bits.
- unsigned getTypeAlign(QualType T) const {
- return getTypeInfo(T).second;
- }
- unsigned getTypeAlign(const Type *T) const {
- return getTypeInfo(T).second;
- }
+ unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; }
+ unsigned getTypeAlign(const Type *T) const { return getTypeInfo(T).Align; }
/// \brief Return the ABI-specified alignment of a (complete) type \p T, in
/// characters.
@@ -1664,6 +1679,11 @@ public:
std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T) const;
std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T) const;
+ /// \brief Determine if the alignment the type has was required using an
+ /// alignment attribute.
+ bool isAlignmentRequired(const Type *T) const;
+ bool isAlignmentRequired(QualType T) const;
+
/// \brief Return the "preferred" alignment of the specified type \p T for
/// the current target, in bits.
///
@@ -2272,17 +2292,23 @@ private:
bool StructField = false,
bool EncodeBlockParameters = false,
bool EncodeClassNames = false,
- bool EncodePointerToObjCTypedef = false) const;
+ bool EncodePointerToObjCTypedef = false,
+ QualType *NotEncodedT=nullptr) const;
// Adds the encoding of the structure's members.
void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
const FieldDecl *Field,
- bool includeVBases = true) const;
+ bool includeVBases = true,
+ QualType *NotEncodedT=nullptr) const;
public:
// Adds the encoding of a method parameter or return type.
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
QualType T, std::string& S,
bool Extended) const;
+
+ /// \brief Returns true if this is an inline-initialized static data member
+ /// which is treated as a definition for MSVC compatibility.
+ bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;
private:
const ASTRecordLayout &
@@ -2308,6 +2334,31 @@ private:
std::unique_ptr<ParentMap> AllParents;
std::unique_ptr<VTableContextBase> VTContext;
+
+public:
+ enum PragmaSectionFlag : unsigned {
+ PSF_None = 0,
+ PSF_Read = 0x1,
+ PSF_Write = 0x2,
+ PSF_Execute = 0x4,
+ PSF_Implicit = 0x8,
+ PSF_Invalid = 0x80000000U,
+ };
+
+ struct SectionInfo {
+ DeclaratorDecl *Decl;
+ SourceLocation PragmaSectionLocation;
+ int SectionFlags;
+ SectionInfo() {}
+ SectionInfo(DeclaratorDecl *Decl,
+ SourceLocation PragmaSectionLocation,
+ int SectionFlags)
+ : Decl(Decl),
+ PragmaSectionLocation(PragmaSectionLocation),
+ SectionFlags(SectionFlags) {}
+ };
+
+ llvm::StringMap<SectionInfo> SectionInfos;
};
/// \brief Utility function for constructing a nullary selector.
@@ -2345,9 +2396,9 @@ static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
/// // Specific alignment
/// IntegerLiteral *Ex2 = new (Context, 4) IntegerLiteral(arguments);
/// @endcode
-/// Please note that you cannot use delete on the pointer; it must be
-/// deallocated using an explicit destructor call followed by
-/// @c Context.Deallocate(Ptr).
+/// Memory allocated through this placement new operator does not need to be
+/// explicitly freed, as ASTContext will free all of this memory when it gets
+/// destroyed. Please note that you cannot use delete on the pointer.
///
/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
/// @param C The ASTContext that provides the allocator.
@@ -2382,9 +2433,9 @@ inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
/// // Specific alignment
/// char *data = new (Context, 4) char[10];
/// @endcode
-/// Please note that you cannot use delete on the pointer; it must be
-/// deallocated using an explicit destructor call followed by
-/// @c Context.Deallocate(Ptr).
+/// Memory allocated through this placement new[] operator does not need to be
+/// explicitly freed, as ASTContext will free all of this memory when it gets
+/// destroyed. Please note that you cannot use delete on the pointer.
///
/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
/// @param C The ASTContext that provides the allocator.
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index 484ca4cb86..27c85e65f2 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_DIAGNOSTICAST_H
-#define LLVM_CLANG_DIAGNOSTICAST_H
+#ifndef LLVM_CLANG_AST_ASTDIAGNOSTIC_H
+#define LLVM_CLANG_AST_ASTDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
diff --git a/include/clang/AST/ASTFwd.h b/include/clang/AST/ASTFwd.h
index 4f3279874b..003d489c1c 100644
--- a/include/clang/AST/ASTFwd.h
+++ b/include/clang/AST/ASTFwd.h
@@ -12,6 +12,9 @@
///
//===-------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_ASTFWD_H
+#define LLVM_CLANG_AST_ASTFWD_H
+
namespace clang {
class Decl;
@@ -26,3 +29,5 @@ class Type;
class CXXCtorInitializer;
} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h
index 9af016b13d..69df2d8c01 100644
--- a/include/clang/AST/ASTLambda.h
+++ b/include/clang/AST/ASTLambda.h
@@ -13,8 +13,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_LAMBDA_H
-#define LLVM_CLANG_AST_LAMBDA_H
+#ifndef LLVM_CLANG_AST_ASTLAMBDA_H
+#define LLVM_CLANG_AST_ASTLAMBDA_H
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
@@ -77,4 +77,4 @@ inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) {
} // clang
-#endif // LLVM_CLANG_AST_LAMBDA_H
+#endif
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index a89bfed53f..48eb629277 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -102,6 +102,12 @@ public:
/// \param D the declaration marked used
virtual void DeclarationMarkedUsed(const Decl *D) {}
+ /// \brief A declaration is marked as OpenMP threadprivate which was not
+ /// previously marked as threadprivate.
+ ///
+ /// \param D the declaration marked OpenMP threadprivate.
+ virtual void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {}
+
// NOTE: If new methods are added they should also be added to
// MultiplexASTMutationListener.
};
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
index 0e06e26e6d..efeac563db 100644
--- a/include/clang/AST/ASTTypeTraits.h
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_AST_TYPE_TRAITS_H
-#define LLVM_CLANG_AST_AST_TYPE_TRAITS_H
+#ifndef LLVM_CLANG_AST_ASTTYPETRAITS_H
+#define LLVM_CLANG_AST_ASTTYPETRAITS_H
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Decl.h"
@@ -53,9 +53,19 @@ public:
return ASTNodeKind(KindToKindId<T>::Id);
}
+ /// \{
+ /// \brief Construct an identifier for the dynamic type of the node
+ static ASTNodeKind getFromNode(const Decl &D);
+ static ASTNodeKind getFromNode(const Stmt &S);
+ static ASTNodeKind getFromNode(const Type &T);
+ /// \}
+
/// \brief Returns \c true if \c this and \c Other represent the same kind.
bool isSame(ASTNodeKind Other) const;
+ /// \brief Returns \c true only for the default \c ASTNodeKind()
+ bool isNone() const { return KindId == NKI_None; }
+
/// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
/// \param Distance If non-null, used to return the distance between \c this
/// and \c Other in the class hierarchy.
@@ -69,6 +79,17 @@ public:
return KindId < Other.KindId;
}
+ /// \brief Return the most derived type between \p Kind1 and \p Kind2.
+ ///
+ /// Return ASTNodeKind() if they are not related.
+ static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2);
+
+ /// \brief Return the most derived common ancestor between Kind1 and Kind2.
+ ///
+ /// Return ASTNodeKind() if they are not related.
+ static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1,
+ ASTNodeKind Kind2);
+
private:
/// \brief Kind ids.
///
@@ -184,12 +205,14 @@ public:
return BaseConverter<T>::get(NodeKind, Storage.buffer);
}
+ ASTNodeKind getNodeKind() const { return NodeKind; }
+
/// \brief Returns a pointer that identifies the stored AST node.
///
/// Note that this is not supported by all AST nodes. For AST nodes
/// that don't have a pointer-defined identity inside the AST, this
/// method returns NULL.
- const void *getMemoizationData() const;
+ const void *getMemoizationData() const { return MemoizationData; }
/// \brief Prints the node to the given output stream.
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
@@ -241,7 +264,8 @@ private:
}
static DynTypedNode create(const BaseT &Node) {
DynTypedNode Result;
- Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+ Result.NodeKind = ASTNodeKind::getFromNode(Node);
+ Result.MemoizationData = &Node;
new (Result.Storage.buffer) const BaseT * (&Node);
return Result;
}
@@ -257,6 +281,7 @@ private:
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+ Result.MemoizationData = &Node;
new (Result.Storage.buffer) const T * (&Node);
return Result;
}
@@ -272,12 +297,14 @@ private:
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+ Result.MemoizationData = nullptr;
new (Result.Storage.buffer) T(Node);
return Result;
}
};
ASTNodeKind NodeKind;
+ const void *MemoizationData;
/// \brief Stores the data of the node.
///
@@ -345,20 +372,7 @@ template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
}
};
-inline const void *DynTypedNode::getMemoizationData() const {
- if (ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(NodeKind)) {
- return BaseConverter<Decl>::get(NodeKind, Storage.buffer);
- } else if (ASTNodeKind::getFromNodeKind<Stmt>().isBaseOf(NodeKind)) {
- return BaseConverter<Stmt>::get(NodeKind, Storage.buffer);
- } else if (ASTNodeKind::getFromNodeKind<Type>().isBaseOf(NodeKind)) {
- return BaseConverter<Type>::get(NodeKind, Storage.buffer);
- } else if (ASTNodeKind::getFromNodeKind<NestedNameSpecifier>().isBaseOf(NodeKind)) {
- return BaseConverter<NestedNameSpecifier>::get(NodeKind, Storage.buffer);
- }
- return nullptr;
-}
-
} // end namespace ast_type_traits
} // end namespace clang
-#endif // LLVM_CLANG_AST_AST_TYPE_TRAITS_H
+#endif
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index d92167e959..6ec054582e 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -15,8 +15,8 @@
// FIXME: Most of this is copy-and-paste from BumpVector.h and SmallVector.h.
// We can refactor this core logic into something common.
-#ifndef LLVM_CLANG_AST_VECTOR
-#define LLVM_CLANG_AST_VECTOR
+#ifndef LLVM_CLANG_AST_ASTVECTOR_H
+#define LLVM_CLANG_AST_ASTVECTOR_H
#include "clang/AST/AttrIterator.h"
#include "llvm/ADT/PointerIntPair.h"
@@ -236,14 +236,14 @@ public:
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);
- return this->end()-1;
- }
-
// Convert iterator to elt# to avoid invalidating iterator when we reserve()
size_t InsertElt = I - this->begin();
+ if (I == this->end()) { // Important special case for empty vector.
+ append(C, NumToInsert, Elt);
+ return this->begin() + InsertElt;
+ }
+
// Ensure there is enough space.
reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
@@ -284,14 +284,15 @@ public:
template<typename ItTy>
iterator insert(const ASTContext &C, iterator I, ItTy From, ItTy To) {
- if (I == this->end()) { // Important special case for empty vector.
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ size_t InsertElt = I - this->begin();
+
+ if (I == this->end()) { // Important special case for empty vector.
append(C, From, To);
- return this->end()-1;
+ return this->begin() + InsertElt;
}
size_t NumToInsert = std::distance(From, To);
- // Convert iterator to elt# to avoid invalidating iterator when we reserve()
- size_t InsertElt = I - this->begin();
// Ensure there is enough space.
reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index fc4881619b..787843e64f 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -16,6 +16,7 @@
#include "clang/AST/AttrIterator.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/LLVM.h"
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 7cccef69dd..aa3c846829 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_CANONICAL_TYPE_H
-#define LLVM_CLANG_AST_CANONICAL_TYPE_H
+#ifndef LLVM_CLANG_AST_CANONICALTYPE_H
+#define LLVM_CLANG_AST_CANONICALTYPE_H
#include "clang/AST/Type.h"
#include "llvm/Support/Casting.h"
@@ -736,4 +736,4 @@ CanTypeIterator<InputIterator>::operator->() const {
}
-#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H
+#endif
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index e18fe9ab86..94470cbf30 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -96,9 +96,10 @@ protected:
unsigned : NumInlineContentCommentBits;
unsigned RenderKind : 2;
- unsigned CommandID : 8;
+ unsigned CommandID : CommandInfo::NumCommandIDBits;
};
- enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 };
+ enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 2 +
+ CommandInfo::NumCommandIDBits };
class HTMLTagCommentBitfields {
friend class HTMLTagComment;
@@ -139,13 +140,14 @@ protected:
unsigned : NumCommentBits;
- unsigned CommandID : 8;
+ unsigned CommandID : CommandInfo::NumCommandIDBits;
/// Describes the syntax that was used in a documentation command.
/// Contains values from CommandMarkerKind enum.
unsigned CommandMarker : 1;
};
- enum { NumBlockCommandCommentBits = NumCommentBits + 9 };
+ enum { NumBlockCommandCommentBits = NumCommentBits +
+ CommandInfo::NumCommandIDBits + 1 };
class ParamCommandCommentBitfields {
friend class ParamCommandComment;
diff --git a/include/clang/AST/CommentBriefParser.h b/include/clang/AST/CommentBriefParser.h
index 5d50886063..be5b8eeb80 100644
--- a/include/clang/AST/CommentBriefParser.h
+++ b/include/clang/AST/CommentBriefParser.h
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_BRIEF_COMMENT_PARSER_H
-#define LLVM_CLANG_AST_BRIEF_COMMENT_PARSER_H
+#ifndef LLVM_CLANG_AST_COMMENTBRIEFPARSER_H
+#define LLVM_CLANG_AST_COMMENTBRIEFPARSER_H
#include "clang/AST/CommentLexer.h"
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h
index dde7a1442f..ec6d83c030 100644
--- a/include/clang/AST/CommentCommandTraits.h
+++ b/include/clang/AST/CommentCommandTraits.h
@@ -13,8 +13,8 @@
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
-#define LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
+#ifndef LLVM_CLANG_AST_COMMENTCOMMANDTRAITS_H
+#define LLVM_CLANG_AST_COMMENTCOMMANDTRAITS_H
#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/LLVM.h"
@@ -40,7 +40,11 @@ struct CommandInfo {
/// Name of the command that ends the verbatim block.
const char *EndCommandName;
- unsigned ID : 8;
+ /// DRY definition of the number of bits used for a command ID.
+ enum { NumCommandIDBits = 20 };
+
+ /// The ID of the command.
+ unsigned ID : NumCommandIDBits;
/// Number of word-like arguments for a given block command, except for
/// \\param and \\tparam commands -- these have special argument parsers.
diff --git a/include/clang/AST/CommentDiagnostic.h b/include/clang/AST/CommentDiagnostic.h
index 312da065ff..f3a209bf6e 100644
--- a/include/clang/AST/CommentDiagnostic.h
+++ b/include/clang/AST/CommentDiagnostic.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_COMMENTDIAGNOSTIC_H
-#define LLVM_CLANG_COMMENTDIAGNOSTIC_H
+#ifndef LLVM_CLANG_AST_COMMENTDIAGNOSTIC_H
+#define LLVM_CLANG_AST_COMMENTDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index a6e3ed89b2..d995df9212 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_COMMENT_LEXER_H
-#define LLVM_CLANG_AST_COMMENT_LEXER_H
+#ifndef LLVM_CLANG_AST_COMMENTLEXER_H
+#define LLVM_CLANG_AST_COMMENTLEXER_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h
index 7e008131d2..2c444f0dc3 100644
--- a/include/clang/AST/CommentParser.h
+++ b/include/clang/AST/CommentParser.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_COMMENT_PARSER_H
-#define LLVM_CLANG_AST_COMMENT_PARSER_H
+#ifndef LLVM_CLANG_AST_COMMENTPARSER_H
+#define LLVM_CLANG_AST_COMMENTPARSER_H
#include "clang/AST/Comment.h"
#include "clang/AST/CommentLexer.h"
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
index 027c3b929d..4ae6fe0c61 100644
--- a/include/clang/AST/CommentSema.h
+++ b/include/clang/AST/CommentSema.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_COMMENT_SEMA_H
-#define LLVM_CLANG_AST_COMMENT_SEMA_H
+#ifndef LLVM_CLANG_AST_COMMENTSEMA_H
+#define LLVM_CLANG_AST_COMMENTSEMA_H
#include "clang/AST/Comment.h"
#include "clang/Basic/Diagnostic.h"
@@ -85,7 +85,7 @@ public:
std::uninitialized_copy(Source.begin(), Source.end(), Mem);
return llvm::makeArrayRef(Mem, Size);
}
- return ArrayRef<T>();
+ return None;
}
ParagraphComment *actOnParagraphComment(
diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h
index e2dcdbe392..c0526e1cfd 100644
--- a/include/clang/AST/DataRecursiveASTVisitor.h
+++ b/include/clang/AST/DataRecursiveASTVisitor.h
@@ -424,6 +424,7 @@ private:
bool TraverseFunctionHelper(FunctionDecl *D);
bool TraverseVarHelper(VarDecl *D);
bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
+ bool TraverseOMPLoopDirective(OMPLoopDirective *S);
bool TraverseOMPClause(OMPClause *C);
#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
#include "clang/Basic/OpenMPKinds.def"
@@ -623,6 +624,7 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Super:
return true;
case NestedNameSpecifier::TypeSpec:
@@ -647,6 +649,7 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Super:
return true;
case NestedNameSpecifier::TypeSpec:
@@ -875,6 +878,9 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {
for (const auto &E : T->exceptions()) {
TRY_TO(TraverseType(E));
}
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TRY_TO(TraverseStmt(NE));
})
DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
@@ -1083,6 +1089,9 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
for (const auto &E : T->exceptions()) {
TRY_TO(TraverseType(E));
}
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TRY_TO(TraverseStmt(NE));
})
DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
@@ -2122,21 +2131,29 @@ bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
TRY_TO(TraverseLambdaCapture(S, C));
}
- if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
- TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
- if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
- // Visit the whole type.
- TRY_TO(TraverseTypeLoc(TL));
- } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
- if (S->hasExplicitParameters()) {
- // Visit parameters.
- for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
- TRY_TO(TraverseDecl(Proto.getParam(I)));
- }
- } else {
- TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
+ TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+ FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
+
+ if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
+ // Visit the whole type.
+ TRY_TO(TraverseTypeLoc(TL));
+ } else {
+ if (S->hasExplicitParameters()) {
+ // Visit parameters.
+ for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+ TRY_TO(TraverseDecl(Proto.getParam(I)));
}
+ } else if (S->hasExplicitResultType()) {
+ TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
}
+
+ auto *T = Proto.getTypePtr();
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TRY_TO(TraverseStmt(NE));
}
TRY_TO(TraverseLambdaBody(S));
@@ -2237,6 +2254,7 @@ DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
+DEF_TRAVERSE_STMT(TypoExpr, {})
DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
// These operators (all of them) do not need any action except
@@ -2253,6 +2271,7 @@ DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
+DEF_TRAVERSE_STMT(CXXFoldExpr, {})
DEF_TRAVERSE_STMT(AtomicExpr, {})
// These literals (all of them) do not need any action.
@@ -2279,6 +2298,12 @@ bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
return true;
}
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
+ return TraverseOMPExecutableDirective(S);
+}
+
DEF_TRAVERSE_STMT(OMPParallelDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2288,6 +2313,9 @@ DEF_TRAVERSE_STMT(OMPSimdDirective,
DEF_TRAVERSE_STMT(OMPForDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPForSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPSectionsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2297,12 +2325,50 @@ DEF_TRAVERSE_STMT(OMPSectionDirective,
DEF_TRAVERSE_STMT(OMPSingleDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPMasterDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPCriticalDirective, {
+ TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
+ TRY_TO(TraverseOMPExecutableDirective(S));
+})
+
DEF_TRAVERSE_STMT(OMPParallelForDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPTaskDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPBarrierDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPFlushDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPOrderedDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPAtomicDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTeamsDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
// OpenMP clauses.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
@@ -2328,6 +2394,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
+ TRY_TO(TraverseStmt(C->getCondition()));
+ return true;
+}
+
+template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
TRY_TO(TraverseStmt(C->getNumThreads()));
@@ -2375,6 +2447,42 @@ bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPWriteClause(OMPWriteClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
+ return true;
+}
+
+template <typename Derived>
template <typename T>
bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
for (auto *E : Node->varlists()) {
@@ -2386,6 +2494,9 @@ bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
TRY_TO(VisitOMPClauseList(C));
+ for (auto *E : C->private_copies()) {
+ TRY_TO(TraverseStmt(E));
+ }
return true;
}
@@ -2393,6 +2504,12 @@ template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
OMPFirstprivateClause *C) {
TRY_TO(VisitOMPClauseList(C));
+ for (auto *E : C->private_copies()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->inits()) {
+ TRY_TO(TraverseStmt(E));
+ }
return true;
}
@@ -2445,6 +2562,12 @@ RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
+ TRY_TO(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/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index ce8b8b7dbc..b946636ebd 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -43,6 +43,7 @@ class Stmt;
class StringLiteral;
class TemplateArgumentList;
class TemplateParameterList;
+class TypeAliasTemplateDecl;
class TypeLoc;
class UnresolvedSetImpl;
class VarTemplateDecl;
@@ -67,6 +68,9 @@ public:
/// \brief Return the TypeLoc wrapper for the type source info.
TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
+
+ /// \brief Override the type stored in this TypeSourceInfo. Use with caution!
+ void overrideType(QualType T) { Ty = T; }
};
/// TranslationUnitDecl - The top declaration context.
@@ -288,6 +292,8 @@ public:
return const_cast<NamedDecl*>(this)->getMostRecentDecl();
}
+ ObjCStringFormatFamily getObjCFStringFormattingFamily() const;
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; }
};
@@ -305,6 +311,8 @@ inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) {
class LabelDecl : public NamedDecl {
void anchor() override;
LabelStmt *TheStmt;
+ StringRef MSAsmName;
+ bool MSAsmNameResolved;
/// LocStart - For normal labels, this is the same as the main declaration
/// label, i.e., the location of the identifier; for GNU local labels,
/// this is the location of the __label__ keyword.
@@ -312,7 +320,10 @@ class LabelDecl : public NamedDecl {
LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II,
LabelStmt *S, SourceLocation StartL)
- : NamedDecl(Label, DC, IdentL, II), TheStmt(S), LocStart(StartL) {}
+ : NamedDecl(Label, DC, IdentL, II),
+ TheStmt(S),
+ MSAsmNameResolved(false),
+ LocStart(StartL) {}
public:
static LabelDecl *Create(ASTContext &C, DeclContext *DC,
@@ -332,6 +343,12 @@ public:
return SourceRange(LocStart, getLocation());
}
+ bool isMSAsmLabel() const { return MSAsmName.size() != 0; }
+ bool isResolvedMSAsmLabel() const { return isMSAsmLabel() && MSAsmNameResolved; }
+ void setMSAsmLabel(StringRef Name);
+ StringRef getMSAsmLabel() const { return MSAsmName; }
+ void setMSAsmLabelResolved() { MSAsmNameResolved = true; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Label; }
@@ -648,8 +665,6 @@ struct EvaluatedStmt {
/// declaration or definition.
class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
public:
- typedef clang::StorageClass StorageClass;
-
/// getStorageClassSpecifierString - Return the string used to
/// specify the storage class \p SC.
///
@@ -1423,8 +1438,6 @@ private:
class FunctionDecl : public DeclaratorDecl, public DeclContext,
public Redeclarable<FunctionDecl> {
public:
- typedef clang::StorageClass StorageClass;
-
/// \brief The kind of templated function a FunctionDecl can be.
enum TemplatedKind {
TK_NonTemplate,
@@ -1650,7 +1663,7 @@ public:
/// unnecessary AST de-serialization of the body.
Stmt *getBody(const FunctionDecl *&Definition) const;
- Stmt *getBody() const override {
+ Stmt *getBody() const override {
const FunctionDecl* Definition;
return getBody(Definition);
}
@@ -1880,7 +1893,7 @@ public:
return llvm::makeArrayRef(ParamInfo, getNumParams());
}
- const ArrayRef<NamedDecl *> &getDeclsInPrototypeScope() const {
+ ArrayRef<NamedDecl *> getDeclsInPrototypeScope() const {
return DeclsInPrototypeScope;
}
void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls);
@@ -2154,17 +2167,41 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
bool Mutable : 1;
mutable unsigned CachedFieldIndex : 31;
- /// \brief An InClassInitStyle value, and either a bit width expression (if
- /// the InClassInitStyle value is ICIS_NoInit), or a pointer to the in-class
- /// initializer for this field (otherwise).
+ /// The kinds of value we can store in InitializerOrBitWidth.
+ ///
+ /// Note that this is compatible with InClassInitStyle except for
+ /// ISK_CapturedVLAType.
+ enum InitStorageKind {
+ /// If the pointer is null, there's nothing special. Otherwise,
+ /// this is a bitfield and the pointer is the Expr* storing the
+ /// bit-width.
+ ISK_BitWidthOrNothing = (unsigned) ICIS_NoInit,
+
+ /// The pointer is an (optional due to delayed parsing) Expr*
+ /// holding the copy-initializer.
+ ISK_InClassCopyInit = (unsigned) ICIS_CopyInit,
+
+ /// The pointer is an (optional due to delayed parsing) Expr*
+ /// holding the list-initializer.
+ ISK_InClassListInit = (unsigned) ICIS_ListInit,
+
+ /// The pointer is a VariableArrayType* that's been captured;
+ /// the enclosing context is a lambda or captured statement.
+ ISK_CapturedVLAType,
+ };
+
+ /// \brief Storage for either the bit-width, the in-class
+ /// initializer, or the captured variable length array bound.
///
- /// We can safely combine these two because in-class initializers are not
- /// permitted for bit-fields.
+ /// We can safely combine these because in-class initializers are
+ /// not permitted for bit-fields, and both are exclusive with VLA
+ /// captures.
///
- /// If the InClassInitStyle is not ICIS_NoInit and the initializer is null,
- /// then this field has an in-class initializer which has not yet been parsed
+ /// If the storage kind is ISK_InClassCopyInit or
+ /// ISK_InClassListInit, but the initializer is null, then this
+ /// field has an in-class initializer which has not yet been parsed
/// and attached.
- llvm::PointerIntPair<Expr *, 2, unsigned> InitializerOrBitWidth;
+ llvm::PointerIntPair<void *, 2, InitStorageKind> InitStorage;
protected:
FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
@@ -2172,7 +2209,7 @@ protected:
InClassInitStyle InitStyle)
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
Mutable(Mutable), CachedFieldIndex(0),
- InitializerOrBitWidth(BW, InitStyle) {
+ InitStorage(BW, (InitStorageKind) InitStyle) {
assert((!BW || InitStyle == ICIS_NoInit) && "got initializer for bitfield");
}
@@ -2192,10 +2229,10 @@ public:
/// isMutable - Determines whether this field is mutable (C++ only).
bool isMutable() const { return Mutable; }
- /// isBitfield - Determines whether this field is a bitfield.
+ /// \brief Determines whether this field is a bitfield.
bool isBitField() const {
- return getInClassInitStyle() == ICIS_NoInit &&
- InitializerOrBitWidth.getPointer();
+ return InitStorage.getInt() == ISK_BitWidthOrNothing &&
+ InitStorage.getPointer() != nullptr;
}
/// @brief Determines whether this is an unnamed bitfield.
@@ -2208,24 +2245,34 @@ public:
bool isAnonymousStructOrUnion() const;
Expr *getBitWidth() const {
- return isBitField() ? InitializerOrBitWidth.getPointer() : nullptr;
+ return isBitField()
+ ? static_cast<Expr *>(InitStorage.getPointer())
+ : nullptr;
}
unsigned getBitWidthValue(const ASTContext &Ctx) const;
/// setBitWidth - Set the bit-field width for this member.
// Note: used by some clients (i.e., do not remove it).
- void setBitWidth(Expr *Width);
+ void setBitWidth(Expr *Width) {
+ assert(InitStorage.getInt() == ISK_BitWidthOrNothing &&
+ InitStorage.getPointer() == nullptr &&
+ "bit width, initializer or captured type already set");
+ InitStorage.setPointerAndInt(Width, ISK_BitWidthOrNothing);
+ }
+
/// removeBitWidth - Remove the bit-field width from this member.
// Note: used by some clients (i.e., do not remove it).
void removeBitWidth() {
assert(isBitField() && "no bitfield width to remove");
- InitializerOrBitWidth.setPointer(nullptr);
+ InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing);
}
/// getInClassInitStyle - Get the kind of (C++11) in-class initializer which
/// this field has.
InClassInitStyle getInClassInitStyle() const {
- return static_cast<InClassInitStyle>(InitializerOrBitWidth.getInt());
+ InitStorageKind storageKind = InitStorage.getInt();
+ return (storageKind == ISK_CapturedVLAType
+ ? ICIS_NoInit : (InClassInitStyle) storageKind);
}
/// hasInClassInitializer - Determine whether this member has a C++11 in-class
@@ -2233,24 +2280,47 @@ public:
bool hasInClassInitializer() const {
return getInClassInitStyle() != ICIS_NoInit;
}
+
/// getInClassInitializer - Get the C++11 in-class initializer for this
/// member, or null if one has not been set. If a valid declaration has an
/// in-class initializer, but this returns null, then we have not parsed and
/// attached it yet.
Expr *getInClassInitializer() const {
- return hasInClassInitializer() ? InitializerOrBitWidth.getPointer()
- : nullptr;
+ return hasInClassInitializer()
+ ? static_cast<Expr *>(InitStorage.getPointer())
+ : nullptr;
}
+
/// setInClassInitializer - Set the C++11 in-class initializer for this
/// member.
- void setInClassInitializer(Expr *Init);
+ void setInClassInitializer(Expr *Init) {
+ assert(hasInClassInitializer() &&
+ InitStorage.getPointer() == nullptr &&
+ "bit width, initializer or captured type already set");
+ InitStorage.setPointer(Init);
+ }
+
/// removeInClassInitializer - Remove the C++11 in-class initializer from this
/// member.
void removeInClassInitializer() {
assert(hasInClassInitializer() && "no initializer to remove");
- InitializerOrBitWidth.setPointer(nullptr);
- InitializerOrBitWidth.setInt(ICIS_NoInit);
+ InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing);
+ }
+
+ /// \brief Determine whether this member captures the variable length array
+ /// type.
+ bool hasCapturedVLAType() const {
+ return InitStorage.getInt() == ISK_CapturedVLAType;
+ }
+
+ /// \brief Get the captured variable length array type.
+ const VariableArrayType *getCapturedVLAType() const {
+ return hasCapturedVLAType() ? static_cast<const VariableArrayType *>(
+ InitStorage.getPointer())
+ : nullptr;
}
+ /// \brief Set the captured variable length array type for this field.
+ void setCapturedVLAType(const VariableArrayType *VLAType);
/// getParent - Returns the parent of this field declaration, which
/// is the struct in which this method is defined.
@@ -2492,9 +2562,13 @@ public:
/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
/// alias-declaration.
class TypeAliasDecl : public TypedefNameDecl {
+ /// The template for which this is the pattern, if any.
+ TypeAliasTemplateDecl *Template;
+
TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo) {}
+ : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo),
+ Template(nullptr) {}
public:
static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2504,6 +2578,9 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
+ TypeAliasTemplateDecl *getDescribedAliasTemplate() const { return Template; }
+ void setDescribedAliasTemplate(TypeAliasTemplateDecl *TAT) { Template = TAT; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == TypeAlias; }
@@ -2647,7 +2724,7 @@ public:
}
/// isThisDeclarationADefinition() - Return true if this declaration
- /// is a completion definintion of the type. Provided for consistency.
+ /// is a completion definition of the type. Provided for consistency.
bool isThisDeclarationADefinition() const {
return isCompleteDefinition();
}
@@ -3136,6 +3213,17 @@ public:
/// \endcode
bool isInjectedClassName() const;
+ /// \brief Determine whether this record is a class describing a lambda
+ /// function object.
+ bool isLambda() const;
+
+ /// \brief Determine whether this record is a record for captured variables in
+ /// CapturedStmt construct.
+ bool isCapturedRecord() const;
+ /// \brief Mark the record as a record for captured variables in CapturedStmt
+ /// construct.
+ void setCapturedRecord();
+
/// getDefinition - Returns the RecordDecl that actually defines
/// this struct/union/class. When determining whether or not a
/// struct/union/class is completely defined, one should use this
@@ -3181,6 +3269,11 @@ public:
/// commandline option.
bool isMsStruct(const ASTContext &C) const;
+ /// \brief Whether we are allowed to insert extra padding between fields.
+ /// These padding are added to help AddressSanitizer detect
+ /// intra-object-overflow bugs.
+ bool mayInsertExtraPadding(bool EmitRemark = false) const;
+
private:
/// \brief Deserialize just the fields.
void LoadFieldsFromExternalStorage() const;
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 607ca4ec27..984ab13df4 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -48,6 +48,7 @@ class ObjCInterfaceDecl;
class ObjCMethodDecl;
class ObjCProtocolDecl;
struct PrintingPolicy;
+class RecordDecl;
class Stmt;
class StoredDeclsMap;
class TranslationUnitDecl;
@@ -515,9 +516,13 @@ public:
/// indicating the declaration is used.
void markUsed(ASTContext &C);
- /// \brief Whether this declaration was referenced.
+ /// \brief Whether any declaration of this entity was referenced.
bool isReferenced() const;
+ /// \brief Whether this declaration was referenced. This should not be relied
+ /// upon for anything other than debugging.
+ bool isThisDeclarationReferenced() const { return Referenced; }
+
void setReferenced(bool R = true) { Referenced = R; }
/// \brief Whether this declaration is a top-level declaration (function,
@@ -675,9 +680,9 @@ public:
return const_cast<Decl*>(this)->getLexicalDeclContext();
}
- virtual bool isOutOfLine() const {
- return getLexicalDeclContext() != getDeclContext();
- }
+ /// Determine whether this declaration is declared out of line (outside its
+ /// semantic context).
+ virtual bool isOutOfLine() const;
/// setDeclContext - Set both the semantic and lexical DeclContext
/// to DC.
@@ -1234,6 +1239,12 @@ public:
return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
}
+ /// \brief Retrieve the outermost lexically enclosing record context.
+ RecordDecl *getOuterLexicalRecordContext();
+ const RecordDecl *getOuterLexicalRecordContext() const {
+ return const_cast<DeclContext *>(this)->getOuterLexicalRecordContext();
+ }
+
/// \brief Test if this context is part of the enclosing namespace set of
/// the context NS, as defined in C++0x [namespace.def]p9. If either context
/// isn't a namespace, this is equivalent to Equals().
@@ -1642,7 +1653,7 @@ public:
void dumpDeclContext() const;
void dumpLookups() const;
- void dumpLookups(llvm::raw_ostream &OS) const;
+ void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false) const;
private:
void reconcileExternalVisibleStorage() const;
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 72fad7c28e..062c1527d7 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -538,6 +538,12 @@ class CXXRecordDecl : public RecordDecl {
ManglingNumber(0), ContextDecl(nullptr), Captures(nullptr),
MethodTyInfo(Info) {
IsLambda = true;
+
+ // C++11 [expr.prim.lambda]p3:
+ // This class type is neither an aggregate nor a literal type.
+ Aggregate = false;
+ PlainOldData = false;
+ HasNonLiteralTypeFieldsOrBases = true;
}
/// \brief Whether this lambda is known to be dependent, even if its
@@ -1371,6 +1377,15 @@ public:
/// \brief Set the kind of specialization or template instantiation this is.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
+ /// \brief Retrieve the record declaration from which this record could be
+ /// instantiated. Returns null if this class is not a template instantiation.
+ const CXXRecordDecl *getTemplateInstantiationPattern() const;
+
+ CXXRecordDecl *getTemplateInstantiationPattern() {
+ return const_cast<CXXRecordDecl *>(const_cast<const CXXRecordDecl *>(this)
+ ->getTemplateInstantiationPattern());
+ }
+
/// \brief Returns the destructor decl for this class.
CXXDestructorDecl *getDestructor() const;
@@ -2104,8 +2119,8 @@ public:
}
ArrayRef<VarDecl *> getArrayIndexes() {
assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init");
- return ArrayRef<VarDecl *>(reinterpret_cast<VarDecl **>(this + 1),
- getNumArrayIndices());
+ return llvm::makeArrayRef(reinterpret_cast<VarDecl **>(this + 1),
+ getNumArrayIndices());
}
/// \brief Get the initializer.
@@ -2636,7 +2651,8 @@ public:
/// \code
/// namespace Foo = Bar;
/// \endcode
-class NamespaceAliasDecl : public NamedDecl {
+class NamespaceAliasDecl : public NamedDecl,
+ public Redeclarable<NamespaceAliasDecl> {
void anchor() override;
/// \brief The location of the \c namespace keyword.
@@ -2654,17 +2670,47 @@ class NamespaceAliasDecl : public NamedDecl {
/// a NamespaceAliasDecl.
NamedDecl *Namespace;
- NamespaceAliasDecl(DeclContext *DC, SourceLocation NamespaceLoc,
- SourceLocation AliasLoc, IdentifierInfo *Alias,
- NestedNameSpecifierLoc QualifierLoc,
+ NamespaceAliasDecl(ASTContext &C, DeclContext *DC,
+ SourceLocation NamespaceLoc, SourceLocation AliasLoc,
+ IdentifierInfo *Alias, NestedNameSpecifierLoc QualifierLoc,
SourceLocation IdentLoc, NamedDecl *Namespace)
- : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias),
- NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
- QualifierLoc(QualifierLoc), Namespace(Namespace) { }
+ : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias), redeclarable_base(C),
+ NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
+ QualifierLoc(QualifierLoc), Namespace(Namespace) {}
+
+ typedef Redeclarable<NamespaceAliasDecl> redeclarable_base;
+ NamespaceAliasDecl *getNextRedeclarationImpl() override;
+ NamespaceAliasDecl *getPreviousDeclImpl() override;
+ NamespaceAliasDecl *getMostRecentDeclImpl() override;
friend class ASTDeclReader;
public:
+ static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation NamespaceLoc,
+ SourceLocation AliasLoc,
+ IdentifierInfo *Alias,
+ NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation IdentLoc,
+ NamedDecl *Namespace);
+
+ static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ typedef redeclarable_base::redecl_range redecl_range;
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redeclarable_base::redecls_begin;
+ using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
+ using redeclarable_base::getPreviousDecl;
+ using redeclarable_base::getMostRecentDecl;
+
+ NamespaceAliasDecl *getCanonicalDecl() override {
+ return getFirstDecl();
+ }
+ const NamespaceAliasDecl *getCanonicalDecl() const {
+ return getFirstDecl();
+ }
+
/// \brief Retrieve the nested-name-specifier that qualifies the
/// name of the namespace, with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
@@ -2701,16 +2747,6 @@ public:
/// may either be a NamespaceDecl or a NamespaceAliasDecl.
NamedDecl *getAliasedNamespace() const { return Namespace; }
- static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation NamespaceLoc,
- SourceLocation AliasLoc,
- IdentifierInfo *Alias,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Namespace);
-
- static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(NamespaceLoc, IdentLoc);
}
@@ -2824,7 +2860,7 @@ public:
/// \code
/// using someNameSpace::someIdentifier;
/// \endcode
-class UsingDecl : public NamedDecl {
+class UsingDecl : public NamedDecl, public Mergeable<UsingDecl> {
void anchor() override;
/// \brief The source location of the 'using' keyword itself.
@@ -2948,6 +2984,10 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
+ /// Retrieves the canonical declaration of this declaration.
+ UsingDecl *getCanonicalDecl() override { return getFirstDecl(); }
+ const UsingDecl *getCanonicalDecl() const { return getFirstDecl(); }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Using; }
@@ -2966,7 +3006,8 @@ public:
/// using Base<T>::foo;
/// };
/// \endcode
-class UnresolvedUsingValueDecl : public ValueDecl {
+class UnresolvedUsingValueDecl : public ValueDecl,
+ public Mergeable<UnresolvedUsingValueDecl> {
void anchor() override;
/// \brief The source location of the 'using' keyword
@@ -3022,6 +3063,14 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
+ /// Retrieves the canonical declaration of this declaration.
+ UnresolvedUsingValueDecl *getCanonicalDecl() override {
+ return getFirstDecl();
+ }
+ const UnresolvedUsingValueDecl *getCanonicalDecl() const {
+ return getFirstDecl();
+ }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
@@ -3040,7 +3089,9 @@ public:
///
/// The type associated with an unresolved using typename decl is
/// currently always a typename type.
-class UnresolvedUsingTypenameDecl : public TypeDecl {
+class UnresolvedUsingTypenameDecl
+ : public TypeDecl,
+ public Mergeable<UnresolvedUsingTypenameDecl> {
void anchor() override;
/// \brief The source location of the 'typename' keyword
@@ -3084,6 +3135,14 @@ public:
static UnresolvedUsingTypenameDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
+ /// Retrieves the canonical declaration of this declaration.
+ UnresolvedUsingTypenameDecl *getCanonicalDecl() override {
+ return getFirstDecl();
+ }
+ const UnresolvedUsingTypenameDecl *getCanonicalDecl() const {
+ return getFirstDecl();
+ }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
};
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 97741c1c37..12b93b408a 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -135,8 +135,12 @@ public:
/// Retrieves the source range for the friend declaration.
SourceRange getSourceRange() const override LLVM_READONLY {
if (NamedDecl *ND = getFriendDecl()) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+ return FD->getSourceRange();
if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
return FTD->getSourceRange();
+ if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
+ return CTD->getSourceRange();
if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) {
if (DD->getOuterLocStart() != DD->getInnerLocStart())
return DD->getSourceRange();
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 520f523a6d..55d4b0f169 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -329,6 +329,7 @@ public:
QualType getReturnType() const { return MethodDeclType; }
void setReturnType(QualType T) { MethodDeclType = T; }
+ SourceRange getReturnTypeSourceRange() const;
/// \brief Determine the type of an expression that sends a message to this
/// function.
@@ -378,8 +379,7 @@ public:
/// ignored.
void setMethodParams(ASTContext &C,
ArrayRef<ParmVarDecl*> Params,
- ArrayRef<SourceLocation> SelLocs =
- ArrayRef<SourceLocation>());
+ ArrayRef<SourceLocation> SelLocs = llvm::None);
// Iterator access to parameter types.
typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
@@ -591,7 +591,8 @@ public:
bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
- ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
+ ObjCPropertyDecl *
+ FindPropertyDeclaration(const IdentifierInfo *PropertyId) const;
typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap;
@@ -956,6 +957,10 @@ public:
unsigned Num,
ASTContext &C);
+ /// Produce a name to be used for class's metadata. It comes either via
+ /// objc_runtime_name attribute or class name.
+ StringRef getObjCRuntimeNameAsString() const;
+
/// Returns the designated initializers for the interface.
///
/// If this declaration does not have methods marked as designated
@@ -1653,6 +1658,10 @@ public:
/// \brief Starts the definition of this Objective-C protocol.
void startDefinition();
+ /// Produce a name to be used for protocol's metadata. It comes either via
+ /// objc_runtime_name attribute or protocol name.
+ StringRef getObjCRuntimeNameAsString() const;
+
SourceRange getSourceRange() const override LLVM_READONLY {
if (isThisDeclarationADefinition())
return ObjCContainerDecl::getSourceRange();
@@ -2100,6 +2109,10 @@ public:
std::string getNameAsString() const {
return getName();
}
+
+ /// Produce a name to be used for class's metadata. It comes either via
+ /// class's objc_runtime_name attribute or class name.
+ StringRef getObjCRuntimeNameAsString() const;
const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
@@ -2342,7 +2355,7 @@ public:
/// Lookup a property by name in the specified DeclContext.
static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
- IdentifierInfo *propertyID);
+ const IdentifierInfo *propertyID);
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCProperty; }
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index 1b329dcd00..7f0616f1e6 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -12,13 +12,14 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_OPENMP_H
-#define LLVM_CLANG_AST_OPENMP_H
+#ifndef LLVM_CLANG_AST_DECLOPENMP_H
+#define LLVM_CLANG_AST_DECLOPENMP_H
#include "clang/AST/DeclBase.h"
#include "llvm/ADT/ArrayRef.h"
namespace clang {
+class Expr;
/// \brief This represents '#pragma omp threadprivate ...' directive.
/// For example, in the following, both 'a' and 'A::b' are threadprivate:
@@ -42,9 +43,8 @@ class OMPThreadPrivateDecl : public Decl {
Decl(DK, DC, L), NumVars(0) { }
ArrayRef<const Expr *> getVars() const {
- return ArrayRef<const Expr *>(
- reinterpret_cast<const Expr * const *>(this + 1),
- NumVars);
+ return llvm::makeArrayRef(reinterpret_cast<const Expr * const *>(this + 1),
+ NumVars);
}
MutableArrayRef<Expr *> getVars() {
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 980a06e35b..9283d2dc43 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -87,10 +87,10 @@ public:
unsigned size() const { return NumParams; }
ArrayRef<NamedDecl*> asArray() {
- return ArrayRef<NamedDecl*>(begin(), size());
+ return llvm::makeArrayRef(begin(), end());
}
ArrayRef<const NamedDecl*> asArray() const {
- return ArrayRef<const NamedDecl*>(begin(), size());
+ return llvm::makeArrayRef(begin(), size());
}
NamedDecl* getParam(unsigned Idx) {
@@ -204,7 +204,7 @@ public:
/// \brief Produce this as an array ref.
ArrayRef<TemplateArgument> asArray() const {
- return ArrayRef<TemplateArgument>(data(), size());
+ return llvm::makeArrayRef(data(), size());
}
/// \brief Retrieve the number of template arguments in this
@@ -236,7 +236,7 @@ protected:
TemplateParams(nullptr) {}
// Construct a template decl with the given name and parameters.
- // Used when there is not templated element (tt-params, alias?).
+ // Used when there is not templated element (tt-params).
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params)
: NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 3076b30cd3..49e51e09b8 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -59,6 +59,7 @@ public:
CXXLiteralOperatorName,
CXXUsingDirective
};
+ static const unsigned NumNameKinds = CXXUsingDirective + 1;
private:
/// StoredNameKind - The kind of name that is actually stored in the
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
index 63047ec4db..63066797b3 100644
--- a/include/clang/AST/DependentDiagnostic.h
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
-#define LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
+#ifndef LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
+#define LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclContextInternals.h"
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index e208280ccc..d94e225c74 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -45,6 +45,7 @@ namespace clang {
class ObjCPropertyRefExpr;
class OpaqueValueExpr;
class ParmVarDecl;
+ class StringLiteral;
class TargetInfo;
class ValueDecl;
@@ -124,8 +125,7 @@ public:
QualType getType() const { return TR; }
void setType(QualType t) {
// In C++, the type of an expression is always adjusted so that it
- // will not have reference type an expression will never have
- // reference type (C++ [expr]p6). Use
+ // will not have reference type (C++ [expr]p6). Use
// QualType::getNonReferenceType() to retrieve the non-reference
// type. Additionally, inspect Expr::isLvalue to determine whether
// an expression that is adjusted in this manner should be
@@ -1161,7 +1161,7 @@ public:
friend class ASTStmtWriter;
};
-/// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__.
+/// \brief [C99 6.4.2.2] - A predefined identifier such as __func__.
class PredefinedExpr : public Expr {
public:
enum IdentType {
@@ -1171,7 +1171,7 @@ public:
FuncDName,
FuncSig,
PrettyFunction,
- /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
+ /// \brief The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
PrettyFunctionNoVirtual
};
@@ -1179,24 +1179,27 @@ public:
private:
SourceLocation Loc;
IdentType Type;
+ Stmt *FnName;
+
public:
- PredefinedExpr(SourceLocation l, QualType type, IdentType IT)
- : Expr(PredefinedExprClass, type, VK_LValue, OK_Ordinary,
- type->isDependentType(), type->isDependentType(),
- type->isInstantiationDependentType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Loc(l), Type(IT) {}
+ PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT,
+ StringLiteral *SL);
/// \brief Construct an empty predefined expression.
explicit PredefinedExpr(EmptyShell Empty)
- : Expr(PredefinedExprClass, Empty) { }
+ : Expr(PredefinedExprClass, Empty), Loc(), Type(Func), FnName(nullptr) {}
IdentType getIdentType() const { return Type; }
- void setIdentType(IdentType IT) { Type = IT; }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
+ StringLiteral *getFunctionName();
+ const StringLiteral *getFunctionName() const {
+ return const_cast<PredefinedExpr *>(this)->getFunctionName();
+ }
+
+ static StringRef getIdentTypeName(IdentType IT);
static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
@@ -1207,7 +1210,9 @@ public:
}
// Iterators
- child_range children() { return child_range(); }
+ child_range children() { return child_range(&FnName, &FnName + 1); }
+
+ friend class ASTStmtReader;
};
/// \brief Used by IntegerLiteral/FloatingLiteral to store the numeric without
@@ -2212,11 +2217,11 @@ public:
/// getArg - Return the specified argument.
Expr *getArg(unsigned Arg) {
assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(SubExprs[Arg+getNumPreArgs()+PREARGS_START]);
+ return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
}
const Expr *getArg(unsigned Arg) const {
assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(SubExprs[Arg+getNumPreArgs()+PREARGS_START]);
+ return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
}
/// setArg - Set the specified argument.
@@ -2256,8 +2261,8 @@ public:
/// interface. This provides efficient reverse iteration of the
/// subexpressions. This is currently used for CFG construction.
ArrayRef<Stmt*> getRawSubExprs() {
- return ArrayRef<Stmt*>(SubExprs,
- getNumPreArgs() + PREARGS_START + getNumArgs());
+ return llvm::makeArrayRef(SubExprs,
+ getNumPreArgs() + PREARGS_START + getNumArgs());
}
/// getNumCommas - Return the number of commas that must have been present in
@@ -2653,9 +2658,6 @@ public:
/// representation in the source code (ExplicitCastExpr's derived
/// classes).
class CastExpr : public Expr {
-public:
- typedef clang::CastKind CastKind;
-
private:
Stmt *Op;
@@ -2673,20 +2675,23 @@ private:
}
protected:
- CastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
- const CastKind kind, Expr *op, unsigned BasePathSize) :
- Expr(SC, ty, VK, OK_Ordinary,
- // Cast expressions are type-dependent if the type is
- // dependent (C++ [temp.dep.expr]p3).
- ty->isDependentType(),
- // Cast expressions are value-dependent if the type is
- // dependent or if the subexpression is value-dependent.
- ty->isDependentType() || (op && op->isValueDependent()),
- (ty->isInstantiationDependentType() ||
- (op && op->isInstantiationDependent())),
- (ty->containsUnexpandedParameterPack() ||
- (op && op->containsUnexpandedParameterPack()))),
- Op(op) {
+ CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind,
+ Expr *op, unsigned BasePathSize)
+ : Expr(SC, ty, VK, OK_Ordinary,
+ // Cast expressions are type-dependent if the type is
+ // dependent (C++ [temp.dep.expr]p3).
+ ty->isDependentType(),
+ // Cast expressions are value-dependent if the type is
+ // dependent or if the subexpression is value-dependent.
+ ty->isDependentType() || (op && op->isValueDependent()),
+ (ty->isInstantiationDependentType() ||
+ (op && op->isInstantiationDependent())),
+ // An implicit cast expression doesn't (lexically) contain an
+ // unexpanded pack, even if its target type does.
+ ((SC != ImplicitCastExprClass &&
+ ty->containsUnexpandedParameterPack()) ||
+ (op && op->containsUnexpandedParameterPack()))),
+ Op(op) {
assert(kind != CK_Invalid && "creating cast with invalid cast kind");
CastExprBits.Kind = kind;
setBasePathSize(BasePathSize);
@@ -4167,6 +4172,17 @@ public:
return Designators + NumDesignators;
}
+ typedef llvm::iterator_range<designators_iterator> designators_range;
+ designators_range designators() {
+ return designators_range(designators_begin(), designators_end());
+ }
+
+ typedef llvm::iterator_range<const_designators_iterator>
+ designators_const_range;
+ designators_const_range designators() const {
+ return designators_const_range(designators_begin(), designators_end());
+ }
+
typedef std::reverse_iterator<designators_iterator>
reverse_designators_iterator;
reverse_designators_iterator designators_rbegin() {
@@ -4830,6 +4846,24 @@ public:
return child_range(SubExprs, SubExprs+NumSubExprs);
}
};
+
+/// TypoExpr - Internal placeholder for expressions where typo correction
+/// still needs to be performed and/or an error diagnostic emitted.
+class TypoExpr : public Expr {
+public:
+ TypoExpr(QualType T)
+ : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary,
+ /*isTypeDependent*/ true,
+ /*isValueDependent*/ true,
+ /*isInstantiationDependent*/ true,
+ /*containsUnexpandedParameterPack*/ false) {
+ assert(T->isDependentType() && "TypoExpr given a non-dependent type");
+ }
+
+ child_range children() { return child_range(); }
+ SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+};
} // end namespace clang
#endif
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 4403b0858f..040fbe7f92 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -737,8 +737,8 @@ public:
/// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
/// a single GUID.
- static UuidAttr *GetUuidAttrOfType(QualType QT,
- bool *HasMultipleGUIDsPtr = nullptr);
+ static const UuidAttr *GetUuidAttrOfType(QualType QT,
+ bool *HasMultipleGUIDsPtr = nullptr);
// Iterators
child_range children() {
@@ -967,8 +967,14 @@ public:
const FieldDecl *getField() const { return Field; }
/// \brief Get the initialization expression that will be used.
- const Expr *getExpr() const { return Field->getInClassInitializer(); }
- Expr *getExpr() { return Field->getInClassInitializer(); }
+ const Expr *getExpr() const {
+ assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
+ return Field->getInClassInitializer();
+ }
+ Expr *getExpr() {
+ assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
+ return Field->getInClassInitializer();
+ }
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
@@ -1077,6 +1083,7 @@ private:
bool Elidable : 1;
bool HadMultipleCandidates : 1;
bool ListInitialization : 1;
+ bool StdInitListInitialization : 1;
bool ZeroInitialization : 1;
unsigned ConstructKind : 2;
Stmt **Args;
@@ -1088,6 +1095,7 @@ protected:
ArrayRef<Expr *> Args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
@@ -1114,6 +1122,7 @@ public:
ArrayRef<Expr *> Args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
@@ -1137,6 +1146,13 @@ public:
bool isListInitialization() const { return ListInitialization; }
void setListInitialization(bool V) { ListInitialization = V; }
+ /// \brief Whether this constructor call was written as list-initialization,
+ /// but was interpreted as forming a std::initializer_list<T> from the list
+ /// and passing that as a single constructor argument.
+ /// See C++11 [over.match.list]p1 bullet 1.
+ bool isStdInitListInitialization() const { return StdInitListInitialization; }
+ void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
+
/// \brief Whether this construction first requires
/// zero-initialization before the initializer is called.
bool requiresZeroInitialization() const { return ZeroInitialization; }
@@ -1155,6 +1171,13 @@ public:
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
+ typedef llvm::iterator_range<arg_iterator> arg_range;
+ typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+
+ arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
+ arg_const_range arguments() const {
+ return arg_const_range(arg_begin(), arg_end());
+ }
arg_iterator arg_begin() { return Args; }
arg_iterator arg_end() { return Args + NumArgs; }
@@ -1272,6 +1295,7 @@ public:
SourceRange ParenOrBraceRange,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization);
explicit CXXTemporaryObjectExpr(EmptyShell Empty)
: CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
@@ -1468,6 +1492,12 @@ public:
/// arguments.
typedef Expr **capture_init_iterator;
+ /// \brief Retrieve the initialization expressions for this lambda's captures.
+ llvm::iterator_range<capture_init_iterator> capture_inits() const {
+ return llvm::iterator_range<capture_init_iterator>(capture_init_begin(),
+ capture_init_end());
+ }
+
/// \brief Retrieve the first initialization argument for this
/// lambda expression (which initializes the first capture field).
capture_init_iterator capture_init_begin() const {
@@ -1552,12 +1582,12 @@ class CXXScalarValueInitExpr : public Expr {
public:
/// \brief Create an explicitly-written scalar-value initialization
/// expression.
- CXXScalarValueInitExpr(QualType Type,
- TypeSourceInfo *TypeInfo,
- SourceLocation rParenLoc ) :
- Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
- false, false, Type->isInstantiationDependentType(), false),
- RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
+ CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
+ SourceLocation rParenLoc)
+ : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
+ false, false, Type->isInstantiationDependentType(),
+ Type->containsUnexpandedParameterPack()),
+ RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
explicit CXXScalarValueInitExpr(EmptyShell Shell)
: Expr(CXXScalarValueInitExprClass, Shell) { }
@@ -2096,7 +2126,7 @@ public:
/// \brief Retrieve the argument types.
ArrayRef<TypeSourceInfo *> getArgs() const {
- return ArrayRef<TypeSourceInfo *>(getTypeSourceInfos(), getNumArgs());
+ return llvm::makeArrayRef(getTypeSourceInfos(), getNumArgs());
}
typedef TypeSourceInfo **arg_iterator;
@@ -2750,7 +2780,7 @@ public:
ArrayRef<CleanupObject> objects);
ArrayRef<CleanupObject> getObjects() const {
- return ArrayRef<CleanupObject>(getObjectsBuffer(), getNumObjects());
+ return llvm::makeArrayRef(getObjectsBuffer(), getNumObjects());
}
unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; }
@@ -3794,6 +3824,69 @@ public:
}
};
+/// \brief Represents a folding of a pack over an operator.
+///
+/// This expression is always dependent and represents a pack expansion of the
+/// forms:
+///
+/// ( expr op ... )
+/// ( ... op expr )
+/// ( expr op ... op expr )
+class CXXFoldExpr : public Expr {
+ SourceLocation LParenLoc;
+ SourceLocation EllipsisLoc;
+ SourceLocation RParenLoc;
+ Stmt *SubExprs[2];
+ BinaryOperatorKind Opcode;
+
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+public:
+ CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS,
+ BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS,
+ SourceLocation RParenLoc)
+ : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary,
+ /*Dependent*/ true, true, true,
+ /*ContainsUnexpandedParameterPack*/ false),
+ LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
+ Opcode(Opcode) {
+ SubExprs[0] = LHS;
+ SubExprs[1] = RHS;
+ }
+ CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
+
+ Expr *getLHS() const { return static_cast<Expr*>(SubExprs[0]); }
+ Expr *getRHS() const { return static_cast<Expr*>(SubExprs[1]); }
+
+ /// Does this produce a right-associated sequence of operators?
+ bool isRightFold() const {
+ return getLHS() && getLHS()->containsUnexpandedParameterPack();
+ }
+ /// Does this produce a left-associated sequence of operators?
+ bool isLeftFold() const { return !isRightFold(); }
+ /// Get the pattern, that is, the operand that contains an unexpanded pack.
+ Expr *getPattern() const { return isLeftFold() ? getRHS() : getLHS(); }
+ /// Get the operand that doesn't contain a pack, for a binary fold.
+ Expr *getInit() const { return isLeftFold() ? getLHS() : getRHS(); }
+
+ SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+ BinaryOperatorKind getOperator() const { return Opcode; }
+
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return LParenLoc;
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return RParenLoc;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXFoldExprClass;
+ }
+
+ // Iterators
+ child_range children() { return child_range(SubExprs, SubExprs + 2); }
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 1e8eff38d3..ff1d180ee8 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -11,8 +11,8 @@
// construction of AST nodes from some external source.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
-#define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
+#ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H
+#define LLVM_CLANG_AST_EXTERNALASTSOURCE_H
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclBase.h"
@@ -650,4 +650,4 @@ typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
} // end namespace clang
-#endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
+#endif
diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h
index 8633c97965..a7468a0fd5 100644
--- a/include/clang/AST/LambdaCapture.h
+++ b/include/clang/AST/LambdaCapture.h
@@ -68,13 +68,23 @@ public:
/// \brief Determine whether this capture handles the C++ \c this
/// pointer.
- bool capturesThis() const { return DeclAndBits.getPointer() == nullptr; }
+ bool capturesThis() const {
+ return (DeclAndBits.getPointer() == nullptr) &&
+ !(DeclAndBits.getInt() & Capture_ByCopy);
+ }
/// \brief Determine whether this capture handles a variable.
bool capturesVariable() const {
return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
}
+ /// \brief Determine whether this captures a variable length array bound
+ /// expression.
+ bool capturesVLAType() const {
+ return (DeclAndBits.getPointer() == nullptr) &&
+ (DeclAndBits.getInt() & Capture_ByCopy);
+ }
+
/// \brief Determine whether this is an init-capture.
bool isInitCapture() const {
return capturesVariable() && getCapturedVar()->isInitCapture();
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index a8d119971b..cbe08a1a76 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -156,6 +156,11 @@ public:
virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
raw_ostream &) = 0;
+ virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
+ raw_ostream &) = 0;
+ virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
+ raw_ostream &) = 0;
+
static bool classof(const MangleContext *C) {
return C->getKind() == MK_Itanium;
}
diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h
index 56c995264b..7a818557fd 100644
--- a/include/clang/AST/MangleNumberingContext.h
+++ b/include/clang/AST/MangleNumberingContext.h
@@ -12,8 +12,8 @@
// literals.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_MANGLENUMBERINGCONTEXT_H
-#define LLVM_CLANG_MANGLENUMBERINGCONTEXT_H
+#ifndef LLVM_CLANG_AST_MANGLENUMBERINGCONTEXT_H
+#define LLVM_CLANG_AST_MANGLENUMBERINGCONTEXT_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
@@ -30,23 +30,20 @@ class VarDecl;
/// \brief Keeps track of the mangled names of lambda expressions and block
/// literals within a particular context.
-class MangleNumberingContext
- : public RefCountedBase<MangleNumberingContext> {
- llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
-
+class MangleNumberingContext : public RefCountedBase<MangleNumberingContext> {
public:
virtual ~MangleNumberingContext() {}
/// \brief Retrieve the mangling number of a new lambda expression with the
/// given call operator within this context.
- unsigned getManglingNumber(const CXXMethodDecl *CallOperator);
+ virtual unsigned getManglingNumber(const CXXMethodDecl *CallOperator) = 0;
/// \brief Retrieve the mangling number of a new block literal within this
/// context.
- unsigned getManglingNumber(const BlockDecl *BD);
+ virtual unsigned getManglingNumber(const BlockDecl *BD) = 0;
/// Static locals are numbered by source order.
- unsigned getStaticLocalNumber(const VarDecl *VD);
+ virtual unsigned getStaticLocalNumber(const VarDecl *VD) = 0;
/// \brief Retrieve the mangling number of a static local variable within
/// this context.
@@ -58,6 +55,6 @@ public:
virtual unsigned getManglingNumber(const TagDecl *TD,
unsigned MSLocalManglingNumber) = 0;
};
-
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h
index 0b21b03348..33fcce2109 100644
--- a/include/clang/AST/NSAPI.h
+++ b/include/clang/AST/NSAPI.h
@@ -42,7 +42,8 @@ public:
NSStr_stringWithUTF8String,
NSStr_stringWithCStringEncoding,
NSStr_stringWithCString,
- NSStr_initWithString
+ NSStr_initWithString,
+ NSStr_initWithUTF8String
};
static const unsigned NumNSStringMethods = 5;
@@ -100,8 +101,8 @@ public:
NSDict_objectForKey,
NSMutableDict_setObjectForKey
};
- static const unsigned NumNSDictionaryMethods = 11;
-
+ static const unsigned NumNSDictionaryMethods = 12;
+
/// \brief The Objective-C NSDictionary selectors.
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
@@ -184,6 +185,9 @@ public:
bool isObjCNSIntegerType(QualType T) const;
/// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
bool isObjCNSUIntegerType(QualType T) const;
+ /// \brief Returns one of NSIntegral typedef names if \param T is a typedef
+ /// of that name in objective-c.
+ StringRef GetNSIntegralKind(QualType T) const;
private:
bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index fc719bdc16..518f1232fe 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -22,6 +22,7 @@
namespace clang {
class ASTContext;
+class CXXRecordDecl;
class NamespaceAliasDecl;
class NamespaceDecl;
class IdentifierInfo;
@@ -45,7 +46,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
/// \brief Enumeration describing
enum StoredSpecifierKind {
StoredIdentifier = 0,
- StoredNamespaceOrAlias = 1,
+ StoredDecl = 1,
StoredTypeSpec = 2,
StoredTypeSpecWithTemplate = 3
};
@@ -83,7 +84,10 @@ public:
/// stored as a Type*.
TypeSpecWithTemplate,
/// \brief The global specifier '::'. There is no stored value.
- Global
+ Global,
+ /// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
+ /// the class it appeared in.
+ Super
};
private:
@@ -143,6 +147,11 @@ public:
/// scope.
static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
+ /// \brief Returns the nested name specifier representing the __super scope
+ /// for the given CXXRecordDecl.
+ static NestedNameSpecifier *SuperSpecifier(const ASTContext &Context,
+ CXXRecordDecl *RD);
+
/// \brief Return the prefix of this nested name specifier.
///
/// The prefix contains all of the parts of the nested name
@@ -172,6 +181,10 @@ public:
/// specifier.
NamespaceAliasDecl *getAsNamespaceAlias() const;
+ /// \brief Retrieve the record declaration stored in this nested name
+ /// specifier.
+ CXXRecordDecl *getAsRecordDecl() const;
+
/// \brief Retrieve the type stored in this nested name specifier.
const Type *getAsType() const {
if (Prefix.getInt() == StoredTypeSpec ||
@@ -421,7 +434,22 @@ public:
/// \brief Turn this (empty) nested-name-specifier into the global
/// nested-name-specifier '::'.
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
-
+
+ /// \brief Turns this (empty) nested-name-specifier into '__super'
+ /// nested-name-specifier.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param RD The declaration of the class in which nested-name-specifier
+ /// appeared.
+ ///
+ /// \param SuperLoc The location of the '__super' keyword.
+ /// name.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
+ SourceLocation SuperLoc, SourceLocation ColonColonLoc);
/// \brief Make a new nested-name-specifier from incomplete source-location
/// information.
///
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index 95cb11ce64..0c3002c103 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -61,7 +61,7 @@ public:
ConstStmtRange children() const {
return const_cast<OMPClause *>(this)->children();
}
- static bool classof(const OMPClause *T) { return true; }
+ static bool classof(const OMPClause *) { return true; }
};
/// \brief This represents clauses with the list of variables like 'private',
@@ -135,10 +135,10 @@ public:
/// \brief Fetches list of all variables in the clause.
ArrayRef<const Expr *> getVarRefs() const {
- return ArrayRef<const Expr *>(
+ return llvm::makeArrayRef(
reinterpret_cast<const Expr *const *>(
reinterpret_cast<const char *>(this) +
- llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
+ llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<const Expr *>())),
NumVars);
}
};
@@ -196,6 +196,59 @@ public:
StmtRange children() { return StmtRange(&Condition, &Condition + 1); }
};
+/// \brief This represents 'final' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp task final(a > 5)
+/// \endcode
+/// In this example directive '#pragma omp task' has simple 'final'
+/// clause with condition 'a > 5'.
+///
+class OMPFinalClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Condition of the 'if' clause.
+ Stmt *Condition;
+
+ /// \brief Set condition.
+ ///
+ void setCondition(Expr *Cond) { Condition = Cond; }
+
+public:
+ /// \brief Build 'final' clause with condition \a Cond.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param Cond Condition of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPFinalClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_final, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Condition(Cond) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPFinalClause()
+ : OMPClause(OMPC_final, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), Condition(nullptr) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Returns condition.
+ Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_final;
+ }
+
+ StmtRange children() { return StmtRange(&Condition, &Condition + 1); }
+};
+
/// \brief This represents 'num_threads' clause in the '#pragma omp ...'
/// directive.
///
@@ -658,6 +711,212 @@ public:
StmtRange children() { return StmtRange(); }
};
+/// \brief This represents 'untied' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp task untied
+/// \endcode
+/// In this example directive '#pragma omp task' has 'untied' clause.
+///
+class OMPUntiedClause : public OMPClause {
+public:
+ /// \brief Build 'untied' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_untied, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPUntiedClause()
+ : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_untied;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'mergeable' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp task mergeable
+/// \endcode
+/// In this example directive '#pragma omp task' has 'mergeable' clause.
+///
+class OMPMergeableClause : public OMPClause {
+public:
+ /// \brief Build 'mergeable' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPMergeableClause()
+ : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_mergeable;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'read' clause in the '#pragma omp atomic' directive.
+///
+/// \code
+/// #pragma omp atomic read
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'read' clause.
+///
+class OMPReadClause : public OMPClause {
+public:
+ /// \brief Build 'read' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_read, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_read;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'write' clause in the '#pragma omp atomic' directive.
+///
+/// \code
+/// #pragma omp atomic write
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'write' clause.
+///
+class OMPWriteClause : public OMPClause {
+public:
+ /// \brief Build 'write' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_write, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPWriteClause()
+ : OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_write;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'update' clause in the '#pragma omp atomic'
+/// directive.
+///
+/// \code
+/// #pragma omp atomic update
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'update' clause.
+///
+class OMPUpdateClause : public OMPClause {
+public:
+ /// \brief Build 'update' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_update, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPUpdateClause()
+ : OMPClause(OMPC_update, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_update;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'capture' clause in the '#pragma omp atomic'
+/// directive.
+///
+/// \code
+/// #pragma omp atomic capture
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'capture' clause.
+///
+class OMPCaptureClause : public OMPClause {
+public:
+ /// \brief Build 'capture' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_capture, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPCaptureClause()
+ : OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_capture;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'seq_cst' clause in the '#pragma omp atomic'
+/// directive.
+///
+/// \code
+/// #pragma omp atomic seq_cst
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'seq_cst' clause.
+///
+class OMPSeqCstClause : public OMPClause {
+public:
+ /// \brief Build 'seq_cst' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_seq_cst, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPSeqCstClause()
+ : OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_seq_cst;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
///
/// \code
@@ -667,6 +926,7 @@ public:
/// with the variables 'a' and 'b'.
///
class OMPPrivateClause : public OMPVarListClause<OMPPrivateClause> {
+ friend class OMPClauseReader;
/// \brief Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
@@ -688,6 +948,20 @@ class OMPPrivateClause : public OMPVarListClause<OMPPrivateClause> {
SourceLocation(), SourceLocation(),
N) {}
+ /// \brief Sets the list of references to private copies with initializers for
+ /// new private variables.
+ /// \param VL List of references.
+ void setPrivateCopies(ArrayRef<Expr *> VL);
+
+ /// \brief Gets the list of references to private copies with initializers for
+ /// new private variables.
+ MutableArrayRef<Expr *> getPrivateCopies() {
+ return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getPrivateCopies() const {
+ return llvm::makeArrayRef(varlist_end(), varlist_size());
+ }
+
public:
/// \brief Creates clause with a list of variables \a VL.
///
@@ -696,10 +970,12 @@ public:
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param VL List of references to the variables.
+ /// \param PrivateVL List of references to private copies with initializers.
///
static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ SourceLocation EndLoc, ArrayRef<Expr *> VL,
+ ArrayRef<Expr *> PrivateVL);
/// \brief Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
@@ -707,6 +983,21 @@ public:
///
static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+ typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
+ typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
+ typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
+ typedef llvm::iterator_range<private_copies_const_iterator>
+ private_copies_const_range;
+
+ private_copies_range private_copies() {
+ return private_copies_range(getPrivateCopies().begin(),
+ getPrivateCopies().end());
+ }
+ private_copies_const_range private_copies() const {
+ return private_copies_const_range(getPrivateCopies().begin(),
+ getPrivateCopies().end());
+ }
+
StmtRange children() {
return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
@@ -727,6 +1018,8 @@ public:
/// with the variables 'a' and 'b'.
///
class OMPFirstprivateClause : public OMPVarListClause<OMPFirstprivateClause> {
+ friend class OMPClauseReader;
+
/// \brief Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
@@ -747,6 +1040,33 @@ class OMPFirstprivateClause : public OMPVarListClause<OMPFirstprivateClause> {
: OMPVarListClause<OMPFirstprivateClause>(
OMPC_firstprivate, SourceLocation(), SourceLocation(),
SourceLocation(), N) {}
+ /// \brief Sets the list of references to private copies with initializers for
+ /// new private variables.
+ /// \param VL List of references.
+ void setPrivateCopies(ArrayRef<Expr *> VL);
+
+ /// \brief Gets the list of references to private copies with initializers for
+ /// new private variables.
+ MutableArrayRef<Expr *> getPrivateCopies() {
+ return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getPrivateCopies() const {
+ return llvm::makeArrayRef(varlist_end(), varlist_size());
+ }
+
+ /// \brief Sets the list of references to initializer variables for new
+ /// private variables.
+ /// \param VL List of references.
+ void setInits(ArrayRef<Expr *> VL);
+
+ /// \brief Gets the list of references to initializer variables for new
+ /// private variables.
+ MutableArrayRef<Expr *> getInits() {
+ return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getInits() const {
+ return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
+ }
public:
/// \brief Creates clause with a list of variables \a VL.
@@ -755,11 +1075,16 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
+ /// \param VL List of references to the original variables.
+ /// \param PrivateVL List of references to private copies with initializers.
+ /// \param InitVL List of references to auto generated variables used for
+ /// initialization of a single array element. Used if firstprivate variable is
+ /// of array type.
///
static OMPFirstprivateClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
+ ArrayRef<Expr *> InitVL);
/// \brief Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
@@ -767,6 +1092,33 @@ public:
///
static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+ typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
+ typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
+ typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
+ typedef llvm::iterator_range<private_copies_const_iterator>
+ private_copies_const_range;
+
+ private_copies_range private_copies() {
+ return private_copies_range(getPrivateCopies().begin(),
+ getPrivateCopies().end());
+ }
+ private_copies_const_range private_copies() const {
+ return private_copies_const_range(getPrivateCopies().begin(),
+ getPrivateCopies().end());
+ }
+
+ typedef MutableArrayRef<Expr *>::iterator inits_iterator;
+ typedef ArrayRef<const Expr *>::iterator inits_const_iterator;
+ typedef llvm::iterator_range<inits_iterator> inits_range;
+ typedef llvm::iterator_range<inits_const_iterator> inits_const_range;
+
+ inits_range inits() {
+ return inits_range(getInits().begin(), getInits().end());
+ }
+ inits_const_range inits() const {
+ return inits_const_range(getInits().begin(), getInits().end());
+ }
+
StmtRange children() {
return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
@@ -1278,6 +1630,71 @@ public:
}
};
+/// \brief This represents implicit clause 'flush' for the '#pragma omp flush'
+/// directive.
+/// This clause does not exist by itself, it can be only as a part of 'omp
+/// flush' directive. This clause is introduced to keep the original structure
+/// of \a OMPExecutableDirective class and its derivatives and to use the
+/// existing infrastructure of clauses with the list of variables.
+///
+/// \code
+/// #pragma omp flush(a,b)
+/// \endcode
+/// In this example directive '#pragma omp flush' has implicit clause 'flush'
+/// with the variables 'a' and 'b'.
+///
+class OMPFlushClause : public OMPVarListClause<OMPFlushClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPFlushClause>(OMPC_flush, StartLoc, LParenLoc,
+ EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPFlushClause(unsigned N)
+ : OMPVarListClause<OMPFlushClause>(OMPC_flush, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ ///
+ static OMPFlushClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc,
+ ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPFlushClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_flush;
+ }
+};
+
} // end namespace clang
#endif
+
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
index aba88d6c54..e3f0126677 100644
--- a/include/clang/AST/OperationKinds.h
+++ b/include/clang/AST/OperationKinds.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_OPERATION_KINDS_H
-#define LLVM_CLANG_AST_OPERATION_KINDS_H
+#ifndef LLVM_CLANG_AST_OPERATIONKINDS_H
+#define LLVM_CLANG_AST_OPERATIONKINDS_H
namespace clang {
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
index eece8510e9..8945c413d2 100644
--- a/include/clang/AST/ParentMap.h
+++ b/include/clang/AST/ParentMap.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_PARENTMAP_H
-#define LLVM_CLANG_PARENTMAP_H
+#ifndef LLVM_CLANG_AST_PARENTMAP_H
+#define LLVM_CLANG_AST_PARENTMAP_H
namespace clang {
class Stmt;
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 349f4c44a4..35ceabbd6b 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_PRETTY_PRINTER_H
-#define LLVM_CLANG_AST_PRETTY_PRINTER_H
+#ifndef LLVM_CLANG_AST_PRETTYPRINTER_H
+#define LLVM_CLANG_AST_PRETTYPRINTER_H
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index 8ba85c43f6..2e005ddbd0 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_RAW_COMMENT_LIST_H
-#define LLVM_CLANG_AST_RAW_COMMENT_LIST_H
+#ifndef LLVM_CLANG_AST_RAWCOMMENTLIST_H
+#define LLVM_CLANG_AST_RAWCOMMENTLIST_H
#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/SourceManager.h"
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 4befb45062..7b7799884a 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_LAYOUTINFO_H
-#define LLVM_CLANG_AST_LAYOUTINFO_H
+#ifndef LLVM_CLANG_AST_RECORDLAYOUT_H
+#define LLVM_CLANG_AST_RECORDLAYOUT_H
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclCXX.h"
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index b4c4fd6ddb..a1d36180d7 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -429,6 +429,7 @@ private:
bool TraverseFunctionHelper(FunctionDecl *D);
bool TraverseVarHelper(VarDecl *D);
bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
+ bool TraverseOMPLoopDirective(OMPLoopDirective *S);
bool TraverseOMPClause(OMPClause *C);
#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
#include "clang/Basic/OpenMPKinds.def"
@@ -689,6 +690,7 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Super:
return true;
case NestedNameSpecifier::TypeSpec:
@@ -713,6 +715,7 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Super:
return true;
case NestedNameSpecifier::TypeSpec:
@@ -940,6 +943,9 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {
for (const auto &E : T->exceptions()) {
TRY_TO(TraverseType(E));
}
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TRY_TO(TraverseStmt(NE));
})
DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
@@ -1148,6 +1154,9 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
for (const auto &E : T->exceptions()) {
TRY_TO(TraverseType(E));
}
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TRY_TO(TraverseStmt(NE));
})
DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
@@ -2144,21 +2153,29 @@ bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
TRY_TO(TraverseLambdaCapture(S, C));
}
- if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
- TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
- if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
- // Visit the whole type.
- TRY_TO(TraverseTypeLoc(TL));
- } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
- if (S->hasExplicitParameters()) {
- // Visit parameters.
- for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
- TRY_TO(TraverseDecl(Proto.getParam(I)));
- }
- } else {
- TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
+ TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+ FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
+
+ if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
+ // Visit the whole type.
+ TRY_TO(TraverseTypeLoc(TL));
+ } else {
+ if (S->hasExplicitParameters()) {
+ // Visit parameters.
+ for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+ TRY_TO(TraverseDecl(Proto.getParam(I)));
}
+ } else if (S->hasExplicitResultType()) {
+ TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
}
+
+ auto *T = Proto.getTypePtr();
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TRY_TO(TraverseStmt(NE));
}
TRY_TO(TraverseLambdaBody(S));
@@ -2259,6 +2276,7 @@ DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
+DEF_TRAVERSE_STMT(TypoExpr, {})
DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
// These operators (all of them) do not need any action except
@@ -2275,6 +2293,7 @@ DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
+DEF_TRAVERSE_STMT(CXXFoldExpr, {})
DEF_TRAVERSE_STMT(AtomicExpr, {})
// These literals (all of them) do not need any action.
@@ -2301,6 +2320,12 @@ bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
return true;
}
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
+ return TraverseOMPExecutableDirective(S);
+}
+
DEF_TRAVERSE_STMT(OMPParallelDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2310,6 +2335,9 @@ DEF_TRAVERSE_STMT(OMPSimdDirective,
DEF_TRAVERSE_STMT(OMPForDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPForSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPSectionsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2319,12 +2347,50 @@ DEF_TRAVERSE_STMT(OMPSectionDirective,
DEF_TRAVERSE_STMT(OMPSingleDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPMasterDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPCriticalDirective, {
+ TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
+ TRY_TO(TraverseOMPExecutableDirective(S));
+})
+
DEF_TRAVERSE_STMT(OMPParallelForDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPTaskDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPBarrierDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPFlushDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPOrderedDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPAtomicDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTeamsDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
// OpenMP clauses.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
@@ -2350,6 +2416,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
+ TRY_TO(TraverseStmt(C->getCondition()));
+ return true;
+}
+
+template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
TRY_TO(TraverseStmt(C->getNumThreads()));
@@ -2397,6 +2469,42 @@ bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPWriteClause(OMPWriteClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
+ return true;
+}
+
+template <typename Derived>
template <typename T>
bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
for (auto *E : Node->varlists()) {
@@ -2408,6 +2516,9 @@ bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
TRY_TO(VisitOMPClauseList(C));
+ for (auto *E : C->private_copies()) {
+ TRY_TO(TraverseStmt(E));
+ }
return true;
}
@@ -2415,6 +2526,12 @@ template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
OMPFirstprivateClause *C) {
TRY_TO(VisitOMPClauseList(C));
+ for (auto *E : C->private_copies()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->inits()) {
+ TRY_TO(TraverseStmt(E));
+ }
return true;
}
@@ -2467,6 +2584,12 @@ RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
+ TRY_TO(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/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 790c8e3e66..380c3b956e 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -393,6 +393,10 @@ public:
/// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
Stmt *IgnoreImplicit();
+ /// \brief Skip no-op (attributed, compound) container stmts and skip captured
+ /// stmt at the top, if \a IgnoreCaptured is true.
+ Stmt *IgnoreContainers(bool IgnoreCaptured = false);
+
const Stmt *stripLabelLikeStatements() const;
Stmt *stripLabelLikeStatements() {
return const_cast<Stmt*>(
@@ -548,14 +552,17 @@ public:
///
class CompoundStmt : public Stmt {
Stmt** Body;
- SourceLocation LBracLoc, RBracLoc;
+ SourceLocation LBraceLoc, RBraceLoc;
+
+ friend class ASTStmtReader;
+
public:
CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
SourceLocation LB, SourceLocation RB);
// \brief Build an empty compound statement with a location.
explicit CompoundStmt(SourceLocation Loc)
- : Stmt(CompoundStmtClass), Body(nullptr), LBracLoc(Loc), RBracLoc(Loc) {
+ : Stmt(CompoundStmtClass), Body(nullptr), LBraceLoc(Loc), RBraceLoc(Loc) {
CompoundStmtBits.NumStmts = 0;
}
@@ -614,13 +621,11 @@ public:
return const_reverse_body_iterator(body_begin());
}
- SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
+ SourceLocation getLocStart() const LLVM_READONLY { return LBraceLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return RBraceLoc; }
- SourceLocation getLBracLoc() const { return LBracLoc; }
- void setLBracLoc(SourceLocation L) { LBracLoc = L; }
- SourceLocation getRBracLoc() const { return RBracLoc; }
- void setRBracLoc(SourceLocation L) { RBracLoc = L; }
+ SourceLocation getLBracLoc() const { return LBraceLoc; }
+ SourceLocation getRBracLoc() const { return RBraceLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CompoundStmtClass;
@@ -846,7 +851,7 @@ public:
SourceLocation getAttrLoc() const { return AttrLoc; }
ArrayRef<const Attr*> getAttrs() const {
- return ArrayRef<const Attr*>(getAttrArrayPtr(), NumAttrs);
+ return llvm::makeArrayRef(getAttrArrayPtr(), NumAttrs);
}
Stmt *getSubStmt() { return SubStmt; }
const Stmt *getSubStmt() const { return SubStmt; }
@@ -1580,18 +1585,21 @@ public:
Kind MyKind;
std::string Str;
unsigned OperandNo;
+
+ // Source range for operand references.
+ CharSourceRange Range;
public:
AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
- AsmStringPiece(unsigned OpNo, char Modifier)
- : MyKind(Operand), Str(), OperandNo(OpNo) {
- Str += Modifier;
+ AsmStringPiece(unsigned OpNo, const std::string &S, SourceLocation Begin,
+ SourceLocation End)
+ : MyKind(Operand), Str(S), OperandNo(OpNo),
+ Range(CharSourceRange::getCharRange(Begin, End)) {
}
bool isString() const { return MyKind == String; }
bool isOperand() const { return MyKind == Operand; }
const std::string &getString() const {
- assert(isString());
return Str;
}
@@ -1600,12 +1608,14 @@ public:
return OperandNo;
}
+ CharSourceRange getRange() const {
+ assert(isOperand() && "Range is currently used only for Operands.");
+ return Range;
+ }
+
/// getModifier - Get the modifier for this operand, if present. This
/// returns '\0' if there was no modifier.
- char getModifier() const {
- assert(isOperand());
- return Str[0];
- }
+ char getModifier() const;
};
/// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
@@ -1780,14 +1790,14 @@ public:
//===--- Other ---===//
ArrayRef<StringRef> getAllConstraints() const {
- return ArrayRef<StringRef>(Constraints, NumInputs + NumOutputs);
+ return llvm::makeArrayRef(Constraints, NumInputs + NumOutputs);
}
ArrayRef<StringRef> getClobbers() const {
- return ArrayRef<StringRef>(Clobbers, NumClobbers);
+ return llvm::makeArrayRef(Clobbers, NumClobbers);
}
ArrayRef<Expr*> getAllExprs() const {
- return ArrayRef<Expr*>(reinterpret_cast<Expr**>(Exprs),
- NumInputs + NumOutputs);
+ return llvm::makeArrayRef(reinterpret_cast<Expr**>(Exprs),
+ NumInputs + NumOutputs);
}
StringRef getClobber(unsigned i) const { return getClobbers()[i]; }
@@ -1972,15 +1982,18 @@ public:
/// @endcode
class CapturedStmt : public Stmt {
public:
- /// \brief The different capture forms: by 'this' or by reference, etc.
+ /// \brief The different capture forms: by 'this', by reference, capture for
+ /// variable-length array type etc.
enum VariableCaptureKind {
VCK_This,
- VCK_ByRef
+ VCK_ByRef,
+ VCK_VLAType,
};
- /// \brief Describes the capture of either a variable or 'this'.
+ /// \brief Describes the capture of either a variable, or 'this', or
+ /// variable-length array type.
class Capture {
- llvm::PointerIntPair<VarDecl *, 1, VariableCaptureKind> VarAndKind;
+ llvm::PointerIntPair<VarDecl *, 2, VariableCaptureKind> VarAndKind;
SourceLocation Loc;
public:
@@ -2002,6 +2015,10 @@ public:
case VCK_ByRef:
assert(Var && "capturing by reference must have a variable!");
break;
+ case VCK_VLAType:
+ assert(!Var &&
+ "Variable-length array type capture cannot have a variable!");
+ break;
}
}
@@ -2016,13 +2033,20 @@ public:
bool capturesThis() const { return getCaptureKind() == VCK_This; }
/// \brief Determine whether this capture handles a variable.
- bool capturesVariable() const { return getCaptureKind() != VCK_This; }
+ bool capturesVariable() const { return getCaptureKind() == VCK_ByRef; }
+
+ /// \brief Determine whether this capture handles a variable-length array
+ /// type.
+ bool capturesVariableArrayType() const {
+ return getCaptureKind() == VCK_VLAType;
+ }
/// \brief Retrieve the declaration of the variable being captured.
///
- /// This operation is only valid if this capture does not capture 'this'.
+ /// This operation is only valid if this capture captures a variable.
VarDecl *getCapturedVar() const {
- assert(!capturesThis() && "No variable available for 'this' capture");
+ assert(capturesVariable() &&
+ "No variable available for 'this' or VAT capture");
return VarAndKind.getPointer();
}
friend class ASTStmtReader;
diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h
index a3e9e1e093..ab636a5ddc 100644
--- a/include/clang/AST/StmtGraphTraits.h
+++ b/include/clang/AST/StmtGraphTraits.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
-#define LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
+#ifndef LLVM_CLANG_AST_STMTGRAPHTRAITS_H
+#define LLVM_CLANG_AST_STMTGRAPHTRAITS_H
#include "clang/AST/Stmt.h"
#include "llvm/ADT/DepthFirstIterator.h"
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
index 18c55166be..6ffe74f2d7 100644
--- a/include/clang/AST/StmtIterator.h
+++ b/include/clang/AST/StmtIterator.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_STMT_ITR_H
-#define LLVM_CLANG_AST_STMT_ITR_H
+#ifndef LLVM_CLANG_AST_STMTITERATOR_H
+#define LLVM_CLANG_AST_STMTITERATOR_H
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index f6fe473f7b..6a2832cdad 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -83,7 +83,10 @@ protected:
///
/// /param S Associated statement.
///
- void setAssociatedStmt(Stmt *S) { *child_begin() = S; }
+ void setAssociatedStmt(Stmt *S) {
+ assert(hasAssociatedStmt() && "no associated statement.");
+ *child_begin() = S;
+ }
public:
/// \brief Iterates over a filtered subrange of clauses applied to a
@@ -125,6 +128,13 @@ public:
operator bool() { return Current != End; }
};
+ /// \brief Gets a single clause of the specified kind \a K associated with the
+ /// current directive iff there is only one clause of this kind (and assertion
+ /// is fired if there is more than one clause is associated with the
+ /// directive). Returns nullptr if no clause of kind \a K is associated with
+ /// the directive.
+ const OMPClause *getSingleClause(OpenMPClauseKind K) const;
+
/// \brief Returns starting location of directive kind.
SourceLocation getLocStart() const { return StartLoc; }
/// \brief Returns ending location of directive.
@@ -150,8 +160,14 @@ public:
///
OMPClause *getClause(unsigned i) const { return clauses()[i]; }
+ /// \brief Returns true if directive has associated statement.
+ bool hasAssociatedStmt() const { return NumChildren > 0; }
+
/// \brief Returns statement associated with the directive.
- Stmt *getAssociatedStmt() const { return const_cast<Stmt *>(*child_begin()); }
+ Stmt *getAssociatedStmt() const {
+ assert(hasAssociatedStmt() && "no associated statement.");
+ return const_cast<Stmt *>(*child_begin());
+ }
OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
@@ -161,6 +177,8 @@ public:
}
child_range children() {
+ if (!hasAssociatedStmt())
+ return child_range();
Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
return child_range(ChildStorage, ChildStorage + NumChildren);
}
@@ -227,6 +245,168 @@ public:
}
};
+/// \brief This is a common base class for loop directives ('omp simd', 'omp
+/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
+///
+class OMPLoopDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Number of collapsed loops as specified by 'collapse' clause.
+ unsigned CollapsedNum;
+
+ /// \brief Offsets to the stored exprs.
+ enum {
+ AssociatedStmtOffset = 0,
+ IterationVariableOffset = 1,
+ LastIterationOffset = 2,
+ CalcLastIterationOffset = 3,
+ PreConditionOffset = 4,
+ CondOffset = 5,
+ SeparatedCondOffset = 6,
+ InitOffset = 7,
+ IncOffset = 8,
+ ArraysOffset = 9
+ };
+
+ /// \brief Get the counters storage.
+ MutableArrayRef<Expr *> getCounters() {
+ Expr **Storage =
+ reinterpret_cast<Expr **>(&(*(std::next(child_begin(), ArraysOffset))));
+ return MutableArrayRef<Expr *>(Storage, CollapsedNum);
+ }
+
+ /// \brief Get the updates storage.
+ MutableArrayRef<Expr *> getUpdates() {
+ Expr **Storage = reinterpret_cast<Expr **>(
+ &*std::next(child_begin(), ArraysOffset + CollapsedNum));
+ return MutableArrayRef<Expr *>(Storage, CollapsedNum);
+ }
+
+ /// \brief Get the final counter updates storage.
+ MutableArrayRef<Expr *> getFinals() {
+ Expr **Storage = reinterpret_cast<Expr **>(
+ &*std::next(child_begin(), ArraysOffset + 2 * CollapsedNum));
+ return MutableArrayRef<Expr *>(Storage, CollapsedNum);
+ }
+
+protected:
+ /// \brief Build instance of loop directive of class \a Kind.
+ ///
+ /// \param SC Statement class.
+ /// \param Kind Kind of OpenMP directive.
+ /// \param StartLoc Starting location of the directive (directive keyword).
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
+ /// \param NumClauses Number of clauses.
+ /// \param NumSpecialChildren Number of additional directive-specific stmts.
+ ///
+ template <typename T>
+ OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
+ SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses,
+ unsigned NumSpecialChildren = 0)
+ : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
+ numLoopChildren(CollapsedNum) +
+ NumSpecialChildren),
+ CollapsedNum(CollapsedNum) {}
+
+ /// \brief Children number.
+ static unsigned numLoopChildren(unsigned CollapsedNum) {
+ return ArraysOffset + 3 * CollapsedNum; // Counters, Updates and Finals
+ }
+
+ void setIterationVariable(Expr *IV) {
+ *std::next(child_begin(), IterationVariableOffset) = IV;
+ }
+ void setLastIteration(Expr *LI) {
+ *std::next(child_begin(), LastIterationOffset) = LI;
+ }
+ void setCalcLastIteration(Expr *CLI) {
+ *std::next(child_begin(), CalcLastIterationOffset) = CLI;
+ }
+ void setPreCond(Expr *PC) {
+ *std::next(child_begin(), PreConditionOffset) = PC;
+ }
+ void setCond(Expr *Cond, Expr *SeparatedCond) {
+ *std::next(child_begin(), CondOffset) = Cond;
+ *std::next(child_begin(), SeparatedCondOffset) = SeparatedCond;
+ }
+ void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
+ void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
+ void setCounters(ArrayRef<Expr *> A);
+ void setUpdates(ArrayRef<Expr *> A);
+ void setFinals(ArrayRef<Expr *> A);
+
+public:
+ /// \brief Get number of collapsed loops.
+ unsigned getCollapsedNumber() const { return CollapsedNum; }
+
+ Expr *getIterationVariable() const {
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+ *std::next(child_begin(), IterationVariableOffset)));
+ }
+ Expr *getLastIteration() const {
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+ *std::next(child_begin(), LastIterationOffset)));
+ }
+ Expr *getCalcLastIteration() const {
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+ *std::next(child_begin(), CalcLastIterationOffset)));
+ }
+ Expr *getPreCond() const {
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+ *std::next(child_begin(), PreConditionOffset)));
+ }
+ Expr *getCond(bool SeparateIter) const {
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
+ *std::next(child_begin(),
+ (SeparateIter ? SeparatedCondOffset : CondOffset))));
+ }
+ Expr *getInit() const {
+ return const_cast<Expr *>(
+ reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
+ }
+ Expr *getInc() const {
+ return const_cast<Expr *>(
+ reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
+ }
+ const Stmt *getBody() const {
+ // This relies on the loop form is already checked by Sema.
+ Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
+ Body = cast<ForStmt>(Body)->getBody();
+ for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
+ Body = Body->IgnoreContainers();
+ Body = cast<ForStmt>(Body)->getBody();
+ }
+ return Body;
+ }
+
+ ArrayRef<Expr *> counters() { return getCounters(); }
+
+ ArrayRef<Expr *> counters() const {
+ return const_cast<OMPLoopDirective *>(this)->getCounters();
+ }
+
+ ArrayRef<Expr *> updates() { return getUpdates(); }
+
+ ArrayRef<Expr *> updates() const {
+ return const_cast<OMPLoopDirective *>(this)->getUpdates();
+ }
+
+ ArrayRef<Expr *> finals() { return getFinals(); }
+
+ ArrayRef<Expr *> finals() const {
+ return const_cast<OMPLoopDirective *>(this)->getFinals();
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPSimdDirectiveClass ||
+ T->getStmtClass() == OMPForDirectiveClass ||
+ T->getStmtClass() == OMPForSimdDirectiveClass ||
+ T->getStmtClass() == OMPParallelForDirectiveClass ||
+ T->getStmtClass() == OMPParallelForSimdDirectiveClass;
+ }
+};
+
/// \brief This represents '#pragma omp simd' directive.
///
/// \code
@@ -236,10 +416,8 @@ public:
/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
///
-class OMPSimdDirective : public OMPExecutableDirective {
+class OMPSimdDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief Number of collapsed loops as specified by 'collapse' clause.
- unsigned CollapsedNum;
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
@@ -249,9 +427,8 @@ class OMPSimdDirective : public OMPExecutableDirective {
///
OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
- EndLoc, NumClauses, 1),
- CollapsedNum(CollapsedNum) {}
+ : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
+ EndLoc, CollapsedNum, NumClauses) {}
/// \brief Build an empty directive.
///
@@ -259,10 +436,9 @@ class OMPSimdDirective : public OMPExecutableDirective {
/// \param NumClauses Number of clauses.
///
explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd,
- SourceLocation(), SourceLocation(), NumClauses,
- 1),
- CollapsedNum(CollapsedNum) {}
+ : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
+ SourceLocation(), SourceLocation(), CollapsedNum,
+ NumClauses) {}
public:
/// \brief Creates directive with a list of \a Clauses.
@@ -273,11 +449,24 @@ public:
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned CollapsedNum,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt);
+ /// \param IV Loop iteration variable for CodeGen.
+ /// \param LastIteration Loop last iteration number for CodeGen.
+ /// \param CalcLastIteration Calculation of last iteration.
+ /// \param PreCond Pre-condition.
+ /// \param Cond Condition.
+ /// \param SeparatedCond Condition with 1 iteration separated.
+ /// \param Inc Loop increment.
+ /// \param Counters Loop counters.
+ /// \param Updates Expressions for loop counters update for CodeGen.
+ /// \param Finals Final loop counter values for GodeGen.
+ ///
+ static OMPSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
+ Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
+ Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
+ ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
/// \brief Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -289,8 +478,6 @@ public:
static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
unsigned CollapsedNum, EmptyShell);
- unsigned getCollapsedNumber() const { return CollapsedNum; }
-
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPSimdDirectiveClass;
}
@@ -305,10 +492,8 @@ public:
/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
/// and 'd'.
///
-class OMPForDirective : public OMPExecutableDirective {
+class OMPForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief Number of collapsed loops as specified by 'collapse' clause.
- unsigned CollapsedNum;
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
@@ -318,9 +503,8 @@ class OMPForDirective : public OMPExecutableDirective {
///
OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc,
- EndLoc, NumClauses, 1),
- CollapsedNum(CollapsedNum) {}
+ : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
+ CollapsedNum, NumClauses) {}
/// \brief Build an empty directive.
///
@@ -328,10 +512,8 @@ class OMPForDirective : public OMPExecutableDirective {
/// \param NumClauses Number of clauses.
///
explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for,
- SourceLocation(), SourceLocation(), NumClauses,
- 1),
- CollapsedNum(CollapsedNum) {}
+ : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
+ SourceLocation(), CollapsedNum, NumClauses) {}
public:
/// \brief Creates directive with a list of \a Clauses.
@@ -342,11 +524,24 @@ public:
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned CollapsedNum,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt);
+ /// \param IV Loop iteration variable for CodeGen.
+ /// \param LastIteration Loop last iteration number for CodeGen.
+ /// \param CalcLastIteration Calculation of last iteration.
+ /// \param PreCond Pre-condition.
+ /// \param Cond Condition.
+ /// \param SeparatedCond Condition with 1 iteration separated.
+ /// \param Inc Loop increment.
+ /// \param Counters Loop counters.
+ /// \param Updates Expressions for loop counters update for CodeGen.
+ /// \param Finals Final loop counter values for GodeGen.
+ ///
+ static OMPForDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
+ Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
+ Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
+ ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
/// \brief Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -358,13 +553,88 @@ public:
static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
unsigned CollapsedNum, EmptyShell);
- unsigned getCollapsedNumber() const { return CollapsedNum; }
-
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPForDirectiveClass;
}
};
+/// \brief This represents '#pragma omp for simd' directive.
+///
+/// \code
+/// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp for simd' has clauses 'private'
+/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
+/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
+///
+class OMPForSimdDirective : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
+ StartLoc, EndLoc, CollapsedNum, NumClauses) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
+ SourceLocation(), SourceLocation(), CollapsedNum,
+ NumClauses) {}
+
+public:
+ /// \brief Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param IV Loop iteration variable for CodeGen.
+ /// \param LastIteration Loop last iteration number for CodeGen.
+ /// \param CalcLastIteration Calculation of last iteration.
+ /// \param PreCond Pre-condition.
+ /// \param Cond Condition.
+ /// \param SeparatedCond Condition with 1 iteration separated.
+ /// \param Inc Loop increment.
+ /// \param Counters Loop counters.
+ /// \param Updates Expressions for loop counters update for CodeGen.
+ /// \param Finals Final loop counter values for GodeGen.
+ ///
+ static OMPForSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
+ Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
+ Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
+ ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
+
+ /// \brief Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPForSimdDirectiveClass;
+ }
+};
+
/// \brief This represents '#pragma omp sections' directive.
///
/// \code
@@ -527,6 +797,116 @@ public:
}
};
+/// \brief This represents '#pragma omp master' directive.
+///
+/// \code
+/// #pragma omp master
+/// \endcode
+///
+class OMPMasterDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
+ StartLoc, EndLoc, 0, 1) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPMasterDirective()
+ : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
+ SourceLocation(), SourceLocation(), 0, 1) {}
+
+public:
+ /// \brief Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPMasterDirective *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPMasterDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp critical' directive.
+///
+/// \code
+/// #pragma omp critical
+/// \endcode
+///
+class OMPCriticalDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Name of the directive.
+ DeclarationNameInfo DirName;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param Name Name of the directive.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
+ SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
+ StartLoc, EndLoc, 0, 1),
+ DirName(Name) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPCriticalDirective()
+ : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
+ SourceLocation(), SourceLocation(), 0, 1),
+ DirName() {}
+
+ /// \brief Set name of the directive.
+ ///
+ /// \param Name Name of the directive.
+ ///
+ void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
+
+public:
+ /// \brief Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param Name Name of the directive.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPCriticalDirective *
+ Create(const ASTContext &C, const DeclarationNameInfo &Name,
+ SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ /// \brief Return name of the directive.
+ ///
+ DeclarationNameInfo getDirectiveName() const { return DirName; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPCriticalDirectiveClass;
+ }
+};
+
/// \brief This represents '#pragma omp parallel for' directive.
///
/// \code
@@ -536,10 +916,8 @@ public:
/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
/// variables 'c' and 'd'.
///
-class OMPParallelForDirective : public OMPExecutableDirective {
+class OMPParallelForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief Number of collapsed loops as specified by 'collapse' clause.
- unsigned CollapsedNum;
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
@@ -549,10 +927,8 @@ class OMPParallelForDirective : public OMPExecutableDirective {
///
OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
- OMPD_parallel_for, StartLoc, EndLoc, NumClauses,
- 1),
- CollapsedNum(CollapsedNum) {}
+ : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
+ StartLoc, EndLoc, CollapsedNum, NumClauses) {}
/// \brief Build an empty directive.
///
@@ -560,10 +936,9 @@ class OMPParallelForDirective : public OMPExecutableDirective {
/// \param NumClauses Number of clauses.
///
explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
- OMPD_parallel_for, SourceLocation(),
- SourceLocation(), NumClauses, 1),
- CollapsedNum(CollapsedNum) {}
+ : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
+ SourceLocation(), SourceLocation(), CollapsedNum,
+ NumClauses) {}
public:
/// \brief Creates directive with a list of \a Clauses.
@@ -574,11 +949,24 @@ public:
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
+ /// \param IV Loop iteration variable for CodeGen.
+ /// \param LastIteration Loop last iteration number for CodeGen.
+ /// \param CalcLastIteration Calculation of last iteration.
+ /// \param PreCond Pre-condition.
+ /// \param Cond Condition.
+ /// \param SeparatedCond Condition with 1 iteration separated.
+ /// \param Inc Loop increment.
+ /// \param Counters Loop counters.
+ /// \param Updates Expressions for loop counters update for CodeGen.
+ /// \param Finals Final loop counter values for GodeGen.
///
static OMPParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt);
+ Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
+ Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
+ Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
+ ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
/// \brief Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -592,13 +980,92 @@ public:
unsigned CollapsedNum,
EmptyShell);
- unsigned getCollapsedNumber() const { return CollapsedNum; }
-
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPParallelForDirectiveClass;
}
};
+/// \brief This represents '#pragma omp parallel for simd' directive.
+///
+/// \code
+/// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp parallel for simd' has clauses
+/// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
+/// and linear step 's', 'reduction' with operator '+' and variables 'c' and
+/// 'd'.
+///
+class OMPParallelForSimdDirective : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
+ OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
+ NumClauses) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
+ OMPD_parallel_for_simd, SourceLocation(),
+ SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+ /// \brief Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param IV Loop iteration variable for CodeGen.
+ /// \param LastIteration Loop last iteration number for CodeGen.
+ /// \param CalcLastIteration Calculation of last iteration.
+ /// \param PreCond Pre-condition.
+ /// \param Cond Condition.
+ /// \param SeparatedCond Condition with 1 iteration separated.
+ /// \param Inc Loop increment.
+ /// \param Counters Loop counters.
+ /// \param Updates Expressions for loop counters update for CodeGen.
+ /// \param Finals Final loop counter values for GodeGen.
+ ///
+ static OMPParallelForSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
+ Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
+ Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
+ ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
+
+ /// \brief Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
+ }
+};
+
/// \brief This represents '#pragma omp parallel sections' directive.
///
/// \code
@@ -658,6 +1125,502 @@ public:
}
};
+/// \brief This represents '#pragma omp task' directive.
+///
+/// \code
+/// #pragma omp task private(a,b) final(d)
+/// \endcode
+/// In this example directive '#pragma omp task' has clauses 'private' with the
+/// variables 'a' and 'b' and 'final' with condition 'd'.
+///
+class OMPTaskDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
+ EndLoc, NumClauses, 1) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTaskDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 1) {}
+
+public:
+ /// \brief Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTaskDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp taskyield' directive.
+///
+/// \code
+/// #pragma omp taskyield
+/// \endcode
+///
+class OMPTaskyieldDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
+ StartLoc, EndLoc, 0, 0) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPTaskyieldDirective()
+ : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
+ SourceLocation(), SourceLocation(), 0, 0) {}
+
+public:
+ /// \brief Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ ///
+ static OMPTaskyieldDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTaskyieldDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp barrier' directive.
+///
+/// \code
+/// #pragma omp barrier
+/// \endcode
+///
+class OMPBarrierDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
+ StartLoc, EndLoc, 0, 0) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPBarrierDirective()
+ : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
+ SourceLocation(), SourceLocation(), 0, 0) {}
+
+public:
+ /// \brief Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ ///
+ static OMPBarrierDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPBarrierDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp taskwait' directive.
+///
+/// \code
+/// #pragma omp taskwait
+/// \endcode
+///
+class OMPTaskwaitDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
+ StartLoc, EndLoc, 0, 0) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPTaskwaitDirective()
+ : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
+ SourceLocation(), SourceLocation(), 0, 0) {}
+
+public:
+ /// \brief Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ ///
+ static OMPTaskwaitDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTaskwaitDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp flush' directive.
+///
+/// \code
+/// #pragma omp flush(a,b)
+/// \endcode
+/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
+/// and 'b'.
+/// 'omp flush' directive does not have clauses but have an optional list of
+/// variables to flush. This list of variables is stored within some fake clause
+/// FlushClause.
+class OMPFlushDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
+ StartLoc, EndLoc, NumClauses, 0) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPFlushDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 0) {}
+
+public:
+ /// \brief Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses (only single OMPFlushClause clause is
+ /// allowed).
+ ///
+ static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses);
+
+ /// \brief Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPFlushDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPFlushDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp ordered' directive.
+///
+/// \code
+/// #pragma omp ordered
+/// \endcode
+///
+class OMPOrderedDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
+ StartLoc, EndLoc, 0, 1) {}
+
+ /// \brief Build an empty directive.
+ ///
+ explicit OMPOrderedDirective()
+ : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
+ SourceLocation(), SourceLocation(), 0, 1) {}
+
+public:
+ /// \brief Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPOrderedDirective *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPOrderedDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPOrderedDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp atomic' directive.
+///
+/// \code
+/// #pragma omp atomic capture
+/// \endcode
+/// In this example directive '#pragma omp atomic' has clause 'capture'.
+///
+class OMPAtomicDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
+ StartLoc, EndLoc, NumClauses, 4) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPAtomicDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 4) {}
+
+ /// \brief Set 'x' part of the associated expression/statement.
+ void setX(Expr *X) { *std::next(child_begin()) = X; }
+ /// \brief Set 'v' part of the associated expression/statement.
+ void setV(Expr *V) { *std::next(child_begin(), 2) = V; }
+ /// \brief Set 'expr' part of the associated expression/statement.
+ void setExpr(Expr *E) { *std::next(child_begin(), 3) = E; }
+
+public:
+ /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
+ /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
+ /// detailed description of 'x', 'v' and 'expr').
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param X 'x' part of the associated expression/statement.
+ /// \param V 'v' part of the associated expression/statement.
+ /// \param E 'expr' part of the associated expression/statement.
+ ///
+ static OMPAtomicDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
+ Expr *E);
+
+ /// \brief Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ /// \brief Get 'x' part of the associated expression/statement.
+ Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
+ const Expr *getX() const {
+ return cast_or_null<Expr>(*std::next(child_begin()));
+ }
+ /// \brief Get 'v' part of the associated expression/statement.
+ Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 2)); }
+ const Expr *getV() const {
+ return cast_or_null<Expr>(*std::next(child_begin(), 2));
+ }
+ /// \brief Get 'expr' part of the associated expression/statement.
+ Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
+ const Expr *getExpr() const {
+ return cast_or_null<Expr>(*std::next(child_begin(), 3));
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPAtomicDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp target' directive.
+///
+/// \code
+/// #pragma omp target if(a)
+/// \endcode
+/// In this example directive '#pragma omp target' has clause 'if' with
+/// condition 'a'.
+///
+class OMPTargetDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
+ StartLoc, EndLoc, NumClauses, 1) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTargetDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 1) {}
+
+public:
+ /// \brief Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPTargetDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTargetDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTargetDirectiveClass;
+ }
+};
+
+/// \brief This represents '#pragma omp teams' directive.
+///
+/// \code
+/// #pragma omp teams if(a)
+/// \endcode
+/// In this example directive '#pragma omp teams' has clause 'if' with
+/// condition 'a'.
+///
+class OMPTeamsDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
+ StartLoc, EndLoc, NumClauses, 1) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTeamsDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 1) {}
+
+public:
+ /// \brief Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTeamsDirectiveClass;
+ }
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 9e4a577c4c..f3c6440f40 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -18,6 +18,7 @@
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
@@ -75,7 +76,7 @@ private:
struct DA {
unsigned Kind;
- bool ForRefParam;
+ void *QT;
ValueDecl *D;
};
struct I {
@@ -131,11 +132,11 @@ public:
/// \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) {
+ TemplateArgument(ValueDecl *D, QualType QT) {
assert(D && "Expected decl");
DeclArg.Kind = Declaration;
+ DeclArg.QT = QT.getAsOpaquePtr();
DeclArg.D = D;
- DeclArg.ForRefParam = ForRefParam;
}
/// \brief Construct an integral constant template argument. The memory to
@@ -248,11 +249,9 @@ public:
return DeclArg.D;
}
- /// \brief Retrieve whether a declaration is binding to a
- /// reference parameter in a declaration non-type template argument.
- bool isDeclForReferenceParam() const {
+ QualType getParamTypeForDecl() const {
assert(getKind() == Declaration && "Unexpected kind");
- return DeclArg.ForRefParam;
+ return QualType::getFromOpaquePtr(DeclArg.QT);
}
/// \brief Retrieve the type for null non-type template argument.
@@ -327,6 +326,12 @@ public:
return Args.Args + Args.NumArgs;
}
+ /// \brief Iterator range referencing all of the elements of a template
+ /// argument pack.
+ llvm::iterator_range<pack_iterator> pack_elements() const {
+ return llvm::make_range(pack_begin(), pack_end());
+ }
+
/// \brief The number of template arguments in the given template argument
/// pack.
unsigned pack_size() const {
@@ -337,7 +342,7 @@ public:
/// \brief Return the array of arguments in this template argument pack.
ArrayRef<TemplateArgument> getPackAsArray() const {
assert(getKind() == Pack);
- return ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
+ return llvm::makeArrayRef(Args.Args, Args.NumArgs);
}
/// \brief Determines whether two template arguments are superficially the
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index a20e43413c..4f194b022d 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1245,6 +1245,7 @@ protected:
class FunctionTypeBitfields {
friend class FunctionType;
+ friend class FunctionProtoType;
unsigned : NumTypeBits;
@@ -1259,6 +1260,11 @@ protected:
/// C++ 8.3.5p4: The return type, the parameter type list and the
/// cv-qualifier-seq, [...], are part of the function type.
unsigned TypeQuals : 3;
+
+ /// \brief The ref-qualifier associated with a \c FunctionProtoType.
+ ///
+ /// This is a value of type \c RefQualifierKind.
+ unsigned RefQualifier : 2;
};
class ObjCObjectTypeBitfields {
@@ -2765,7 +2771,7 @@ class FunctionType : public Type {
protected:
FunctionType(TypeClass tc, QualType res,
- unsigned typeQuals, QualType Canonical, bool Dependent,
+ QualType Canonical, bool Dependent,
bool InstantiationDependent,
bool VariablyModified, bool ContainsUnexpandedParameterPack,
ExtInfo Info)
@@ -2773,7 +2779,6 @@ protected:
ContainsUnexpandedParameterPack),
ResultType(res) {
FunctionTypeBits.ExtInfo = Info.Bits;
- FunctionTypeBits.TypeQuals = typeQuals;
}
unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
@@ -2810,7 +2815,7 @@ public:
/// no information available about its arguments.
class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
- : FunctionType(FunctionNoProto, Result, 0, Canonical,
+ : FunctionType(FunctionNoProto, Result, Canonical,
/*Dependent=*/false, /*InstantiationDependent=*/false,
Result->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false, Info) {}
@@ -2844,33 +2849,51 @@ public:
/// type.
class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
public:
+ struct ExceptionSpecInfo {
+ ExceptionSpecInfo()
+ : Type(EST_None), NoexceptExpr(nullptr),
+ SourceDecl(nullptr), SourceTemplate(nullptr) {}
+
+ ExceptionSpecInfo(ExceptionSpecificationType EST)
+ : Type(EST), NoexceptExpr(nullptr), SourceDecl(nullptr),
+ SourceTemplate(nullptr) {}
+
+ /// The kind of exception specification this is.
+ ExceptionSpecificationType Type;
+ /// Explicitly-specified list of exception types.
+ ArrayRef<QualType> Exceptions;
+ /// Noexcept expression, if this is EST_ComputedNoexcept.
+ Expr *NoexceptExpr;
+ /// The function whose exception specification this is, for
+ /// EST_Unevaluated and EST_Uninstantiated.
+ FunctionDecl *SourceDecl;
+ /// The function template whose exception specification this is instantiated
+ /// from, for EST_Uninstantiated.
+ FunctionDecl *SourceTemplate;
+ };
+
/// ExtProtoInfo - Extra information about a function prototype.
struct ExtProtoInfo {
ExtProtoInfo()
: Variadic(false), HasTrailingReturn(false), TypeQuals(0),
- ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0),
- Exceptions(nullptr), NoexceptExpr(nullptr),
- ExceptionSpecDecl(nullptr), ExceptionSpecTemplate(nullptr),
- ConsumedParameters(nullptr) {}
+ RefQualifier(RQ_None), ConsumedParameters(nullptr) {}
ExtProtoInfo(CallingConv CC)
: ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0),
- ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0),
- Exceptions(nullptr), NoexceptExpr(nullptr),
- ExceptionSpecDecl(nullptr), ExceptionSpecTemplate(nullptr),
- ConsumedParameters(nullptr) {}
+ RefQualifier(RQ_None), ConsumedParameters(nullptr) {}
+
+ ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &O) {
+ ExtProtoInfo Result(*this);
+ Result.ExceptionSpec = O;
+ return Result;
+ }
FunctionType::ExtInfo ExtInfo;
bool Variadic : 1;
bool HasTrailingReturn : 1;
unsigned char TypeQuals;
- ExceptionSpecificationType ExceptionSpecType;
RefQualifierKind RefQualifier;
- unsigned NumExceptions;
- const QualType *Exceptions;
- Expr *NoexceptExpr;
- FunctionDecl *ExceptionSpecDecl;
- FunctionDecl *ExceptionSpecTemplate;
+ ExceptionSpecInfo ExceptionSpec;
const bool *ConsumedParameters;
};
@@ -2896,7 +2919,7 @@ private:
unsigned NumExceptions : 9;
/// ExceptionSpecType - The type of exception specification this function has.
- unsigned ExceptionSpecType : 3;
+ unsigned ExceptionSpecType : 4;
/// HasAnyConsumedParams - Whether this function has any consumed parameters.
unsigned HasAnyConsumedParams : 1;
@@ -2907,11 +2930,6 @@ private:
/// HasTrailingReturn - Whether this function has a trailing return type.
unsigned HasTrailingReturn : 1;
- /// \brief The ref-qualifier associated with a \c FunctionProtoType.
- ///
- /// This is a value of type \c RefQualifierKind.
- unsigned RefQualifier : 2;
-
// ParamInfo - There is an variable size array after the class in memory that
// holds the parameter types.
@@ -2952,7 +2970,7 @@ public:
return param_type_begin()[i];
}
ArrayRef<QualType> getParamTypes() const {
- return ArrayRef<QualType>(param_type_begin(), param_type_end());
+ return llvm::makeArrayRef(param_type_begin(), param_type_end());
}
ExtProtoInfo getExtProtoInfo() const {
@@ -2960,19 +2978,18 @@ public:
EPI.ExtInfo = getExtInfo();
EPI.Variadic = isVariadic();
EPI.HasTrailingReturn = hasTrailingReturn();
- EPI.ExceptionSpecType = getExceptionSpecType();
+ EPI.ExceptionSpec.Type = getExceptionSpecType();
EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals());
EPI.RefQualifier = getRefQualifier();
- if (EPI.ExceptionSpecType == EST_Dynamic) {
- EPI.NumExceptions = NumExceptions;
- EPI.Exceptions = exception_begin();
- } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) {
- EPI.NoexceptExpr = getNoexceptExpr();
- } else if (EPI.ExceptionSpecType == EST_Uninstantiated) {
- EPI.ExceptionSpecDecl = getExceptionSpecDecl();
- EPI.ExceptionSpecTemplate = getExceptionSpecTemplate();
- } else if (EPI.ExceptionSpecType == EST_Unevaluated) {
- EPI.ExceptionSpecDecl = getExceptionSpecDecl();
+ if (EPI.ExceptionSpec.Type == EST_Dynamic) {
+ EPI.ExceptionSpec.Exceptions = exceptions();
+ } else if (EPI.ExceptionSpec.Type == EST_ComputedNoexcept) {
+ EPI.ExceptionSpec.NoexceptExpr = getNoexceptExpr();
+ } else if (EPI.ExceptionSpec.Type == EST_Uninstantiated) {
+ EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl();
+ EPI.ExceptionSpec.SourceTemplate = getExceptionSpecTemplate();
+ } else if (EPI.ExceptionSpec.Type == EST_Unevaluated) {
+ EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl();
}
if (hasAnyConsumedParams())
EPI.ConsumedParameters = getConsumedParamsBuffer();
@@ -2995,6 +3012,8 @@ public:
bool hasNoexceptExceptionSpec() const {
return isNoexceptExceptionSpec(getExceptionSpecType());
}
+ /// \brief Return whether this function has a dependent exception spec.
+ bool hasDependentExceptionSpec() const;
/// \brief Result type of getNoexceptSpec().
enum NoexceptResult {
NR_NoNoexcept, ///< There is no noexcept specifier.
@@ -3057,7 +3076,7 @@ public:
/// \brief Retrieve the ref-qualifier associated with this function type.
RefQualifierKind getRefQualifier() const {
- return static_cast<RefQualifierKind>(RefQualifier);
+ return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier);
}
typedef const QualType *param_type_iterator;
@@ -3074,10 +3093,9 @@ public:
}
typedef const QualType *exception_iterator;
- typedef llvm::iterator_range<exception_iterator> exception_range;
- exception_range exceptions() const {
- return exception_range(exception_begin(), exception_end());
+ ArrayRef<QualType> exceptions() const {
+ return llvm::makeArrayRef(exception_begin(), exception_end());
}
exception_iterator exception_begin() const {
// exceptions begin where arguments end
@@ -3416,6 +3434,7 @@ public:
attr_stdcall,
attr_thiscall,
attr_pascal,
+ attr_vectorcall,
attr_pnaclcall,
attr_inteloclbicc,
attr_ms_abi,
@@ -5231,8 +5250,8 @@ template <typename T> const T *Type::castAs() const {
ArrayType_cannot_be_used_with_getAs<T> at;
(void) at;
- assert(isa<T>(CanonicalType));
if (const T *ty = dyn_cast<T>(this)) return ty;
+ assert(isa<T>(CanonicalType));
return cast<T>(getUnqualifiedDesugaredType());
}
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 3648d2a5c2..4f3c811ce2 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -1208,7 +1208,7 @@ public:
}
ArrayRef<ParmVarDecl *> getParams() const {
- return ArrayRef<ParmVarDecl *>(getParmArray(), getNumParams());
+ return llvm::makeArrayRef(getParmArray(), getNumParams());
}
// ParmVarDecls* are stored after Info, one for each parameter.
@@ -1567,6 +1567,8 @@ public:
void setUnderlyingTInfo(TypeSourceInfo* TI) const {
this->getLocalData()->UnderlyingTInfo = TI;
}
+
+ void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
// FIXME: location of the 'decltype' and parens.
diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h
index 9c9f15e953..392e544d90 100644
--- a/include/clang/AST/TypeOrdering.h
+++ b/include/clang/AST/TypeOrdering.h
@@ -16,8 +16,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TYPE_ORDERING_H
-#define LLVM_CLANG_TYPE_ORDERING_H
+#ifndef LLVM_CLANG_AST_TYPEORDERING_H
+#define LLVM_CLANG_AST_TYPEORDERING_H
#include "clang/AST/CanonicalType.h"
#include "clang/AST/Type.h"
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index 2ef5800c30..a11f22d201 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -98,7 +98,7 @@ class UnresolvedSetImpl {
private:
template <unsigned N> friend class UnresolvedSet;
UnresolvedSetImpl() {}
- UnresolvedSetImpl(const UnresolvedSetImpl &) LLVM_DELETED_FUNCTION;
+ UnresolvedSetImpl(const UnresolvedSetImpl &) {}
public:
// We don't currently support assignment through this iterator, so we might
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
index 8af0546db5..e5fc44c050 100644
--- a/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -38,10 +38,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCH_FINDER_H
-#define LLVM_CLANG_AST_MATCHERS_AST_MATCH_FINDER_H
+#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHFINDER_H
+#define LLVM_CLANG_ASTMATCHERS_ASTMATCHFINDER_H
#include "clang/ASTMatchers/ASTMatchers.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Timer.h"
namespace clang {
@@ -102,6 +104,12 @@ public:
///
/// Optionally override to do per translation unit tasks.
virtual void onEndOfTranslationUnit() {}
+
+ /// \brief An id used to group the matchers.
+ ///
+ /// This id is used, for example, for the profiling output.
+ /// It defaults to "<unknown>".
+ virtual StringRef getID() const;
};
/// \brief Called when parsing is finished. Intended for testing only.
@@ -111,7 +119,22 @@ public:
virtual void run() = 0;
};
- MatchFinder();
+ struct MatchFinderOptions {
+ struct Profiling {
+ Profiling(llvm::StringMap<llvm::TimeRecord> &Records)
+ : Records(Records) {}
+
+ /// \brief Per bucket timing information.
+ llvm::StringMap<llvm::TimeRecord> &Records;
+ };
+
+ /// \brief Enables per-check timers.
+ ///
+ /// It prints a report after match.
+ llvm::Optional<Profiling> CheckProfiling;
+ };
+
+ MatchFinder(MatchFinderOptions Options = MatchFinderOptions());
~MatchFinder();
/// \brief Adds a matcher to execute when running over the AST.
@@ -148,7 +171,7 @@ public:
MatchCallback *Action);
/// \brief Creates a clang ASTConsumer that finds all matches.
- clang::ASTConsumer *newASTConsumer();
+ std::unique_ptr<clang::ASTConsumer> newASTConsumer();
/// \brief Calls the registered callbacks on all matches on the given \p Node.
///
@@ -173,11 +196,25 @@ public:
/// Each call to FindAll(...) will call the closure once.
void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone);
-private:
- /// \brief For each \c DynTypedMatcher a \c MatchCallback that will be called
+ /// \brief For each \c Matcher<> a \c MatchCallback that will be called
/// when it matches.
- std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> >
- MatcherCallbackPairs;
+ struct MatchersByType {
+ std::vector<std::pair<DeclarationMatcher, MatchCallback *>> Decl;
+ std::vector<std::pair<TypeMatcher, MatchCallback *>> Type;
+ std::vector<std::pair<StatementMatcher, MatchCallback *>> Stmt;
+ std::vector<std::pair<NestedNameSpecifierMatcher, MatchCallback *>>
+ NestedNameSpecifier;
+ std::vector<std::pair<NestedNameSpecifierLocMatcher, MatchCallback *>>
+ NestedNameSpecifierLoc;
+ std::vector<std::pair<TypeLocMatcher, MatchCallback *>> TypeLoc;
+ /// \brief All the callbacks in one container to simplify iteration.
+ std::vector<MatchCallback *> AllCallbacks;
+ };
+
+private:
+ MatchersByType Matchers;
+
+ MatchFinderOptions Options;
/// \brief Called when parsing is done.
ParsingDoneTestCallback *ParsingDone;
@@ -210,16 +247,14 @@ match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
///
/// This is useful in combanation with \c match():
/// \code
-/// Decl *D = selectFirst<Decl>("id", match(Matcher.bind("id"),
-/// Node, Context));
+/// const Decl *D = selectFirst<Decl>("id", match(Matcher.bind("id"),
+/// Node, Context));
/// \endcode
template <typename NodeT>
-NodeT *
+const NodeT *
selectFirst(StringRef BoundTo, const SmallVectorImpl<BoundNodes> &Results) {
- for (SmallVectorImpl<BoundNodes>::const_iterator I = Results.begin(),
- E = Results.end();
- I != E; ++I) {
- if (NodeT *Node = I->getNodeAs<NodeT>(BoundTo))
+ for (const BoundNodes &N : Results) {
+ if (const NodeT *Node = N.getNodeAs<NodeT>(BoundTo))
return Node;
}
return nullptr;
@@ -243,7 +278,7 @@ match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
MatchFinder Finder;
Finder.addMatcher(Matcher, &Callback);
Finder.match(Node, Context);
- return Callback.Nodes;
+ return std::move(Callback.Nodes);
}
template <typename MatcherT, typename NodeT>
@@ -255,4 +290,4 @@ match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) {
} // end namespace ast_matchers
} // end namespace clang
-#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCH_FINDER_H
+#endif
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 406ec93114..37c7b16934 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -42,8 +42,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H
-#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H
+#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
+#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclTemplate.h"
@@ -140,10 +140,7 @@ typedef internal::Matcher<NestedNameSpecifierLoc> NestedNameSpecifierLocMatcher;
/// \endcode
///
/// Usable as: Any Matcher
-inline internal::PolymorphicMatcherWithParam0<internal::TrueMatcher>
-anything() {
- return internal::PolymorphicMatcherWithParam0<internal::TrueMatcher>();
-}
+inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
/// \brief Matches declarations.
///
@@ -156,6 +153,17 @@ anything() {
/// \endcode
const internal::VariadicAllOfMatcher<Decl> decl;
+/// \brief Matches a declaration of a linkage specification.
+///
+/// Given
+/// \code
+/// extern "C" {}
+/// \endcode
+/// linkageSpecDecl()
+/// matches "extern "C" {}"
+const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
+ linkageSpecDecl;
+
/// \brief Matches a declaration of anything that could have a name.
///
/// Example matches \c X, \c S, the anonymous union type, \c i, and \c U;
@@ -263,6 +271,17 @@ const internal::VariadicDynCastAllOfMatcher<
/// \endcode
const internal::VariadicAllOfMatcher<CXXCtorInitializer> ctorInitializer;
+/// \brief Matches template arguments.
+///
+/// Given
+/// \code
+/// template <typename T> struct C {};
+/// C<int> c;
+/// \endcode
+/// templateArgument()
+/// matches 'int' in C<int>.
+const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
+
/// \brief Matches public C++ declarations.
///
/// Given
@@ -441,6 +460,23 @@ AST_POLYMORPHIC_MATCHER_P2(
return InnerMatcher.matches(List[N], Finder, Builder);
}
+/// \brief Matches if the number of template arguments equals \p N.
+///
+/// Given
+/// \code
+/// template<typename T> struct C {};
+/// C<int> c;
+/// \endcode
+/// classTemplateSpecializationDecl(templateArgumentCountIs(1))
+/// matches C<int>.
+AST_POLYMORPHIC_MATCHER_P(
+ templateArgumentCountIs,
+ AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
+ TemplateSpecializationType),
+ unsigned, N) {
+ return internal::getTemplateSpecializationArgs(Node).size() == N;
+}
+
/// \brief Matches a TemplateArgument that refers to a certain type.
///
/// Given
@@ -497,6 +533,68 @@ AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher<Expr>, InnerMatcher) {
return false;
}
+/// \brief Matches a TemplateArgument that is an integral value.
+///
+/// Given
+/// \code
+/// template<int T> struct A {};
+/// C<42> c;
+/// \endcode
+/// classTemplateSpecializationDecl(
+/// hasAnyTemplateArgument(isIntegral()))
+/// matches the implicit instantiation of C in C<42>
+/// with isIntegral() matching 42.
+AST_MATCHER(TemplateArgument, isIntegral) {
+ return Node.getKind() == TemplateArgument::Integral;
+}
+
+/// \brief Matches a TemplateArgument that referes to an integral type.
+///
+/// Given
+/// \code
+/// template<int T> struct A {};
+/// C<42> c;
+/// \endcode
+/// classTemplateSpecializationDecl(
+/// hasAnyTemplateArgument(refersToIntegralType(asString("int"))))
+/// matches the implicit instantiation of C in C<42>.
+AST_MATCHER_P(TemplateArgument, refersToIntegralType,
+ internal::Matcher<QualType>, InnerMatcher) {
+ if (Node.getKind() != TemplateArgument::Integral)
+ return false;
+ return InnerMatcher.matches(Node.getIntegralType(), Finder, Builder);
+}
+
+/// \brief Matches a TemplateArgument of integral type with a given value.
+///
+/// Note that 'Value' is a string as the template argument's value is
+/// an arbitrary precision integer. 'Value' must be euqal to the canonical
+/// representation of that integral value in base 10.
+///
+/// Given
+/// \code
+/// template<int T> struct A {};
+/// C<42> c;
+/// \endcode
+/// classTemplateSpecializationDecl(
+/// hasAnyTemplateArgument(equalsIntegralValue("42")))
+/// matches the implicit instantiation of C in C<42>.
+AST_MATCHER_P(TemplateArgument, equalsIntegralValue,
+ std::string, Value) {
+ if (Node.getKind() != TemplateArgument::Integral)
+ return false;
+ return Node.getAsIntegral().toString(10) == Value;
+}
+
+/// \brief Matches any value declaration.
+///
+/// Example matches A, B, C and F
+/// \code
+/// enum X { A, B, C };
+/// void F();
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
+
/// \brief Matches C++ constructor declarations.
///
/// Example matches Foo::Foo() and Foo::Foo(int)
@@ -714,6 +812,18 @@ substNonTypeTemplateParmExpr;
/// matches \code using X::x \endcode
const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
+/// \brief Matches using namespace declarations.
+///
+/// Given
+/// \code
+/// namespace X { int x; }
+/// using namespace X;
+/// \endcode
+/// usingDirectiveDecl()
+/// matches \code using namespace X \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
+ usingDirectiveDecl;
+
/// \brief Matches unresolved using value declarations.
///
/// Given
@@ -1402,21 +1512,21 @@ const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
///
/// Usable as: Any Matcher
const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> eachOf = {
- internal::EachOfVariadicOperator
+ internal::DynTypedMatcher::VO_EachOf
};
/// \brief Matches if any of the given matchers matches.
///
/// Usable as: Any Matcher
const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> anyOf = {
- internal::AnyOfVariadicOperator
+ internal::DynTypedMatcher::VO_AnyOf
};
/// \brief Matches if all given matchers match.
///
/// Usable as: Any Matcher
const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> allOf = {
- internal::AllOfVariadicOperator
+ internal::DynTypedMatcher::VO_AllOf
};
/// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
@@ -1490,16 +1600,8 @@ inline internal::Matcher<Stmt> sizeOfExpr(
/// \code
/// namespace a { namespace b { class X; } }
/// \endcode
-AST_MATCHER_P(NamedDecl, hasName, std::string, Name) {
- assert(!Name.empty());
- const std::string FullNameString = "::" + Node.getQualifiedNameAsString();
- const StringRef FullName = FullNameString;
- const StringRef Pattern = Name;
- if (Pattern.startswith("::")) {
- return FullName == Pattern;
- } else {
- return FullName.endswith(("::" + Pattern).str());
- }
+inline internal::Matcher<NamedDecl> hasName(const std::string &Name) {
+ return internal::Matcher<NamedDecl>(new internal::HasNameMatcher(Name));
}
/// \brief Matches NamedDecl nodes whose fully qualified names contain
@@ -1542,14 +1644,14 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
/// line and \c recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches
/// the declaration of \c A.
///
-/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<CXXMethodDecl>
+/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
inline internal::PolymorphicMatcherWithParam1<
internal::HasOverloadedOperatorNameMatcher, StringRef,
- AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, CXXMethodDecl)>
-hasOverloadedOperatorName(const StringRef Name) {
+ AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>
+hasOverloadedOperatorName(StringRef Name) {
return internal::PolymorphicMatcherWithParam1<
internal::HasOverloadedOperatorNameMatcher, StringRef,
- AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, CXXMethodDecl)>(
+ AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>(
Name);
}
@@ -1756,7 +1858,7 @@ const internal::ArgumentAdaptingMatcherFunc<
///
/// Usable as: Any Matcher
const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
- internal::NotUnaryOperator
+ internal::DynTypedMatcher::VO_UnaryNot
};
/// \brief Matches a node if the declaration associated with that node
@@ -1832,7 +1934,7 @@ AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
/// Example matches y.x() (matcher = callExpr(callee(methodDecl(hasName("x")))))
/// \code
/// class Y { public: void x(); };
-/// void z() { Y y; y.x();
+/// void z() { Y y; y.x(); }
/// \endcode
AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher,
1) {
@@ -1940,6 +2042,7 @@ AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>,
/// void a(X b) {
/// X &x = b;
/// const X &y = b;
+/// }
/// };
/// \endcode
AST_MATCHER_P(QualType, references, internal::Matcher<QualType>,
@@ -2268,11 +2371,10 @@ AST_MATCHER(CXXCtorInitializer, isWritten) {
AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, AST_POLYMORPHIC_SUPPORTED_TYPES_2(
CallExpr, CXXConstructExpr),
internal::Matcher<Expr>, InnerMatcher) {
- for (unsigned I = 0; I < Node.getNumArgs(); ++I) {
+ for (const Expr *Arg : Node.arguments()) {
BoundNodesTreeBuilder Result(*Builder);
- if (InnerMatcher.matches(*Node.getArg(I)->IgnoreParenImpCasts(), Finder,
- &Result)) {
- *Builder = Result;
+ if (InnerMatcher.matches(*Arg->IgnoreParenImpCasts(), Finder, &Result)) {
+ *Builder = std::move(Result);
return true;
}
}
@@ -2360,6 +2462,19 @@ AST_MATCHER(FunctionDecl, isExternC) {
return Node.isExternC();
}
+/// \brief Matches deleted function declarations.
+///
+/// Given:
+/// \code
+/// void Func();
+/// void DeletedFunc() = delete;
+/// \endcode
+/// functionDecl(isDeleted())
+/// matches the declaration of DeletedFunc, but not Func.
+AST_MATCHER(FunctionDecl, isDeleted) {
+ return Node.isDeleted();
+}
+
/// \brief Matches the condition expression of an if statement, for loop,
/// or conditional operator.
///
@@ -2941,6 +3056,46 @@ AST_POLYMORPHIC_MATCHER(
TSK_ExplicitInstantiationDefinition);
}
+/// \brief Matches declarations that are template instantiations or are inside
+/// template instantiations.
+///
+/// Given
+/// \code
+/// template<typename T> void A(T t) { T i; }
+/// A(0);
+/// A(0U);
+/// \endcode
+/// functionDecl(isInstantiated())
+/// matches 'A(int) {...};' and 'A(unsigned) {...}'.
+AST_MATCHER(Decl, isInstantiated) {
+ auto IsInstantiation = decl(anyOf(recordDecl(isTemplateInstantiation()),
+ functionDecl(isTemplateInstantiation())));
+ auto InnerMatcher =
+ decl(anyOf(IsInstantiation, hasAncestor(IsInstantiation)));
+ return InnerMatcher.matches(Node, Finder, Builder);
+}
+
+/// \brief Matches statements inside of a template instantiation.
+///
+/// Given
+/// \code
+/// int j;
+/// template<typename T> void A(T t) { T i; j += 42;}
+/// A(0);
+/// A(0U);
+/// \endcode
+/// declStmt(isInTemplateInstantiation())
+/// matches 'int i;' and 'unsigned i'.
+/// unless(stmt(isInTemplateInstantiation()))
+/// will NOT match j += 42; as it's shared between the template definition and
+/// instantiation.
+AST_MATCHER(Stmt, isInTemplateInstantiation) {
+ auto InnerMatcher =
+ stmt(hasAncestor(decl(anyOf(recordDecl(isTemplateInstantiation()),
+ functionDecl(isTemplateInstantiation())))));
+ return InnerMatcher.matches(Node, Finder, Builder);
+}
+
/// \brief Matches explicit template specializations of function, class, or
/// static member variable template instantiations.
///
@@ -3082,6 +3237,7 @@ AST_TYPE_MATCHER(IncompleteArrayType, incompleteArrayType);
/// int a[] = { 2, 3 }
/// int b[42];
/// int c[a[0]];
+/// }
/// \endcode
/// variableArrayType()
/// matches "int c[a[0]]"
@@ -3420,8 +3576,9 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
/// \c recordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the
/// declaration of \c class \c D.
AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher) {
- return InnerMatcher.matches(*Decl::castFromDeclContext(Node.getDeclContext()),
- Finder, Builder);
+ const DeclContext *DC = Node.getDeclContext();
+ if (!DC) return false;
+ return InnerMatcher.matches(*Decl::castFromDeclContext(DC), Finder, Builder);
}
/// \brief Matches nested name specifiers.
@@ -3587,7 +3744,7 @@ AST_MATCHER_P(SwitchStmt, forEachSwitchCase, internal::Matcher<SwitchCase>,
Result.addMatch(CaseBuilder);
}
}
- *Builder = Result;
+ *Builder = std::move(Result);
return Matched;
}
@@ -3610,7 +3767,7 @@ AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer,
Result.addMatch(InitBuilder);
}
}
- *Builder = Result;
+ *Builder = std::move(Result);
return Matched;
}
@@ -3631,7 +3788,32 @@ AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher<Expr>,
return InnerMatcher.matches(*Node.getLHS(), Finder, Builder);
}
+/// \brief Matches declaration that has a given attribute.
+///
+/// Given
+/// \code
+/// __attribute__((device)) void f() { ... }
+/// \endcode
+/// decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of
+/// f.
+AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) {
+ for (const auto *Attr : Node.attrs()) {
+ if (Attr->getKind() == AttrKind)
+ return true;
+ }
+ return false;
+}
+
+/// \brief Matches CUDA kernel call expression.
+///
+/// Example matches,
+/// \code
+/// kernel<<<i,j>>>();
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
+ CUDAKernelCallExpr;
+
} // end namespace ast_matchers
} // end namespace clang
-#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H
+#endif
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 12df77c156..1b8040cf44 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -32,8 +32,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H
-#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H
+#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
+#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Decl.h"
@@ -61,9 +61,8 @@ public:
/// \brief Adds \c Node to the map with key \c ID.
///
/// The node's base type should be in NodeBaseType or it will be unaccessible.
- template <typename T>
- void addNode(StringRef ID, const T* Node) {
- NodeMap[ID] = ast_type_traits::DynTypedNode::create(*Node);
+ void addNode(StringRef ID, const ast_type_traits::DynTypedNode& DynNode) {
+ NodeMap[ID] = DynNode;
}
/// \brief Returns the AST node bound to \c ID.
@@ -103,6 +102,16 @@ public:
return NodeMap;
}
+ /// \brief Returns \c true if this \c BoundNodesMap can be compared, i.e. all
+ /// stored nodes have memoization data.
+ bool isComparable() const {
+ for (const auto &IDAndNode : NodeMap) {
+ if (!IDAndNode.second.getMemoizationData())
+ return false;
+ }
+ return true;
+ }
+
private:
IDToNodeMap NodeMap;
};
@@ -126,11 +135,12 @@ public:
};
/// \brief Add a binding from an id to a node.
- template <typename T> void setBinding(const std::string &Id, const T *Node) {
+ void setBinding(const std::string &Id,
+ const ast_type_traits::DynTypedNode &DynNode) {
if (Bindings.empty())
Bindings.push_back(BoundNodesMap());
- for (unsigned i = 0, e = Bindings.size(); i != e; ++i)
- Bindings[i].addNode(Id, Node);
+ for (BoundNodesMap &Binding : Bindings)
+ Binding.addNode(Id, DynNode);
}
/// \brief Adds a branch in the tree.
@@ -153,12 +163,38 @@ public:
return Bindings < Other.Bindings;
}
+ /// \brief Returns \c true if this \c BoundNodesTreeBuilder can be compared,
+ /// i.e. all stored node maps have memoization data.
+ bool isComparable() const {
+ for (const BoundNodesMap &NodesMap : Bindings) {
+ if (!NodesMap.isComparable())
+ return false;
+ }
+ return true;
+ }
+
private:
SmallVector<BoundNodesMap, 16> Bindings;
};
class ASTMatchFinder;
+/// \brief Generic interface for all matchers.
+///
+/// Used by the implementation of Matcher<T> and DynTypedMatcher.
+/// In general, implement MatcherInterface<T> or SingleNodeMatcherInterface<T>
+/// instead.
+class DynMatcherInterface : public RefCountedBaseVPTR {
+public:
+ /// \brief Returns true if \p DynNode can be matched.
+ ///
+ /// May bind \p DynNode to an ID via \p Builder, or recurse into
+ /// the AST via \p Finder.
+ virtual bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const = 0;
+};
+
/// \brief Generic interface for matchers on an AST node of type T.
///
/// Implement this if your matcher may need to inspect the children or
@@ -167,7 +203,7 @@ class ASTMatchFinder;
/// current node and doesn't care about its children or descendants,
/// implement SingleNodeMatcherInterface instead.
template <typename T>
-class MatcherInterface : public RefCountedBaseVPTR {
+class MatcherInterface : public DynMatcherInterface {
public:
virtual ~MatcherInterface() {}
@@ -178,6 +214,15 @@ public:
virtual bool matches(const T &Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const = 0;
+
+ bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
+ if (const T *Node = DynNode.get<T>()) {
+ return matches(*Node, Finder, Builder);
+ }
+ return false;
+ }
};
/// \brief Interface for matchers that only evaluate properties on a single
@@ -199,6 +244,132 @@ private:
}
};
+template <typename> class Matcher;
+
+/// \brief Matcher that works on a \c DynTypedNode.
+///
+/// It is constructed from a \c Matcher<T> object and redirects most calls to
+/// underlying matcher.
+/// It checks whether the \c DynTypedNode is convertible into the type of the
+/// underlying matcher and then do the actual match on the actual node, or
+/// return false if it is not convertible.
+class DynTypedMatcher {
+public:
+ /// \brief Takes ownership of the provided implementation pointer.
+ template <typename T>
+ DynTypedMatcher(MatcherInterface<T> *Implementation)
+ : AllowBind(false),
+ SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
+ RestrictKind(SupportedKind), Implementation(Implementation) {}
+
+ /// \brief Construct from a variadic function.
+ enum VariadicOperator {
+ /// \brief Matches nodes for which all provided matchers match.
+ VO_AllOf,
+ /// \brief Matches nodes for which at least one of the provided matchers
+ /// matches.
+ VO_AnyOf,
+ /// \brief Matches nodes for which at least one of the provided matchers
+ /// matches, but doesn't stop at the first match.
+ VO_EachOf,
+ /// \brief Matches nodes that do not match the provided matcher.
+ ///
+ /// Uses the variadic matcher interface, but fails if
+ /// InnerMatchers.size() != 1.
+ VO_UnaryNot
+ };
+ static DynTypedMatcher
+ constructVariadic(VariadicOperator Op,
+ std::vector<DynTypedMatcher> InnerMatchers);
+
+ /// \brief Get a "true" matcher for \p NodeKind.
+ ///
+ /// It only checks that the node is of the right kind.
+ static DynTypedMatcher trueMatcher(ast_type_traits::ASTNodeKind NodeKind);
+
+ void setAllowBind(bool AB) { AllowBind = AB; }
+
+ /// \brief Return a matcher that points to the same implementation, but
+ /// restricts the node types for \p Kind.
+ DynTypedMatcher dynCastTo(const ast_type_traits::ASTNodeKind Kind) const;
+
+ /// \brief Returns true if the matcher matches the given \c DynNode.
+ bool matches(const ast_type_traits::DynTypedNode &DynNode,
+ ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const;
+
+ /// \brief Bind the specified \p ID to the matcher.
+ /// \return A new matcher with the \p ID bound to it if this matcher supports
+ /// binding. Otherwise, returns an empty \c Optional<>.
+ llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const;
+
+ /// \brief Returns a unique \p ID for the matcher.
+ ///
+ /// Casting a Matcher<T> to Matcher<U> creates a matcher that has the
+ /// same \c Implementation pointer, but different \c RestrictKind. We need to
+ /// include both in the ID to make it unique.
+ ///
+ /// \c MatcherIDType supports operator< and provides strict weak ordering.
+ typedef std::pair<ast_type_traits::ASTNodeKind, uint64_t> MatcherIDType;
+ MatcherIDType getID() const {
+ /// FIXME: Document the requirements this imposes on matcher
+ /// implementations (no new() implementation_ during a Matches()).
+ return std::make_pair(RestrictKind,
+ reinterpret_cast<uint64_t>(Implementation.get()));
+ }
+
+ /// \brief Returns the type this matcher works on.
+ ///
+ /// \c matches() will always return false unless the node passed is of this
+ /// or a derived type.
+ ast_type_traits::ASTNodeKind getSupportedKind() const {
+ return SupportedKind;
+ }
+
+ /// \brief Returns \c true if the passed \c DynTypedMatcher can be converted
+ /// to a \c Matcher<T>.
+ ///
+ /// This method verifies that the underlying matcher in \c Other can process
+ /// nodes of types T.
+ template <typename T> bool canConvertTo() const {
+ return canConvertTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
+ }
+ bool canConvertTo(ast_type_traits::ASTNodeKind To) const;
+
+ /// \brief Construct a \c Matcher<T> interface around the dynamic matcher.
+ ///
+ /// This method asserts that \c canConvertTo() is \c true. Callers
+ /// should call \c canConvertTo() first to make sure that \c this is
+ /// compatible with T.
+ template <typename T> Matcher<T> convertTo() const {
+ assert(canConvertTo<T>());
+ return unconditionalConvertTo<T>();
+ }
+
+ /// \brief Same as \c convertTo(), but does not check that the underlying
+ /// matcher can handle a value of T.
+ ///
+ /// If it is not compatible, then this matcher will never match anything.
+ template <typename T> Matcher<T> unconditionalConvertTo() const;
+
+private:
+ DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind,
+ ast_type_traits::ASTNodeKind RestrictKind,
+ IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
+ : AllowBind(false),
+ SupportedKind(SupportedKind),
+ RestrictKind(RestrictKind),
+ Implementation(std::move(Implementation)) {}
+
+ bool AllowBind;
+ ast_type_traits::ASTNodeKind SupportedKind;
+ /// \brief A potentially stricter node kind.
+ ///
+ /// It allows to perform implicit and dynamic cast of matchers without
+ /// needing to change \c Implementation.
+ ast_type_traits::ASTNodeKind RestrictKind;
+ IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
+};
+
/// \brief Wrapper of a MatcherInterface<T> *that allows copying.
///
/// A Matcher<Base> can be used anywhere a Matcher<Derived> is
@@ -221,7 +392,10 @@ public:
Matcher(const Matcher<From> &Other,
typename std::enable_if<std::is_base_of<From, T>::value &&
!std::is_same<From, T>::value>::type * = 0)
- : Implementation(new ImplicitCastMatcher<From>(Other)) {}
+ : Implementation(restrictMatcher(Other.Implementation)) {
+ assert(Implementation.getSupportedKind().isSame(
+ ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
+ }
/// \brief Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
///
@@ -233,26 +407,34 @@ public:
std::is_same<TypeT, Type>::value>::type* = 0)
: Implementation(new TypeToQualType<TypeT>(Other)) {}
+ /// \brief Convert \c this into a \c Matcher<T> by applying dyn_cast<> to the
+ /// argument.
+ /// \c To must be a base class of \c T.
+ template <typename To>
+ Matcher<To> dynCastTo() const {
+ static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
+ return Matcher<To>(Implementation);
+ }
+
/// \brief Forwards the call to the underlying MatcherInterface<T> pointer.
bool matches(const T &Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
- 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;
+ return Implementation.matches(ast_type_traits::DynTypedNode::create(Node),
+ Finder, Builder);
}
/// \brief Returns an ID that uniquely identifies the matcher.
- uint64_t getID() const {
- /// FIXME: Document the requirements this imposes on matcher
- /// implementations (no new() implementation_ during a Matches()).
- return reinterpret_cast<uint64_t>(Implementation.get());
+ DynTypedMatcher::MatcherIDType getID() const {
+ return Implementation.getID();
}
+ /// \brief Extract the dynamic matcher.
+ ///
+ /// The returned matcher keeps the same restrictions as \c this and remembers
+ /// that it is meant to support nodes of type \c T.
+ operator DynTypedMatcher() const { return Implementation; }
+
/// \brief Allows the conversion of a \c Matcher<Type> to a \c
/// Matcher<QualType>.
///
@@ -276,24 +458,22 @@ public:
};
private:
- /// \brief Allows conversion from Matcher<Base> to Matcher<T> if T
- /// is derived from Base.
- template <typename Base>
- class ImplicitCastMatcher : public MatcherInterface<T> {
- public:
- explicit ImplicitCastMatcher(const Matcher<Base> &From)
- : From(From) {}
+ // For Matcher<T> <=> Matcher<U> conversions.
+ template <typename U> friend class Matcher;
+ // For DynTypedMatcher::unconditionalConvertTo<T>.
+ friend class DynTypedMatcher;
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- return From.matches(Node, Finder, Builder);
- }
+ static DynTypedMatcher restrictMatcher(const DynTypedMatcher &Other) {
+ return Other.dynCastTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
+ }
- private:
- const Matcher<Base> From;
- };
+ explicit Matcher(const DynTypedMatcher &Implementation)
+ : Implementation(restrictMatcher(Implementation)) {
+ assert(this->Implementation.getSupportedKind()
+ .isSame(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
+ }
- IntrusiveRefCntPtr< MatcherInterface<T> > Implementation;
+ DynTypedMatcher Implementation;
}; // class Matcher
/// \brief A convenient helper for creating a Matcher<T> without specifying
@@ -303,153 +483,10 @@ inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
return Matcher<T>(Implementation);
}
-template <typename T> class BindableMatcher;
-
-/// \brief Matcher that works on a \c DynTypedNode.
-///
-/// It is constructed from a \c Matcher<T> object and redirects most calls to
-/// underlying matcher.
-/// It checks whether the \c DynTypedNode is convertible into the type of the
-/// underlying matcher and then do the actual match on the actual node, or
-/// return false if it is not convertible.
-class DynTypedMatcher {
-public:
- /// \brief Construct from a \c Matcher<T>. Copies the matcher.
- template <typename T> inline DynTypedMatcher(const Matcher<T> &M);
-
- /// \brief Construct from a bindable \c Matcher<T>. Copies the matcher.
- ///
- /// This version enables \c tryBind() on the \c DynTypedMatcher.
- template <typename T> inline DynTypedMatcher(const BindableMatcher<T> &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<DynTypedMatcher> 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<T>.
- ///
- /// This method verifies that the underlying matcher in \c Other can process
- /// nodes of types T.
- template <typename T> bool canConvertTo() const {
- return getSupportedKind().isBaseOf(
- ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
- }
-
- /// \brief Construct a \c Matcher<T> interface around the dynamic matcher.
- ///
- /// This method asserts that \c canConvertTo() is \c true. Callers
- /// should call \c canConvertTo() first to make sure that \c this is
- /// compatible with T.
- template <typename T> Matcher<T> convertTo() const {
- assert(canConvertTo<T>());
- return unconditionalConvertTo<T>();
- }
-
- /// \brief Same as \c convertTo(), but does not check that the underlying
- /// matcher can handle a value of T.
- ///
- /// If it is not compatible, then this matcher will never match anything.
- template <typename T> Matcher<T> unconditionalConvertTo() const;
-
-private:
- 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<DynTypedMatcher> 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 <typename T> class TypedMatcherStorage;
-
- IntrusiveRefCntPtr<const MatcherStorage> Storage;
-};
-
-template <typename T>
-class DynTypedMatcher::TypedMatcherStorage : public MatcherStorage {
-public:
- TypedMatcherStorage(const Matcher<T> &Other, bool AllowBind)
- : MatcherStorage(ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
- Other.getID()),
- InnerMatcher(Other), AllowBind(AllowBind) {}
-
- bool matches(const ast_type_traits::DynTypedNode DynNode,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- if (const T *Node = DynNode.get<T>()) {
- return InnerMatcher.matches(*Node, Finder, Builder);
- }
- return false;
- }
-
- llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const override {
- if (!AllowBind)
- return llvm::Optional<DynTypedMatcher>();
- return DynTypedMatcher(BindableMatcher<T>(InnerMatcher).bind(ID));
- }
-
-private:
- const Matcher<T> InnerMatcher;
- const bool AllowBind;
-};
-
-template <typename T>
-inline DynTypedMatcher::DynTypedMatcher(const Matcher<T> &M)
- : Storage(new TypedMatcherStorage<T>(M, false)) {}
-
-template <typename T>
-inline DynTypedMatcher::DynTypedMatcher(const BindableMatcher<T> &M)
- : Storage(new TypedMatcherStorage<T>(M, true)) {}
-
/// \brief Specialization of the conversion functions for QualType.
///
-/// These specializations provide the Matcher<Type>->Matcher<QualType>
+/// This specialization provides the Matcher<Type>->Matcher<QualType>
/// conversion that the static API does.
-template <> inline bool DynTypedMatcher::canConvertTo<QualType>() const {
- const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
- return SourceKind.isSame(
- ast_type_traits::ASTNodeKind::getFromNodeKind<Type>()) ||
- SourceKind.isSame(
- ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>());
-}
-
template <>
inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {
assert(canConvertTo<QualType>());
@@ -470,7 +507,7 @@ bool matchesFirstInRange(const MatcherT &Matcher, IteratorT Start,
for (IteratorT I = Start; I != End; ++I) {
BoundNodesTreeBuilder Result(*Builder);
if (Matcher.matches(*I, Finder, &Result)) {
- *Builder = Result;
+ *Builder = std::move(Result);
return true;
}
}
@@ -486,7 +523,7 @@ bool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start,
for (IteratorT I = Start; I != End; ++I) {
BoundNodesTreeBuilder Result(*Builder);
if (Matcher.matches(**I, Finder, &Result)) {
- *Builder = Result;
+ *Builder = std::move(Result);
return true;
}
}
@@ -517,7 +554,7 @@ template <typename T> struct has_getDecl {
template <typename T, typename ArgT>
class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
- std::is_same<T, CXXMethodDecl>::value,
+ std::is_base_of<FunctionDecl, T>::value,
"unsupported class for matcher");
static_assert(std::is_same<ArgT, StringRef>::value,
"argument type must be StringRef");
@@ -541,7 +578,7 @@ private:
/// \brief Returns true only if CXXMethodDecl represents an overloaded
/// operator and has the given operator name.
- bool matchesSpecialized(const CXXMethodDecl &Node) const {
+ bool matchesSpecialized(const FunctionDecl &Node) const {
return Node.isOverloadedOperator() &&
getOperatorSpelling(Node.getOverloadedOperator()) == Name;
}
@@ -549,6 +586,33 @@ private:
std::string Name;
};
+/// \brief Matches named declarations with a specific name.
+///
+/// See \c hasName() in ASTMatchers.h for details.
+class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
+ public:
+ explicit HasNameMatcher(StringRef Name);
+
+ bool matchesNode(const NamedDecl &Node) const override;
+
+ private:
+ /// \brief Unqualified match routine.
+ ///
+ /// It is much faster than the full match, but it only works for unqualified
+ /// matches.
+ bool matchesNodeUnqualified(const NamedDecl &Node) const;
+
+ /// \brief Full match routine
+ ///
+ /// It generates the fully qualified name of the declaration (which is
+ /// expensive) before trying to match.
+ /// It is slower but simple and works on all cases.
+ bool matchesNodeFull(const NamedDecl &Node) const;
+
+ const bool UseUnqualifiedMatch;
+ const std::string Name;
+};
+
/// \brief Matches declarations for QualType and CallExpr.
///
/// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but
@@ -973,46 +1037,16 @@ private:
///
/// This is useful when a matcher syntactically requires a child matcher,
/// but the context doesn't care. See for example: anything().
-///
-/// FIXME: Alternatively we could also create a IsAMatcher or something
-/// that checks that a dyn_cast is possible. This is purely needed for the
-/// difference between calling for example:
-/// record()
-/// and
-/// record(SomeMatcher)
-/// In the second case we need the correct type we were dyn_cast'ed to in order
-/// to get the right type for the inner matcher. In the first case we don't need
-/// that, but we use the type conversion anyway and insert a TrueMatcher.
-template <typename T>
-class TrueMatcher : public SingleNodeMatcherInterface<T> {
-public:
- bool matchesNode(const T &Node) const override {
- return true;
- }
-};
-
-/// \brief Matcher<T> that wraps an inner Matcher<T> and binds the matched node
-/// to an ID if the inner matcher matches on the node.
-template <typename T>
-class IdMatcher : public MatcherInterface<T> {
-public:
- /// \brief Creates an IdMatcher that binds to 'ID' if 'InnerMatcher' matches
- /// the node.
- IdMatcher(StringRef ID, const Matcher<T> &InnerMatcher)
- : ID(ID), InnerMatcher(InnerMatcher) {}
+class TrueMatcher {
+ public:
+ typedef AllNodeBaseTypes ReturnTypes;
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- bool Result = InnerMatcher.matches(Node, Finder, Builder);
- if (Result) {
- Builder->setBinding(ID, &Node);
- }
- return Result;
+ template <typename T>
+ operator Matcher<T>() const {
+ return DynTypedMatcher::trueMatcher(
+ ast_type_traits::ASTNodeKind::getFromNodeKind<T>())
+ .template unconditionalConvertTo<T>();
}
-
-private:
- const std::string ID;
- const Matcher<T> InnerMatcher;
};
/// \brief A Matcher that allows binding the node it matches to an id.
@@ -1031,7 +1065,17 @@ public:
/// The returned matcher is equivalent to this matcher, but will
/// bind the matched node on a match.
Matcher<T> bind(StringRef ID) const {
- return Matcher<T>(new IdMatcher<T>(ID, *this));
+ return DynTypedMatcher(*this)
+ .tryBind(ID)
+ ->template unconditionalConvertTo<T>();
+ }
+
+ /// \brief Same as Matcher<T>'s conversion operator, but enables binding on
+ /// the returned matcher.
+ operator DynTypedMatcher() const {
+ DynTypedMatcher Result = static_cast<const Matcher<T>&>(*this);
+ Result.setAllowBind(true);
+ return Result;
}
};
@@ -1089,36 +1133,11 @@ private:
/// \brief VariadicOperatorMatcher related types.
/// @{
-/// \brief Function signature for any variadic operator. It takes the inner
-/// matchers as an array of DynTypedMatcher.
-typedef bool (*VariadicOperatorFunction)(
- const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
-
-/// \brief \c MatcherInterface<T> implementation for an variadic operator.
-template <typename T>
-class VariadicOperatorMatcherInterface : public MatcherInterface<T> {
-public:
- VariadicOperatorMatcherInterface(VariadicOperatorFunction Func,
- std::vector<DynTypedMatcher> InnerMatchers)
- : Func(Func), InnerMatchers(std::move(InnerMatchers)) {}
-
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const override {
- return Func(ast_type_traits::DynTypedNode::create(Node), Finder, Builder,
- InnerMatchers);
- }
-
-private:
- const VariadicOperatorFunction Func;
- const std::vector<DynTypedMatcher> InnerMatchers;
-};
-
/// \brief "No argument" placeholder to use as template paratemers.
struct VariadicOperatorNoArg {};
-/// \brief Polymorphic matcher object that uses a \c VariadicOperatorFunction
-/// operator.
+/// \brief Polymorphic matcher object that uses a \c
+/// DynTypedMatcher::VariadicOperator operator.
///
/// Input matchers can have any type (including other polymorphic matcher
/// types), and the actual Matcher<T> is generated on demand with an implicit
@@ -1133,7 +1152,8 @@ template <typename P1, typename P2 = VariadicOperatorNoArg,
typename P9 = VariadicOperatorNoArg>
class VariadicOperatorMatcher {
public:
- VariadicOperatorMatcher(VariadicOperatorFunction Func, const P1 &Param1,
+ VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op,
+ const P1 &Param1,
const P2 &Param2 = VariadicOperatorNoArg(),
const P3 &Param3 = VariadicOperatorNoArg(),
const P4 &Param4 = VariadicOperatorNoArg(),
@@ -1142,7 +1162,7 @@ public:
const P7 &Param7 = VariadicOperatorNoArg(),
const P8 &Param8 = VariadicOperatorNoArg(),
const P9 &Param9 = VariadicOperatorNoArg())
- : Func(Func), Param1(Param1), Param2(Param2), Param3(Param3),
+ : Op(Op), Param1(Param1), Param2(Param2), Param3(Param3),
Param4(Param4), Param5(Param5), Param6(Param6), Param7(Param7),
Param8(Param8), Param9(Param9) {}
@@ -1157,8 +1177,8 @@ public:
addMatcher<T>(Param7, Matchers);
addMatcher<T>(Param8, Matchers);
addMatcher<T>(Param9, Matchers);
- return Matcher<T>(
- new VariadicOperatorMatcherInterface<T>(Func, std::move(Matchers)));
+ return DynTypedMatcher::constructVariadic(Op, std::move(Matchers))
+ .template unconditionalConvertTo<T>();
}
private:
@@ -1173,7 +1193,7 @@ private:
static void addMatcher(VariadicOperatorNoArg,
std::vector<DynTypedMatcher> &Matchers) {}
- const VariadicOperatorFunction Func;
+ const DynTypedMatcher::VariadicOperator Op;
const P1 Param1;
const P2 Param2;
const P3 Param3;
@@ -1191,7 +1211,7 @@ private:
/// It supports 1-9 argument overloaded operator(). More can be added if needed.
template <unsigned MinCount, unsigned MaxCount>
struct VariadicOperatorMatcherFunc {
- VariadicOperatorFunction Func;
+ DynTypedMatcher::VariadicOperator Op;
template <unsigned Count, typename T>
struct EnableIfValidArity
@@ -1200,30 +1220,29 @@ struct VariadicOperatorMatcherFunc {
template <typename M1>
typename EnableIfValidArity<1, VariadicOperatorMatcher<M1> >::type
operator()(const M1 &P1) const {
- return VariadicOperatorMatcher<M1>(Func, P1);
+ return VariadicOperatorMatcher<M1>(Op, P1);
}
template <typename M1, typename M2>
typename EnableIfValidArity<2, VariadicOperatorMatcher<M1, M2> >::type
operator()(const M1 &P1, const M2 &P2) const {
- return VariadicOperatorMatcher<M1, M2>(Func, P1, P2);
+ return VariadicOperatorMatcher<M1, M2>(Op, P1, P2);
}
template <typename M1, typename M2, typename M3>
typename EnableIfValidArity<3, VariadicOperatorMatcher<M1, M2, M3> >::type
operator()(const M1 &P1, const M2 &P2, const M3 &P3) const {
- return VariadicOperatorMatcher<M1, M2, M3>(Func, P1, P2, P3);
+ return VariadicOperatorMatcher<M1, M2, M3>(Op, P1, P2, P3);
}
template <typename M1, typename M2, typename M3, typename M4>
typename EnableIfValidArity<4, VariadicOperatorMatcher<M1, M2, M3, M4> >::type
operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) const {
- return VariadicOperatorMatcher<M1, M2, M3, M4>(Func, P1, P2, P3, P4);
+ return VariadicOperatorMatcher<M1, M2, M3, M4>(Op, P1, P2, P3, P4);
}
template <typename M1, typename M2, typename M3, typename M4, typename M5>
typename EnableIfValidArity<
5, VariadicOperatorMatcher<M1, M2, M3, M4, M5> >::type
operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
const M5 &P5) const {
- return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Func, P1, P2, P3, P4,
- P5);
+ return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Op, P1, P2, P3, P4, P5);
}
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6>
@@ -1232,7 +1251,7 @@ struct VariadicOperatorMatcherFunc {
operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
const M5 &P5, const M6 &P6) const {
return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6>(
- Func, P1, P2, P3, P4, P5, P6);
+ Op, P1, P2, P3, P4, P5, P6);
}
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6, typename M7>
@@ -1241,7 +1260,7 @@ struct VariadicOperatorMatcherFunc {
operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
const M5 &P5, const M6 &P6, const M7 &P7) const {
return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7>(
- Func, P1, P2, P3, P4, P5, P6, P7);
+ Op, P1, P2, P3, P4, P5, P6, P7);
}
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6, typename M7, typename M8>
@@ -1250,7 +1269,7 @@ struct VariadicOperatorMatcherFunc {
operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8) const {
return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8>(
- Func, P1, P2, P3, P4, P5, P6, P7, P8);
+ Op, P1, P2, P3, P4, P5, P6, P7, P8);
}
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6, typename M7, typename M8, typename M9>
@@ -1260,55 +1279,40 @@ struct VariadicOperatorMatcherFunc {
const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8,
const M9 &P9) const {
return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9>(
- Func, P1, P2, P3, P4, P5, P6, P7, P8, P9);
+ Op, P1, P2, P3, P4, P5, P6, P7, P8, P9);
}
};
/// @}
-/// \brief Matches nodes that do not match the provided matcher.
-///
-/// Uses the variadic matcher interface, but fails if InnerMatchers.size()!=1.
-bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
- ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
- ArrayRef<DynTypedMatcher> InnerMatchers);
-
-/// \brief Matches nodes for which all provided matchers match.
-bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder,
- ArrayRef<DynTypedMatcher> InnerMatchers);
-
-/// \brief Matches nodes for which at least one of the provided matchers
-/// matches, but doesn't stop at the first match.
-bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder,
- ArrayRef<DynTypedMatcher> InnerMatchers);
-
-/// \brief Matches nodes for which at least one of the provided matchers
-/// matches.
-bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder,
- ArrayRef<DynTypedMatcher> InnerMatchers);
-
template <typename T>
inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
- return Matcher<T>(new VariadicOperatorMatcherInterface<T>(
- AllOfVariadicOperator, llvm::makeArrayRef(*this)));
+ return Matcher<T>(*this);
}
/// \brief Creates a Matcher<T> that matches if all inner matchers match.
template<typename T>
BindableMatcher<T> makeAllOfComposite(
ArrayRef<const Matcher<T> *> InnerMatchers) {
- std::vector<DynTypedMatcher> DynMatchers;
- for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
- DynMatchers.push_back(*InnerMatchers[i]);
+ // For the size() == 0 case, we return a "true" matcher.
+ if (InnerMatchers.size() == 0) {
+ return BindableMatcher<T>(TrueMatcher());
}
- return BindableMatcher<T>(new VariadicOperatorMatcherInterface<T>(
- AllOfVariadicOperator, std::move(DynMatchers)));
+ // For the size() == 1 case, we simply return that one matcher.
+ // No need to wrap it in a variadic operation.
+ if (InnerMatchers.size() == 1) {
+ return BindableMatcher<T>(*InnerMatchers[0]);
+ }
+
+ std::vector<DynTypedMatcher> DynMatchers;
+ DynMatchers.reserve(InnerMatchers.size());
+ for (const auto *InnerMatcher : InnerMatchers) {
+ DynMatchers.push_back(*InnerMatcher);
+ }
+ return BindableMatcher<T>(
+ DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf,
+ std::move(DynMatchers))
+ .template unconditionalConvertTo<T>());
}
/// \brief Creates a Matcher<T> that matches if
@@ -1320,8 +1324,8 @@ BindableMatcher<T> makeAllOfComposite(
template<typename T, typename InnerT>
BindableMatcher<T> makeDynCastAllOfComposite(
ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
- return BindableMatcher<T>(DynTypedMatcher(makeAllOfComposite(InnerMatchers))
- .unconditionalConvertTo<T>());
+ return BindableMatcher<T>(
+ makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
}
/// \brief Matches nodes of type T that have at least one descendant node of
@@ -1627,7 +1631,7 @@ getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
inline ArrayRef<TemplateArgument>
getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
- return ArrayRef<TemplateArgument>(T.getArgs(), T.getNumArgs());
+ return llvm::makeArrayRef(T.getArgs(), T.getNumArgs());
}
struct NotEqualsBoundNodePredicate {
@@ -1642,4 +1646,4 @@ struct NotEqualsBoundNodePredicate {
} // end namespace ast_matchers
} // end namespace clang
-#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H
+#endif
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h
index 563372a506..4d57b94c7f 100644
--- a/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ b/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -34,8 +34,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
-#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
+#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
+#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
/// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
/// defines a single-parameter function named DefineMatcher() that returns a
@@ -352,4 +352,4 @@
internal::TypeLocTraverseMatcher, ReturnTypesF>::Func MatcherName##Loc; \
AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
-#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
+#endif
diff --git a/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
index 82a14f1929..ef93ac5450 100644
--- a/include/clang/ASTMatchers/Dynamic/Diagnostics.h
+++ b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
-#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
+#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H
+#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "clang/Basic/LLVM.h"
diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h
index 4045f57d1b..bd006b6e12 100644
--- a/include/clang/ASTMatchers/Dynamic/Parser.h
+++ b/include/clang/ASTMatchers/Dynamic/Parser.h
@@ -31,8 +31,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
-#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
+#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
+#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
#include "clang/ASTMatchers/Dynamic/Registry.h"
@@ -63,17 +63,6 @@ public:
public:
virtual ~Sema();
- /// \brief Lookup a value by name.
- ///
- /// This can be used in the Sema layer to declare known constants or to
- /// allow to split an expression in pieces.
- ///
- /// \param Name The name of the value to lookup.
- ///
- /// \return The named value. It could be any type that VariantValue
- /// supports. An empty value means that the name is not recognized.
- virtual VariantValue getNamedValue(StringRef Name);
-
/// \brief Process a matcher expression.
///
/// All the arguments passed here have already been processed.
@@ -105,6 +94,29 @@ public:
/// found.
virtual llvm::Optional<MatcherCtor>
lookupMatcherCtor(StringRef MatcherName) = 0;
+
+ /// \brief Compute the list of completion types for \p Context.
+ ///
+ /// Each element of \p Context represents a matcher invocation, going from
+ /// outermost to innermost. Elements are pairs consisting of a reference to
+ /// the matcher constructor and the index of the next element in the
+ /// argument list of that matcher (or for the last element, the index of
+ /// the completion point in the argument list). An empty list requests
+ /// completion for the root matcher.
+ virtual std::vector<ArgKind> getAcceptedCompletionTypes(
+ llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);
+
+ /// \brief Compute the list of completions that match any of
+ /// \p AcceptedTypes.
+ ///
+ /// \param AcceptedTypes All types accepted for this completion.
+ ///
+ /// \return All completions for the specified types.
+ /// Completions should be valid when used in \c lookupMatcherCtor().
+ /// The matcher constructed from the return of \c lookupMatcherCtor()
+ /// should be convertible to some type in \p AcceptedTypes.
+ virtual std::vector<MatcherCompletion>
+ getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes);
};
/// \brief Sema implementation that uses the matcher registry to process the
@@ -121,58 +133,91 @@ public:
StringRef BindID,
ArrayRef<ParserValue> Args,
Diagnostics *Error) override;
+
+ std::vector<ArgKind> getAcceptedCompletionTypes(
+ llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context) override;
+
+ std::vector<MatcherCompletion>
+ getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) override;
};
- /// \brief Parse a matcher expression, creating matchers from the registry.
- ///
- /// This overload creates matchers calling directly into the registry. If the
- /// caller needs more control over how the matchers are created, then it can
- /// use the overload below that takes a Sema.
- ///
- /// \param MatcherCode The matcher expression to parse.
- ///
- /// \return The matcher object constructed, or an empty Optional if an error
- /// occurred.
- /// In that case, \c Error will contain a description of the error.
- /// The caller takes ownership of the DynTypedMatcher object returned.
- static llvm::Optional<DynTypedMatcher>
- parseMatcherExpression(StringRef MatcherCode, Diagnostics *Error);
+ typedef llvm::StringMap<VariantValue> NamedValueMap;
/// \brief Parse a matcher expression.
///
/// \param MatcherCode The matcher expression to parse.
///
/// \param S The Sema instance that will help the parser
- /// construct the matchers.
+ /// construct the matchers. If null, it uses the default registry.
+ ///
+ /// \param NamedValues A map of precomputed named values. This provides
+ /// the dictionary for the <NamedValue> rule of the grammar.
+ /// If null, it is ignored.
+ ///
/// \return The matcher object constructed by the processor, or an empty
/// Optional if an error occurred. In that case, \c Error will contain a
/// description of the error.
/// The caller takes ownership of the DynTypedMatcher object returned.
static llvm::Optional<DynTypedMatcher>
- parseMatcherExpression(StringRef MatcherCode, Sema *S, Diagnostics *Error);
-
- /// \brief Parse an expression, creating matchers from the registry.
- ///
- /// Parses any expression supported by this parser. In general, the
- /// \c parseMatcherExpression function is a better approach to get a matcher
- /// object.
- static bool parseExpression(StringRef Code, VariantValue *Value,
- Diagnostics *Error);
+ parseMatcherExpression(StringRef MatcherCode, Sema *S,
+ const NamedValueMap *NamedValues,
+ Diagnostics *Error);
+ static llvm::Optional<DynTypedMatcher>
+ parseMatcherExpression(StringRef MatcherCode, Sema *S,
+ Diagnostics *Error) {
+ return parseMatcherExpression(MatcherCode, S, nullptr, Error);
+ }
+ static llvm::Optional<DynTypedMatcher>
+ parseMatcherExpression(StringRef MatcherCode, Diagnostics *Error) {
+ return parseMatcherExpression(MatcherCode, nullptr, Error);
+ }
/// \brief Parse an expression.
///
/// Parses any expression supported by this parser. In general, the
/// \c parseMatcherExpression function is a better approach to get a matcher
/// object.
+ ///
+ /// \param S The Sema instance that will help the parser
+ /// construct the matchers. If null, it uses the default registry.
+ ///
+ /// \param NamedValues A map of precomputed named values. This provides
+ /// the dictionary for the <NamedValue> rule of the grammar.
+ /// If null, it is ignored.
static bool parseExpression(StringRef Code, Sema *S,
+ const NamedValueMap *NamedValues,
VariantValue *Value, Diagnostics *Error);
+ static bool parseExpression(StringRef Code, Sema *S,
+ VariantValue *Value, Diagnostics *Error) {
+ return parseExpression(Code, S, nullptr, Value, Error);
+ }
+ static bool parseExpression(StringRef Code, VariantValue *Value,
+ Diagnostics *Error) {
+ return parseExpression(Code, nullptr, Value, Error);
+ }
/// \brief Complete an expression at the given offset.
///
+ /// \param S The Sema instance that will help the parser
+ /// construct the matchers. If null, it uses the default registry.
+ ///
+ /// \param NamedValues A map of precomputed named values. This provides
+ /// the dictionary for the <NamedValue> rule of the grammar.
+ /// If null, it is ignored.
+ ///
/// \return The list of completions, which may be empty if there are no
/// available completions or if an error occurred.
static std::vector<MatcherCompletion>
- completeExpression(StringRef Code, unsigned CompletionOffset);
+ completeExpression(StringRef Code, unsigned CompletionOffset, Sema *S,
+ const NamedValueMap *NamedValues);
+ static std::vector<MatcherCompletion>
+ completeExpression(StringRef Code, unsigned CompletionOffset, Sema *S) {
+ return completeExpression(Code, CompletionOffset, S, nullptr);
+ }
+ static std::vector<MatcherCompletion>
+ completeExpression(StringRef Code, unsigned CompletionOffset) {
+ return completeExpression(Code, CompletionOffset, nullptr);
+ }
private:
class CodeTokenizer;
@@ -180,6 +225,7 @@ private:
struct TokenInfo;
Parser(CodeTokenizer *Tokenizer, Sema *S,
+ const NamedValueMap *NamedValues,
Diagnostics *Error);
bool parseExpressionImpl(VariantValue *Value);
@@ -187,12 +233,16 @@ private:
VariantValue *Value);
bool parseIdentifierPrefixImpl(VariantValue *Value);
- void addCompletion(const TokenInfo &CompToken, StringRef TypedText,
- StringRef Decl);
+ void addCompletion(const TokenInfo &CompToken,
+ const MatcherCompletion &Completion);
void addExpressionCompletions();
+ std::vector<MatcherCompletion>
+ getNamedValueCompletions(ArrayRef<ArgKind> AcceptedTypes);
+
CodeTokenizer *const Tokenizer;
Sema *const S;
+ const NamedValueMap *const NamedValues;
Diagnostics *const Error;
typedef std::vector<std::pair<MatcherCtor, unsigned> > ContextStackTy;
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
index faa9254bc2..ad24a8d1b7 100644
--- a/include/clang/ASTMatchers/Dynamic/Registry.h
+++ b/include/clang/ASTMatchers/Dynamic/Registry.h
@@ -14,8 +14,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
-#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
+#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
+#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
@@ -36,8 +36,10 @@ typedef const internal::MatcherDescriptor *MatcherCtor;
struct MatcherCompletion {
MatcherCompletion() {}
- MatcherCompletion(StringRef TypedText, StringRef MatcherDecl)
- : TypedText(TypedText), MatcherDecl(MatcherDecl) {}
+ MatcherCompletion(StringRef TypedText, StringRef MatcherDecl,
+ unsigned Specificity)
+ : TypedText(TypedText), MatcherDecl(MatcherDecl),
+ Specificity(Specificity) {}
/// \brief The text to type to select this matcher.
std::string TypedText;
@@ -45,6 +47,13 @@ struct MatcherCompletion {
/// \brief The "declaration" of the matcher, with type information.
std::string MatcherDecl;
+ /// \brief Value corresponding to the "specificity" of the converted matcher.
+ ///
+ /// Zero specificity indicates that this conversion would produce a trivial
+ /// matcher that will either always or never match.
+ /// Such matchers are excluded from code completion results.
+ unsigned Specificity;
+
bool operator==(const MatcherCompletion &Other) const {
return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
}
@@ -58,28 +67,28 @@ public:
/// constructor, or Optional<MatcherCtor>() if not found.
static llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName);
- /// \brief Compute the list of completions for \p Context.
+ /// \brief Compute the list of completion types for \p Context.
///
/// Each element of \p Context represents a matcher invocation, going from
- /// outermost to innermost. Elements are pairs consisting of a reference to the
- /// matcher constructor and the index of the next element in the argument list
- /// of that matcher (or for the last element, the index of the completion
- /// point in the argument list). An empty list requests completion for the
- /// root matcher.
+ /// outermost to innermost. Elements are pairs consisting of a reference to
+ /// the matcher constructor and the index of the next element in the
+ /// argument list of that matcher (or for the last element, the index of
+ /// the completion point in the argument list). An empty list requests
+ /// completion for the root matcher.
+ static std::vector<ArgKind> getAcceptedCompletionTypes(
+ llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);
+
+ /// \brief Compute the list of completions that match any of
+ /// \p AcceptedTypes.
///
- /// The completions are ordered first by decreasing relevance, then
- /// alphabetically. Relevance is determined by how closely the matcher's
- /// type matches that of the context. For example, if the innermost matcher
- /// takes a FunctionDecl matcher, the FunctionDecl matchers are returned
- /// first, followed by the ValueDecl matchers, then NamedDecl, then Decl, then
- /// polymorphic matchers.
+ /// \param AcceptedTypes All types accepted for this completion.
///
- /// Matchers which are technically convertible to the innermost context but
- /// which would match either all or no nodes are excluded. For example,
- /// namedDecl and varDecl are excluded in a FunctionDecl context, because
- /// those matchers would match respectively all or no nodes in such a context.
+ /// \return All completions for the specified types.
+ /// Completions should be valid when used in \c lookupMatcherCtor().
+ /// The matcher constructed from the return of \c lookupMatcherCtor()
+ /// should be convertible to some type in \p AcceptedTypes.
static std::vector<MatcherCompletion>
- getCompletions(ArrayRef<std::pair<MatcherCtor, unsigned> > Context);
+ getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes);
/// \brief Construct a matcher from the registry.
///
diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h
index b25267b1c5..a9bd3d5011 100644
--- a/include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -14,8 +14,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
-#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
+#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
+#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
@@ -29,6 +29,51 @@ namespace clang {
namespace ast_matchers {
namespace dynamic {
+/// \brief Kind identifier.
+///
+/// It supports all types that VariantValue can contain.
+class ArgKind {
+ public:
+ enum Kind {
+ AK_Matcher,
+ AK_Unsigned,
+ AK_String
+ };
+ /// \brief Constructor for non-matcher types.
+ ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); }
+
+ /// \brief Constructor for matcher types.
+ ArgKind(ast_type_traits::ASTNodeKind MatcherKind)
+ : K(AK_Matcher), MatcherKind(MatcherKind) {}
+
+ Kind getArgKind() const { return K; }
+ ast_type_traits::ASTNodeKind getMatcherKind() const {
+ assert(K == AK_Matcher);
+ return MatcherKind;
+ }
+
+ /// \brief Determines if this type can be converted to \p To.
+ ///
+ /// \param To the requested destination type.
+ ///
+ /// \param Specificity value corresponding to the "specificity" of the
+ /// convertion.
+ bool isConvertibleTo(ArgKind To, unsigned *Specificity) const;
+
+ bool operator<(const ArgKind &Other) const {
+ if (K == AK_Matcher && Other.K == AK_Matcher)
+ return MatcherKind < Other.MatcherKind;
+ return K < Other.K;
+ }
+
+ /// \brief String representation of the type.
+ std::string asString() const;
+
+private:
+ Kind K;
+ ast_type_traits::ASTNodeKind MatcherKind;
+};
+
using ast_matchers::internal::DynTypedMatcher;
/// \brief A variant matcher object.
@@ -48,13 +93,28 @@ class VariantMatcher {
/// \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher.
class MatcherOps {
public:
- virtual ~MatcherOps();
- virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
- bool &IsExactMatch) const = 0;
- virtual void constructFrom(const DynTypedMatcher &Matcher) = 0;
- virtual void constructVariadicOperator(
- ast_matchers::internal::VariadicOperatorFunction Func,
- ArrayRef<VariantMatcher> InnerMatchers) = 0;
+ MatcherOps(ast_type_traits::ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
+
+ bool canConstructFrom(const DynTypedMatcher &Matcher,
+ bool &IsExactMatch) const;
+
+ /// \brief Convert \p Matcher the destination type and return it as a new
+ /// DynTypedMatcher.
+ virtual DynTypedMatcher
+ convertMatcher(const DynTypedMatcher &Matcher) const = 0;
+
+ /// \brief Constructs a variadic typed matcher from \p InnerMatchers.
+ /// Will try to convert each inner matcher to the destination type and
+ /// return llvm::None if it fails to do so.
+ llvm::Optional<DynTypedMatcher>
+ constructVariadicOperator(DynTypedMatcher::VariadicOperator Op,
+ ArrayRef<VariantMatcher> InnerMatchers) const;
+
+ protected:
+ ~MatcherOps() {}
+
+ private:
+ ast_type_traits::ASTNodeKind NodeKind;
};
/// \brief Payload interface to be specialized by each matcher type.
@@ -65,7 +125,10 @@ class VariantMatcher {
virtual ~Payload();
virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
virtual std::string getTypeAsString() const = 0;
- virtual void makeTypedMatcher(MatcherOps &Ops) const = 0;
+ virtual llvm::Optional<DynTypedMatcher>
+ getTypedMatcher(const MatcherOps &Ops) const = 0;
+ virtual bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
+ unsigned *Specificity) const = 0;
};
public:
@@ -84,9 +147,9 @@ public:
/// \brief Creates a 'variadic' operator matcher.
///
/// It will bind to the appropriate type on getTypedMatcher<T>().
- static VariantMatcher VariadicOperatorMatcher(
- ast_matchers::internal::VariadicOperatorFunction Func,
- std::vector<VariantMatcher> Args);
+ static VariantMatcher
+ VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op,
+ std::vector<VariantMatcher> Args);
/// \brief Makes the matcher the "null" matcher.
void reset();
@@ -111,9 +174,21 @@ public:
/// that can, the result would be ambiguous and false is returned.
template <class T>
bool hasTypedMatcher() const {
- TypedMatcherOps<T> Ops;
- if (Value) Value->makeTypedMatcher(Ops);
- return Ops.hasMatcher();
+ if (!Value) return false;
+ return Value->getTypedMatcher(TypedMatcherOps<T>()).hasValue();
+ }
+
+ /// \brief Determines if the contained matcher can be converted to \p Kind.
+ ///
+ /// \param Kind the requested destination type.
+ ///
+ /// \param Specificity value corresponding to the "specificity" of the
+ /// convertion.
+ bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
+ unsigned *Specificity) const {
+ if (Value)
+ return Value->isConvertibleTo(Kind, Specificity);
+ return false;
}
/// \brief Return this matcher as a \c Matcher<T>.
@@ -122,10 +197,9 @@ public:
/// Asserts that \c hasTypedMatcher<T>() is true.
template <class T>
ast_matchers::internal::Matcher<T> getTypedMatcher() const {
- TypedMatcherOps<T> Ops;
- Value->makeTypedMatcher(Ops);
- assert(Ops.hasMatcher() && "hasTypedMatcher<T>() == false");
- return Ops.matcher();
+ assert(hasTypedMatcher<T>() && "hasTypedMatcher<T>() == false");
+ return Value->getTypedMatcher(TypedMatcherOps<T>())
+ ->template convertTo<T>();
}
/// \brief String representation of the type of the value.
@@ -137,51 +211,25 @@ public:
private:
explicit VariantMatcher(Payload *Value) : Value(Value) {}
+ template <typename T> struct TypedMatcherOps;
+
class SinglePayload;
class PolymorphicPayload;
class VariadicOpPayload;
- template <typename T>
- class TypedMatcherOps : public MatcherOps {
- public:
- typedef ast_matchers::internal::Matcher<T> MatcherT;
-
- virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
- bool &IsExactMatch) const {
- IsExactMatch = Matcher.getSupportedKind().isSame(
- ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
- return Matcher.canConvertTo<T>();
- }
-
- virtual void constructFrom(const DynTypedMatcher& Matcher) {
- Out.reset(new MatcherT(Matcher.convertTo<T>()));
- }
-
- virtual void constructVariadicOperator(
- ast_matchers::internal::VariadicOperatorFunction Func,
- ArrayRef<VariantMatcher> InnerMatchers) {
- std::vector<DynTypedMatcher> DynMatchers;
- for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
- // Abort if any of the inner matchers can't be converted to
- // Matcher<T>.
- if (!InnerMatchers[i].hasTypedMatcher<T>()) {
- return;
- }
- DynMatchers.push_back(InnerMatchers[i].getTypedMatcher<T>());
- }
- Out.reset(new MatcherT(
- new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
- Func, DynMatchers)));
- }
-
- bool hasMatcher() const { return Out.get() != nullptr; }
- const MatcherT &matcher() const { return *Out; }
+ IntrusiveRefCntPtr<const Payload> Value;
+};
- private:
- std::unique_ptr<MatcherT> Out;
- };
+template <typename T>
+struct VariantMatcher::TypedMatcherOps final : VariantMatcher::MatcherOps {
+ TypedMatcherOps()
+ : MatcherOps(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()) {}
+ typedef ast_matchers::internal::Matcher<T> MatcherT;
- IntrusiveRefCntPtr<const Payload> Value;
+ DynTypedMatcher
+ convertMatcher(const DynTypedMatcher &Matcher) const override {
+ return DynTypedMatcher(Matcher.convertTo<T>());
+ }
};
/// \brief Variant value class.
@@ -228,6 +276,24 @@ public:
const VariantMatcher &getMatcher() const;
void setMatcher(const VariantMatcher &Matcher);
+ /// \brief Determines if the contained value can be converted to \p Kind.
+ ///
+ /// \param Kind the requested destination type.
+ ///
+ /// \param Specificity value corresponding to the "specificity" of the
+ /// convertion.
+ bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const;
+
+ /// \brief Determines if the contained value can be converted to any kind
+ /// in \p Kinds.
+ ///
+ /// \param Kinds the requested destination types.
+ ///
+ /// \param Specificity value corresponding to the "specificity" of the
+ /// convertion. It is the maximum specificity of all the possible
+ /// conversions.
+ bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const;
+
/// \brief String representation of the type of the value.
std::string getTypeAsString() const;
diff --git a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
index a61d9e4788..cc14c7bd33 100644
--- a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
+++ b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_ANALYSIS_CFG_REACHABILITY
-#define CLANG_ANALYSIS_CFG_REACHABILITY
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_CFGREACHABILITYANALYSIS_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_CFGREACHABILITYANALYSIS_H
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
diff --git a/include/clang/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h
index 36e07c2190..a710923398 100644
--- a/include/clang/Analysis/Analyses/Consumed.h
+++ b/include/clang/Analysis/Analyses/Consumed.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CONSUMED_H
-#define LLVM_CLANG_CONSUMED_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_CONSUMED_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_CONSUMED_H
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
index 6c6d9238e5..fcef0fc10a 100644
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_DOMINATORS_H
-#define LLVM_CLANG_DOMINATORS_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Analysis/CFG.h"
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
index 76fe9ddca6..174cce4f36 100644
--- a/include/clang/Analysis/Analyses/FormatString.h
+++ b/include/clang/Analysis/Analyses/FormatString.h
@@ -16,8 +16,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FORMAT_H
-#define LLVM_CLANG_FORMAT_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H
#include "clang/AST/CanonicalType.h"
@@ -79,6 +79,7 @@ public:
AsLongDouble, // 'L'
AsAllocate, // for '%as', GNU extension to C90 scanf
AsMAllocate, // for '%ms', GNU extension to scanf
+ AsWide, // 'w' (MSVCRT, like l but only for c, C, s, S, or Z
AsWideChar = AsLong // for '%ls', only makes sense for printf
};
@@ -154,6 +155,8 @@ public:
// ** Printf-specific **
+ ZArg, // MS extension
+
// Objective-C specific specifiers.
ObjCObjArg, // '@'
ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg,
@@ -644,6 +647,9 @@ public:
bool ParsePrintfString(FormatStringHandler &H,
const char *beg, const char *end, const LangOptions &LO,
const TargetInfo &Target);
+
+bool ParseFormatStringHasSArg(const char *beg, const char *end, const LangOptions &LO,
+ const TargetInfo &Target);
bool ParseScanfString(FormatStringHandler &H,
const char *beg, const char *end, const LangOptions &LO,
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index 784227108e..c29dd409e5 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LIVEVARIABLES_H
-#define LLVM_CLANG_LIVEVARIABLES_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H
#include "clang/AST/Decl.h"
#include "clang/Analysis/AnalysisContext.h"
diff --git a/include/clang/Analysis/Analyses/PostOrderCFGView.h b/include/clang/Analysis/Analyses/PostOrderCFGView.h
index 91bf51cd61..a1c6504275 100644
--- a/include/clang/Analysis/Analyses/PostOrderCFGView.h
+++ b/include/clang/Analysis/Analyses/PostOrderCFGView.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_POSTORDER_CFGVIEW
-#define LLVM_CLANG_POSTORDER_CFGVIEW
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_POSTORDERCFGVIEW_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_POSTORDERCFGVIEW_H
#include <vector>
//#include <algorithm>
@@ -47,17 +47,17 @@ public:
/// \brief Set the bit associated with a particular CFGBlock.
/// This is the important method for the SetType template parameter.
- bool insert(const CFGBlock *Block) {
+ std::pair<llvm::NoneType, bool> insert(const CFGBlock *Block) {
// Note that insert() is called by po_iterator, which doesn't check to
// make sure that Block is non-null. Moreover, the CFGBlock iterator will
// occasionally hand out null pointers for pruned edges, so we catch those
// here.
if (!Block)
- return false; // if an edge is trivially false.
+ return std::make_pair(None, false); // if an edge is trivially false.
if (VisitedBlockIDs.test(Block->getBlockID()))
- return false;
+ return std::make_pair(None, false);
VisitedBlockIDs.set(Block->getBlockID());
- return true;
+ return std::make_pair(None, true);
}
/// \brief Check if the bit for a CFGBlock has been already set.
diff --git a/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h b/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
index cb73850b08..c4ec2f22ec 100644
--- a/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
+++ b/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYSIS_PSEUDOCONSTANTANALYSIS
-#define LLVM_CLANG_ANALYSIS_PSEUDOCONSTANTANALYSIS
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_PSEUDOCONSTANTANALYSIS_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_PSEUDOCONSTANTANALYSIS_H
#include "clang/AST/Stmt.h"
diff --git a/include/clang/Analysis/Analyses/ReachableCode.h b/include/clang/Analysis/Analyses/ReachableCode.h
index 90a6d014f5..4c523bfc8b 100644
--- a/include/clang/Analysis/Analyses/ReachableCode.h
+++ b/include/clang/Analysis/Analyses/ReachableCode.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_REACHABLECODE_H
-#define LLVM_CLANG_REACHABLECODE_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_REACHABLECODE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_REACHABLECODE_H
#include "clang/Basic/SourceLocation.h"
diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h
index b533c1db49..458bb576f4 100644
--- a/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -16,31 +16,33 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_THREADSAFETY_H
-#define LLVM_CLANG_THREADSAFETY_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/StringRef.h"
namespace clang {
-namespace thread_safety {
+namespace threadSafety {
/// This enum distinguishes between different kinds of operations that may
/// need to be protected by locks. We use this enum in error handling.
enum ProtectedOperationKind {
POK_VarDereference, ///< Dereferencing a variable (e.g. p in *p = 5;)
POK_VarAccess, ///< Reading or writing a variable (e.g. x in x = 5;)
- POK_FunctionCall ///< Making a function call (e.g. fool())
+ POK_FunctionCall, ///< Making a function call (e.g. fool())
+ POK_PassByRef, ///< Passing a guarded variable by reference.
+ POK_PtPassByRef, ///< Passing a pt-guarded variable by reference.
};
/// This enum distinguishes between different kinds of lock actions. For
/// example, it is an error to write a variable protected by shared version of a
/// mutex.
enum LockKind {
- LK_Shared, ///< Shared/reader lock of a mutex.
+ LK_Shared, ///< Shared/reader lock of a mutex.
LK_Exclusive, ///< Exclusive/writer lock of a mutex.
- LK_Generic ///< Can be either Shared or Exclusive
+ LK_Generic ///< Can be either Shared or Exclusive
};
/// This enum distinguishes between different ways to access (read or write) a
@@ -161,6 +163,16 @@ public:
LockKind LK, SourceLocation Loc,
Name *PossibleMatch = nullptr) {}
+ /// Warn when acquiring a lock that the negative capability is not held.
+ /// \param Kind -- the capability's name parameter (role, mutex, etc).
+ /// \param LockName -- The name for the lock expression, to be printed in the
+ /// diagnostic.
+ /// \param Neg -- The name of the negative capability to be printed in the
+ /// diagnostic.
+ /// \param Loc -- The location of the protected operation.
+ virtual void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg,
+ SourceLocation Loc) {}
+
/// Warn when a function is called while an excluded mutex is locked. For
/// example, the mutex may be locked inside the function.
/// \param Kind -- the capability's name parameter (role, mutex, etc).
@@ -171,6 +183,13 @@ public:
virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
Name LockName, SourceLocation Loc) {}
+ /// Called by the analysis when starting analysis of a function.
+ /// Used to issue suggestions for changes to annotations.
+ virtual void enterFunction(const FunctionDecl *FD) {}
+
+ /// Called by the analysis when finishing analysis of a function.
+ virtual void leaveFunction(const FunctionDecl *FD) {}
+
bool issueBetaWarnings() { return IssueBetaWarnings; }
void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; }
@@ -190,5 +209,5 @@ void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
/// of access.
LockKind getLockKindFromAccessKind(AccessKind AK);
-}} // end namespace clang::thread_safety
+}} // end namespace clang::threadSafety
#endif
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
index 09c614ca3e..76d83892dd 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
@@ -19,21 +19,64 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_THREAD_SAFETY_COMMON_H
-#define LLVM_CLANG_THREAD_SAFETY_COMMON_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
+#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Basic/OperatorKinds.h"
#include <memory>
+#include <ostream>
+#include <sstream>
#include <vector>
namespace clang {
namespace threadSafety {
+
+// Various helper functions on til::SExpr
+namespace sx {
+
+inline bool equals(const til::SExpr *E1, const til::SExpr *E2) {
+ return til::EqualsComparator::compareExprs(E1, E2);
+}
+
+inline bool matches(const til::SExpr *E1, const til::SExpr *E2) {
+ // We treat a top-level wildcard as the "univsersal" lock.
+ // It matches everything for the purpose of checking locks, but not
+ // for unlocking them.
+ if (isa<til::Wildcard>(E1))
+ return isa<til::Wildcard>(E2);
+ if (isa<til::Wildcard>(E2))
+ return isa<til::Wildcard>(E1);
+
+ return til::MatchComparator::compareExprs(E1, E2);
+}
+
+inline bool partiallyMatches(const til::SExpr *E1, const til::SExpr *E2) {
+ const auto *PE1 = dyn_cast_or_null<til::Project>(E1);
+ if (!PE1)
+ return false;
+ const auto *PE2 = dyn_cast_or_null<til::Project>(E2);
+ if (!PE2)
+ return false;
+ return PE1->clangDecl() == PE2->clangDecl();
+}
+
+inline std::string toString(const til::SExpr *E) {
+ std::stringstream ss;
+ til::StdPrinter::print(E, ss);
+ return ss.str();
+}
+
+} // end namespace sx
+
+
+
// This class defines the interface of a clang CFG Visitor.
// CFGWalker will invoke the following methods.
// Note that methods are not virtual; the visitor is templatized.
@@ -206,6 +249,59 @@ private:
};
+
+
+class CapabilityExpr {
+ // TODO: move this back into ThreadSafety.cpp
+ // This is specific to thread safety. It is here because
+ // translateAttrExpr needs it, but that should be moved too.
+
+private:
+ const til::SExpr* CapExpr; ///< The capability expression.
+ bool Negated; ///< True if this is a negative capability
+
+public:
+ CapabilityExpr(const til::SExpr *E, bool Neg) : CapExpr(E), Negated(Neg) {}
+
+ const til::SExpr* sexpr() const { return CapExpr; }
+ bool negative() const { return Negated; }
+
+ CapabilityExpr operator!() const {
+ return CapabilityExpr(CapExpr, !Negated);
+ }
+
+ bool equals(const CapabilityExpr &other) const {
+ return (Negated == other.Negated) && sx::equals(CapExpr, other.CapExpr);
+ }
+
+ bool matches(const CapabilityExpr &other) const {
+ return (Negated == other.Negated) && sx::matches(CapExpr, other.CapExpr);
+ }
+
+ bool matchesUniv(const CapabilityExpr &CapE) const {
+ return isUniversal() || matches(CapE);
+ }
+
+ bool partiallyMatches(const CapabilityExpr &other) const {
+ return (Negated == other.Negated) &&
+ sx::partiallyMatches(CapExpr, other.CapExpr);
+ }
+
+ std::string toString() const {
+ if (Negated)
+ return "!" + sx::toString(CapExpr);
+ return sx::toString(CapExpr);
+ }
+
+ bool shouldIgnore() const { return CapExpr == nullptr; }
+
+ bool isInvalid() const { return sexpr() && isa<til::Undefined>(sexpr()); }
+
+ bool isUniversal() const { return sexpr() && isa<til::Wildcard>(sexpr()); }
+};
+
+
+
// Translate clang::Expr to til::SExpr.
class SExprBuilder {
public:
@@ -219,18 +315,16 @@ public:
/// should be evaluated; multiple calling contexts can be chained together
/// by the lock_returned attribute.
struct CallingContext {
+ CallingContext *Prev; // The previous context; or 0 if none.
const NamedDecl *AttrDecl; // The decl to which the attr is attached.
const Expr *SelfArg; // Implicit object argument -- e.g. 'this'
unsigned NumArgs; // Number of funArgs
const Expr *const *FunArgs; // Function arguments
- CallingContext *Prev; // The previous context; or 0 if none.
bool SelfArrow; // is Self referred to with -> or .?
- CallingContext(const NamedDecl *D = nullptr, const Expr *S = nullptr,
- unsigned N = 0, const Expr *const *A = nullptr,
- CallingContext *P = nullptr)
- : AttrDecl(D), SelfArg(S), NumArgs(N), FunArgs(A), Prev(P),
- SelfArrow(false)
+ CallingContext(CallingContext *P, const NamedDecl *D = nullptr)
+ : Prev(P), AttrDecl(D), SelfArg(nullptr),
+ NumArgs(0), FunArgs(nullptr), SelfArrow(false)
{}
};
@@ -242,6 +336,13 @@ public:
SelfVar->setKind(til::Variable::VK_SFun);
}
+ // Translate a clang expression in an attribute to a til::SExpr.
+ // Constructs the context from D, DeclExp, and SelfDecl.
+ CapabilityExpr translateAttrExpr(const Expr *AttrExp, const NamedDecl *D,
+ const Expr *DeclExp, VarDecl *SelfD=nullptr);
+
+ CapabilityExpr translateAttrExpr(const Expr *AttrExp, CallingContext *Ctx);
+
// Translate a clang statement or expression to a TIL expression.
// Also performs substitution of variables; Ctx provides the context.
// Dispatches on the type of S.
@@ -262,7 +363,8 @@ private:
CallingContext *Ctx) ;
til::SExpr *translateCXXThisExpr(const CXXThisExpr *TE, CallingContext *Ctx);
til::SExpr *translateMemberExpr(const MemberExpr *ME, CallingContext *Ctx);
- til::SExpr *translateCallExpr(const CallExpr *CE, CallingContext *Ctx);
+ til::SExpr *translateCallExpr(const CallExpr *CE, CallingContext *Ctx,
+ const Expr *SelfE = nullptr);
til::SExpr *translateCXXMemberCallExpr(const CXXMemberCallExpr *ME,
CallingContext *Ctx);
til::SExpr *translateCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE,
@@ -280,10 +382,8 @@ private:
til::SExpr *translateCastExpr(const CastExpr *CE, CallingContext *Ctx);
til::SExpr *translateArraySubscriptExpr(const ArraySubscriptExpr *E,
CallingContext *Ctx);
- til::SExpr *translateConditionalOperator(const ConditionalOperator *C,
- CallingContext *Ctx);
- til::SExpr *translateBinaryConditionalOperator(
- const BinaryConditionalOperator *C, CallingContext *Ctx);
+ til::SExpr *translateAbstractConditionalOperator(
+ const AbstractConditionalOperator *C, CallingContext *Ctx);
til::SExpr *translateDeclStmt(const DeclStmt *S, CallingContext *Ctx);
@@ -362,21 +462,24 @@ private:
void mergePhiNodesBackEdge(const CFGBlock *Blk);
private:
+ // Set to true when parsing capability expressions, which get translated
+ // inaccurately in order to hack around smart pointers etc.
+ static const bool CapabilityExprMode = true;
+
til::MemRegionRef Arena;
til::Variable *SelfVar; // Variable to use for 'this'. May be null.
- til::SCFG *Scfg;
+ til::SCFG *Scfg;
StatementMap SMap; // Map from Stmt to TIL Variables
LVarIndexMap LVarIdxMap; // Indices of clang local vars.
std::vector<til::BasicBlock *> BlockMap; // Map from clang to til BBs.
std::vector<BlockInfo> BBInfo; // Extra information per BB.
// Indexed by clang BlockID.
- std::unique_ptr<SExprBuilder::CallingContext> CallCtx; // Root calling context
LVarDefinitionMap CurrentLVarMap;
- std::vector<til::Variable*> CurrentArguments;
- std::vector<til::Variable*> CurrentInstructions;
- std::vector<til::Variable*> IncompleteArgs;
+ std::vector<til::Phi*> CurrentArguments;
+ std::vector<til::SExpr*> CurrentInstructions;
+ std::vector<til::Phi*> IncompleteArgs;
til::BasicBlock *CurrentBB;
BlockInfo *CurrentBlockInfo;
};
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
index c4f4b21aab..bc78021343 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
@@ -10,8 +10,8 @@
// that are used as part of fact-checking capability expressions.
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_THREAD_SAFETY_LOGICAL_H
-#define LLVM_CLANG_THREAD_SAFETY_LOGICAL_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYLOGICAL_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYLOGICAL_H
#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
@@ -41,13 +41,13 @@ private:
};
class Terminal : public LExpr {
- til::SExprRef Expr;
+ til::SExpr *Expr;
public:
Terminal(til::SExpr *Expr) : LExpr(LExpr::Terminal), Expr(Expr) {}
- const til::SExpr *expr() const { return Expr.get(); }
- til::SExpr *expr() { return Expr.get(); }
+ const til::SExpr *expr() const { return Expr; }
+ til::SExpr *expr() { return Expr; }
static bool classof(const LExpr *E) { return E->kind() == LExpr::Terminal; }
};
@@ -104,5 +104,5 @@ bool LExpr::implies(const LExpr *RHS) const {
}
}
-#endif // LLVM_CLANG_THREAD_SAFETY_LOGICAL_H
+#endif
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyOps.def b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
index 6ebc95dbe9..0d2458b0c8 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyOps.def
+++ b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
@@ -44,8 +44,11 @@ TIL_OPCODE_DEF(Cast)
TIL_OPCODE_DEF(SCFG)
TIL_OPCODE_DEF(BasicBlock)
TIL_OPCODE_DEF(Phi)
+
+// Terminator instructions
TIL_OPCODE_DEF(Goto)
TIL_OPCODE_DEF(Branch)
+TIL_OPCODE_DEF(Return)
// pseudo-terms
TIL_OPCODE_DEF(Identifier)
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
index 8e4299ea70..e06593c690 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
@@ -44,8 +44,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_THREAD_SAFETY_TIL_H
-#define LLVM_CLANG_THREAD_SAFETY_TIL_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTIL_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTIL_H
// All clang include dependencies for this file must be put in
// ThreadSafetyUtil.h.
@@ -63,24 +63,27 @@ namespace threadSafety {
namespace til {
+/// Enum for the different distinct classes of SExpr
enum TIL_Opcode {
#define TIL_OPCODE_DEF(X) COP_##X,
#include "ThreadSafetyOps.def"
#undef TIL_OPCODE_DEF
};
+/// Opcode for unary arithmetic operations.
enum TIL_UnaryOpcode : unsigned char {
UOP_Minus, // -
UOP_BitNot, // ~
UOP_LogicNot // !
};
+/// Opcode for binary arithmetic operations.
enum TIL_BinaryOpcode : unsigned char {
+ BOP_Add, // +
+ BOP_Sub, // -
BOP_Mul, // *
BOP_Div, // /
BOP_Rem, // %
- BOP_Add, // +
- BOP_Sub, // -
BOP_Shl, // <<
BOP_Shr, // >>
BOP_BitAnd, // &
@@ -90,37 +93,42 @@ enum TIL_BinaryOpcode : unsigned char {
BOP_Neq, // !=
BOP_Lt, // <
BOP_Leq, // <=
- BOP_LogicAnd, // &&
- BOP_LogicOr // ||
+ BOP_LogicAnd, // && (no short-circuit)
+ BOP_LogicOr // || (no short-circuit)
};
+/// Opcode for cast operations.
enum TIL_CastOpcode : unsigned char {
CAST_none = 0,
CAST_extendNum, // extend precision of numeric type
CAST_truncNum, // truncate precision of numeric type
CAST_toFloat, // convert to floating point type
CAST_toInt, // convert to integer type
+ CAST_objToPtr // convert smart pointer to pointer (C++ only)
};
const TIL_Opcode COP_Min = COP_Future;
const TIL_Opcode COP_Max = COP_Branch;
const TIL_UnaryOpcode UOP_Min = UOP_Minus;
const TIL_UnaryOpcode UOP_Max = UOP_LogicNot;
-const TIL_BinaryOpcode BOP_Min = BOP_Mul;
+const TIL_BinaryOpcode BOP_Min = BOP_Add;
const TIL_BinaryOpcode BOP_Max = BOP_LogicOr;
const TIL_CastOpcode CAST_Min = CAST_none;
const TIL_CastOpcode CAST_Max = CAST_toInt;
+/// Return the name of a unary opcode.
StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op);
+
+/// Return the name of a binary opcode.
StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op);
-// ValueTypes are data types that can actually be held in registers.
-// All variables and expressions must have a vBNF_Nonealue type.
-// Pointer types are further subdivided into the various heap-allocated
-// types, such as functions, records, etc.
-// Structured types that are passed by value (e.g. complex numbers)
-// require special handling; they use BT_ValueRef, and size ST_0.
+/// ValueTypes are data types that can actually be held in registers.
+/// All variables and expressions must have a value type.
+/// Pointer types are further subdivided into the various heap-allocated
+/// types, such as functions, records, etc.
+/// Structured types that are passed by value (e.g. complex numbers)
+/// require special handling; they use BT_ValueRef, and size ST_0.
struct ValueType {
enum BaseType : unsigned char {
BT_Void = 0,
@@ -246,8 +254,10 @@ inline ValueType ValueType::getValueType<void*>() {
}
+class BasicBlock;
+
-// Base class for AST nodes in the typed intermediate language.
+/// Base class for AST nodes in the typed intermediate language.
class SExpr {
public:
TIL_Opcode opcode() const { return static_cast<TIL_Opcode>(Opcode); }
@@ -266,71 +276,47 @@ public:
// template <class C> typename C::CType compare(CType* E, C& Cmp) {
// compare all subexpressions, following the comparator interface
// }
-
void *operator new(size_t S, MemRegionRef &R) {
return ::operator new(S, R);
}
- // SExpr objects cannot be deleted.
+ /// SExpr objects cannot be deleted.
// This declaration is public to workaround a gcc bug that breaks building
// with REQUIRES_EH=1.
void operator delete(void *) LLVM_DELETED_FUNCTION;
+ /// Returns the instruction ID for this expression.
+ /// All basic block instructions have a unique ID (i.e. virtual register).
+ unsigned id() const { return SExprID; }
+
+ /// Returns the block, if this is an instruction in a basic block,
+ /// otherwise returns null.
+ BasicBlock* block() const { return Block; }
+
+ /// Set the basic block and instruction ID for this expression.
+ void setID(BasicBlock *B, unsigned id) { Block = B; SExprID = id; }
+
protected:
- SExpr(TIL_Opcode Op) : Opcode(Op), Reserved(0), Flags(0) {}
- SExpr(const SExpr &E) : Opcode(E.Opcode), Reserved(0), Flags(E.Flags) {}
+ SExpr(TIL_Opcode Op)
+ : Opcode(Op), Reserved(0), Flags(0), SExprID(0), Block(nullptr) {}
+ SExpr(const SExpr &E)
+ : Opcode(E.Opcode), Reserved(0), Flags(E.Flags), SExprID(0),
+ Block(nullptr) {}
const unsigned char Opcode;
unsigned char Reserved;
unsigned short Flags;
+ unsigned SExprID;
+ BasicBlock* Block;
private:
SExpr() LLVM_DELETED_FUNCTION;
- // SExpr objects must be created in an arena.
+ /// SExpr objects must be created in an arena.
void *operator new(size_t) LLVM_DELETED_FUNCTION;
};
-// Class for owning references to SExprs.
-// Includes attach/detach logic for counting variable references and lazy
-// rewriting strategies.
-class SExprRef {
-public:
- SExprRef() : Ptr(nullptr) { }
- SExprRef(std::nullptr_t P) : Ptr(nullptr) { }
- SExprRef(SExprRef &&R) : Ptr(R.Ptr) { R.Ptr = nullptr; }
-
- // Defined after Variable and Future, below.
- inline SExprRef(SExpr *P);
- inline ~SExprRef();
-
- SExpr *get() { return Ptr; }
- const SExpr *get() const { return Ptr; }
-
- SExpr *operator->() { return get(); }
- const SExpr *operator->() const { return get(); }
-
- SExpr &operator*() { return *Ptr; }
- const SExpr &operator*() const { return *Ptr; }
-
- bool operator==(const SExprRef &R) const { return Ptr == R.Ptr; }
- bool operator!=(const SExprRef &R) const { return !operator==(R); }
- bool operator==(const SExpr *P) const { return Ptr == P; }
- bool operator!=(const SExpr *P) const { return !operator==(P); }
- bool operator==(std::nullptr_t) const { return Ptr == nullptr; }
- bool operator!=(std::nullptr_t) const { return Ptr != nullptr; }
-
- inline void reset(SExpr *E);
-
-private:
- inline void attach();
- inline void detach();
-
- SExpr *Ptr;
-};
-
-
// Contains various helper functions for SExprs.
namespace ThreadSafetyTIL {
inline bool isTrivial(const SExpr *E) {
@@ -342,62 +328,64 @@ namespace ThreadSafetyTIL {
// Nodes which declare variables
class Function;
class SFunction;
-class BasicBlock;
class Let;
-// A named variable, e.g. "x".
-//
-// There are two distinct places in which a Variable can appear in the AST.
-// A variable declaration introduces a new variable, and can occur in 3 places:
-// Let-expressions: (Let (x = t) u)
-// Functions: (Function (x : t) u)
-// Self-applicable functions (SFunction (x) t)
-//
-// If a variable occurs in any other location, it is a reference to an existing
-// variable declaration -- e.g. 'x' in (x * y + z). To save space, we don't
-// allocate a separate AST node for variable references; a reference is just a
-// pointer to the original declaration.
+/// A named variable, e.g. "x".
+///
+/// There are two distinct places in which a Variable can appear in the AST.
+/// A variable declaration introduces a new variable, and can occur in 3 places:
+/// Let-expressions: (Let (x = t) u)
+/// Functions: (Function (x : t) u)
+/// Self-applicable functions (SFunction (x) t)
+///
+/// If a variable occurs in any other location, it is a reference to an existing
+/// variable declaration -- e.g. 'x' in (x * y + z). To save space, we don't
+/// allocate a separate AST node for variable references; a reference is just a
+/// pointer to the original declaration.
class Variable : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Variable; }
- // Let-variable, function parameter, or self-variable
enum VariableKind {
- VK_Let,
- VK_LetBB,
- VK_Fun,
- VK_SFun
+ VK_Let, ///< Let-variable
+ VK_Fun, ///< Function parameter
+ VK_SFun ///< SFunction (self) parameter
};
- // These are defined after SExprRef contructor, below
- inline Variable(SExpr *D, const clang::ValueDecl *Cvd = nullptr);
- inline Variable(StringRef s, SExpr *D = nullptr);
- inline Variable(const Variable &Vd, SExpr *D);
+ Variable(StringRef s, SExpr *D = nullptr)
+ : SExpr(COP_Variable), Name(s), Definition(D), Cvdecl(nullptr) {
+ Flags = VK_Let;
+ }
+ Variable(SExpr *D, const clang::ValueDecl *Cvd = nullptr)
+ : SExpr(COP_Variable), Name(Cvd ? Cvd->getName() : "_x"),
+ Definition(D), Cvdecl(Cvd) {
+ Flags = VK_Let;
+ }
+ Variable(const Variable &Vd, SExpr *D) // rewrite constructor
+ : SExpr(Vd), Name(Vd.Name), Definition(D), Cvdecl(Vd.Cvdecl) {
+ Flags = Vd.kind();
+ }
+ /// Return the kind of variable (let, function param, or self)
VariableKind kind() const { return static_cast<VariableKind>(Flags); }
- const StringRef name() const { return Name; }
- const clang::ValueDecl *clangDecl() const { return Cvdecl; }
-
- // Returns the definition (for let vars) or type (for parameter & self vars)
- SExpr *definition() { return Definition.get(); }
- const SExpr *definition() const { return Definition.get(); }
+ /// Return the name of the variable, if any.
+ StringRef name() const { return Name; }
- void attachVar() const { ++NumUses; }
- void detachVar() const { assert(NumUses > 0); --NumUses; }
+ /// Return the clang declaration for this variable, if any.
+ const clang::ValueDecl *clangDecl() const { return Cvdecl; }
- unsigned getID() const { return Id; }
- unsigned getBlockID() const { return BlockID; }
+ /// Return the definition of the variable.
+ /// For let-vars, this is the setting expression.
+ /// For function and self parameters, it is the type of the variable.
+ SExpr *definition() { return Definition; }
+ const SExpr *definition() const { return Definition; }
- void setName(StringRef S) { Name = S; }
- void setID(unsigned Bid, unsigned I) {
- BlockID = static_cast<unsigned short>(Bid);
- Id = static_cast<unsigned short>(I);
- }
- void setClangDecl(const clang::ValueDecl *VD) { Cvdecl = VD; }
- void setDefinition(SExpr *E);
+ void setName(StringRef S) { Name = S; }
void setKind(VariableKind K) { Flags = K; }
+ void setDefinition(SExpr *E) { Definition = E; }
+ void setClangDecl(const clang::ValueDecl *VD) { Cvdecl = VD; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -405,7 +393,8 @@ public:
return Vs.reduceVariableRef(this);
}
- template <class C> typename C::CType compare(Variable* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Variable* E, C& Cmp) const {
return Cmp.compareVariableRefs(this, E);
}
@@ -416,17 +405,13 @@ private:
friend class Let;
StringRef Name; // The name of the variable.
- SExprRef Definition; // The TIL type or definition
+ SExpr* Definition; // The TIL type or definition
const clang::ValueDecl *Cvdecl; // The clang declaration for this variable.
-
- unsigned short BlockID;
- unsigned short Id;
- mutable unsigned NumUses;
};
-// Placeholder for an expression that has not yet been created.
-// Used to implement lazy copy and rewriting strategies.
+/// Placeholder for an expression that has not yet been created.
+/// Used to implement lazy copy and rewriting strategies.
class Future : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Future; }
@@ -437,25 +422,17 @@ public:
FS_done
};
- Future() :
- SExpr(COP_Future), Status(FS_pending), Result(nullptr), Location(nullptr)
- {}
+ Future() : SExpr(COP_Future), Status(FS_pending), Result(nullptr) {}
+
private:
virtual ~Future() LLVM_DELETED_FUNCTION;
-public:
-
- // Registers the location in the AST where this future is stored.
- // Forcing the future will automatically update the AST.
- static inline void registerLocation(SExprRef *Member) {
- if (Future *F = dyn_cast_or_null<Future>(Member->get()))
- F->Location = Member;
- }
+public:
// A lazy rewriting strategy should subclass Future and override this method.
- virtual SExpr *create() { return nullptr; }
+ virtual SExpr *compute() { return nullptr; }
// Return the result of this future if it exists, otherwise return null.
- SExpr *maybeGetResult() {
+ SExpr *maybeGetResult() const {
return Result;
}
@@ -463,8 +440,7 @@ public:
SExpr *result() {
switch (Status) {
case FS_pending:
- force();
- return Result;
+ return force();
case FS_evaluating:
return nullptr; // infinite loop; illegal recursion.
case FS_done:
@@ -478,88 +454,22 @@ public:
return Vs.traverse(Result, Ctx);
}
- template <class C> typename C::CType compare(Future* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Future* E, C& Cmp) const {
if (!Result || !E->Result)
return Cmp.comparePointers(this, E);
return Cmp.compare(Result, E->Result);
}
private:
- // Force the future.
- inline void force();
+ SExpr* force();
FutureStatus Status;
SExpr *Result;
- SExprRef *Location;
};
-inline void SExprRef::attach() {
- if (!Ptr)
- return;
-
- TIL_Opcode Op = Ptr->opcode();
- if (Op == COP_Variable) {
- cast<Variable>(Ptr)->attachVar();
- } else if (Op == COP_Future) {
- cast<Future>(Ptr)->registerLocation(this);
- }
-}
-
-inline void SExprRef::detach() {
- if (Ptr && Ptr->opcode() == COP_Variable) {
- cast<Variable>(Ptr)->detachVar();
- }
-}
-
-inline SExprRef::SExprRef(SExpr *P) : Ptr(P) {
- attach();
-}
-
-inline SExprRef::~SExprRef() {
- detach();
-}
-
-inline void SExprRef::reset(SExpr *P) {
- detach();
- Ptr = P;
- attach();
-}
-
-
-inline Variable::Variable(StringRef s, SExpr *D)
- : SExpr(COP_Variable), Name(s), Definition(D), Cvdecl(nullptr),
- BlockID(0), Id(0), NumUses(0) {
- Flags = VK_Let;
-}
-
-inline Variable::Variable(SExpr *D, const clang::ValueDecl *Cvd)
- : SExpr(COP_Variable), Name(Cvd ? Cvd->getName() : "_x"),
- Definition(D), Cvdecl(Cvd), BlockID(0), Id(0), NumUses(0) {
- Flags = VK_Let;
-}
-
-inline Variable::Variable(const Variable &Vd, SExpr *D) // rewrite constructor
- : SExpr(Vd), Name(Vd.Name), Definition(D), Cvdecl(Vd.Cvdecl),
- BlockID(0), Id(0), NumUses(0) {
- Flags = Vd.kind();
-}
-
-inline void Variable::setDefinition(SExpr *E) {
- Definition.reset(E);
-}
-
-void Future::force() {
- Status = FS_evaluating;
- SExpr *R = create();
- Result = R;
- if (Location)
- Location->reset(R);
- Status = FS_done;
-}
-
-
-// Placeholder for C++ expressions that cannot be represented in the TIL.
+/// Placeholder for expressions that cannot be represented in the TIL.
class Undefined : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Undefined; }
@@ -572,8 +482,9 @@ public:
return Vs.reduceUndefined(*this);
}
- template <class C> typename C::CType compare(Undefined* E, C& Cmp) {
- return Cmp.comparePointers(Cstmt, E->Cstmt);
+ template <class C>
+ typename C::CType compare(const Undefined* E, C& Cmp) const {
+ return Cmp.trueResult();
}
private:
@@ -581,7 +492,7 @@ private:
};
-// Placeholder for a wildcard that matches any other expression.
+/// Placeholder for a wildcard that matches any other expression.
class Wildcard : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Wildcard; }
@@ -593,7 +504,8 @@ public:
return Vs.reduceWildcard(*this);
}
- template <class C> typename C::CType compare(Wildcard* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Wildcard* E, C& Cmp) const {
return Cmp.trueResult();
}
};
@@ -626,9 +538,10 @@ public:
template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx);
- template <class C> typename C::CType compare(Literal* E, C& Cmp) {
- // TODO -- use value, not pointer equality
- return Cmp.comparePointers(Cexpr, E->Cexpr);
+ template <class C>
+ typename C::CType compare(const Literal* E, C& Cmp) const {
+ // TODO: defer actual comparison to LiteralT
+ return Cmp.trueResult();
}
private:
@@ -710,8 +623,8 @@ typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) {
}
-// Literal pointer to an object allocated in memory.
-// At compile time, pointer literals are represented by symbolic names.
+/// A Literal pointer to an object allocated in memory.
+/// At compile time, pointer literals are represented by symbolic names.
class LiteralPtr : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_LiteralPtr; }
@@ -727,7 +640,8 @@ public:
return Vs.reduceLiteralPtr(*this);
}
- template <class C> typename C::CType compare(LiteralPtr* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const LiteralPtr* E, C& Cmp) const {
return Cmp.comparePointers(Cvdecl, E->Cvdecl);
}
@@ -736,9 +650,9 @@ private:
};
-// A function -- a.k.a. lambda abstraction.
-// Functions with multiple arguments are created by currying,
-// e.g. (function (x: Int) (function (y: Int) (add x y)))
+/// A function -- a.k.a. lambda abstraction.
+/// Functions with multiple arguments are created by currying,
+/// e.g. (Function (x: Int) (Function (y: Int) (Code { return x + y })))
class Function : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Function; }
@@ -755,8 +669,8 @@ public:
Variable *variableDecl() { return VarDecl; }
const Variable *variableDecl() const { return VarDecl; }
- SExpr *body() { return Body.get(); }
- const SExpr *body() const { return Body.get(); }
+ SExpr *body() { return Body; }
+ const SExpr *body() const { return Body; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -769,7 +683,8 @@ public:
return Vs.reduceFunction(*this, Nvd, E1);
}
- template <class C> typename C::CType compare(Function* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Function* E, C& Cmp) const {
typename C::CType Ct =
Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
if (Cmp.notTrue(Ct))
@@ -782,13 +697,13 @@ public:
private:
Variable *VarDecl;
- SExprRef Body;
+ SExpr* Body;
};
-// A self-applicable function.
-// A self-applicable function can be applied to itself. It's useful for
-// implementing objects and late binding
+/// A self-applicable function.
+/// A self-applicable function can be applied to itself. It's useful for
+/// implementing objects and late binding.
class SFunction : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_SFunction; }
@@ -797,20 +712,20 @@ public:
: SExpr(COP_SFunction), VarDecl(Vd), Body(B) {
assert(Vd->Definition == nullptr);
Vd->setKind(Variable::VK_SFun);
- Vd->Definition.reset(this);
+ Vd->Definition = this;
}
SFunction(const SFunction &F, Variable *Vd, SExpr *B) // rewrite constructor
: SExpr(F), VarDecl(Vd), Body(B) {
assert(Vd->Definition == nullptr);
Vd->setKind(Variable::VK_SFun);
- Vd->Definition.reset(this);
+ Vd->Definition = this;
}
Variable *variableDecl() { return VarDecl; }
const Variable *variableDecl() const { return VarDecl; }
- SExpr *body() { return Body.get(); }
- const SExpr *body() const { return Body.get(); }
+ SExpr *body() { return Body; }
+ const SExpr *body() const { return Body; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -824,7 +739,8 @@ public:
return Vs.reduceSFunction(*this, Nvd, E1);
}
- template <class C> typename C::CType compare(SFunction* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const SFunction* E, C& Cmp) const {
Cmp.enterScope(variableDecl(), E->variableDecl());
typename C::CType Ct = Cmp.compare(body(), E->body());
Cmp.leaveScope();
@@ -833,11 +749,11 @@ public:
private:
Variable *VarDecl;
- SExprRef Body;
+ SExpr* Body;
};
-// A block of code -- e.g. the body of a function.
+/// A block of code -- e.g. the body of a function.
class Code : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Code; }
@@ -846,11 +762,11 @@ public:
Code(const Code &C, SExpr *T, SExpr *B) // rewrite constructor
: SExpr(C), ReturnType(T), Body(B) {}
- SExpr *returnType() { return ReturnType.get(); }
- const SExpr *returnType() const { return ReturnType.get(); }
+ SExpr *returnType() { return ReturnType; }
+ const SExpr *returnType() const { return ReturnType; }
- SExpr *body() { return Body.get(); }
- const SExpr *body() const { return Body.get(); }
+ SExpr *body() { return Body; }
+ const SExpr *body() const { return Body; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -859,7 +775,8 @@ public:
return Vs.reduceCode(*this, Nt, Nb);
}
- template <class C> typename C::CType compare(Code* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Code* E, C& Cmp) const {
typename C::CType Ct = Cmp.compare(returnType(), E->returnType());
if (Cmp.notTrue(Ct))
return Ct;
@@ -867,12 +784,12 @@ public:
}
private:
- SExprRef ReturnType;
- SExprRef Body;
+ SExpr* ReturnType;
+ SExpr* Body;
};
-// A typed, writable location in memory
+/// A typed, writable location in memory
class Field : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Field; }
@@ -881,11 +798,11 @@ public:
Field(const Field &C, SExpr *R, SExpr *B) // rewrite constructor
: SExpr(C), Range(R), Body(B) {}
- SExpr *range() { return Range.get(); }
- const SExpr *range() const { return Range.get(); }
+ SExpr *range() { return Range; }
+ const SExpr *range() const { return Range; }
- SExpr *body() { return Body.get(); }
- const SExpr *body() const { return Body.get(); }
+ SExpr *body() { return Body; }
+ const SExpr *body() const { return Body; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -894,7 +811,8 @@ public:
return Vs.reduceField(*this, Nr, Nb);
}
- template <class C> typename C::CType compare(Field* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Field* E, C& Cmp) const {
typename C::CType Ct = Cmp.compare(range(), E->range());
if (Cmp.notTrue(Ct))
return Ct;
@@ -902,12 +820,16 @@ public:
}
private:
- SExprRef Range;
- SExprRef Body;
+ SExpr* Range;
+ SExpr* Body;
};
-// Apply an argument to a function
+/// Apply an argument to a function.
+/// Note that this does not actually call the function. Functions are curried,
+/// so this returns a closure in which the first parameter has been applied.
+/// Once all parameters have been applied, Call can be used to invoke the
+/// function.
class Apply : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Apply; }
@@ -917,11 +839,11 @@ public:
: SExpr(A), Fun(F), Arg(Ar)
{}
- SExpr *fun() { return Fun.get(); }
- const SExpr *fun() const { return Fun.get(); }
+ SExpr *fun() { return Fun; }
+ const SExpr *fun() const { return Fun; }
- SExpr *arg() { return Arg.get(); }
- const SExpr *arg() const { return Arg.get(); }
+ SExpr *arg() { return Arg; }
+ const SExpr *arg() const { return Arg; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -930,7 +852,8 @@ public:
return Vs.reduceApply(*this, Nf, Na);
}
- template <class C> typename C::CType compare(Apply* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Apply* E, C& Cmp) const {
typename C::CType Ct = Cmp.compare(fun(), E->fun());
if (Cmp.notTrue(Ct))
return Ct;
@@ -938,12 +861,12 @@ public:
}
private:
- SExprRef Fun;
- SExprRef Arg;
+ SExpr* Fun;
+ SExpr* Arg;
};
-// Apply a self-argument to a self-applicable function
+/// Apply a self-argument to a self-applicable function.
class SApply : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_SApply; }
@@ -952,23 +875,24 @@ public:
SApply(SApply &A, SExpr *Sf, SExpr *Ar = nullptr) // rewrite constructor
: SExpr(A), Sfun(Sf), Arg(Ar) {}
- SExpr *sfun() { return Sfun.get(); }
- const SExpr *sfun() const { return Sfun.get(); }
+ SExpr *sfun() { return Sfun; }
+ const SExpr *sfun() const { return Sfun; }
- SExpr *arg() { return Arg.get() ? Arg.get() : Sfun.get(); }
- const SExpr *arg() const { return Arg.get() ? Arg.get() : Sfun.get(); }
+ SExpr *arg() { return Arg ? Arg : Sfun; }
+ const SExpr *arg() const { return Arg ? Arg : Sfun; }
- bool isDelegation() const { return Arg == nullptr; }
+ bool isDelegation() const { return Arg != nullptr; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
auto Nf = Vs.traverse(Sfun, Vs.subExprCtx(Ctx));
- typename V::R_SExpr Na = Arg.get() ? Vs.traverse(Arg, Vs.subExprCtx(Ctx))
+ typename V::R_SExpr Na = Arg ? Vs.traverse(Arg, Vs.subExprCtx(Ctx))
: nullptr;
return Vs.reduceSApply(*this, Nf, Na);
}
- template <class C> typename C::CType compare(SApply* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const SApply* E, C& Cmp) const {
typename C::CType Ct = Cmp.compare(sfun(), E->sfun());
if (Cmp.notTrue(Ct) || (!arg() && !E->arg()))
return Ct;
@@ -976,12 +900,12 @@ public:
}
private:
- SExprRef Sfun;
- SExprRef Arg;
+ SExpr* Sfun;
+ SExpr* Arg;
};
-// Project a named slot from a C++ struct or class.
+/// Project a named slot from a C++ struct or class.
class Project : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Project; }
@@ -989,17 +913,23 @@ public:
Project(SExpr *R, StringRef SName)
: SExpr(COP_Project), Rec(R), SlotName(SName), Cvdecl(nullptr)
{ }
- Project(SExpr *R, clang::ValueDecl *Cvd)
+ Project(SExpr *R, const clang::ValueDecl *Cvd)
: SExpr(COP_Project), Rec(R), SlotName(Cvd->getName()), Cvdecl(Cvd)
{ }
Project(const Project &P, SExpr *R)
: SExpr(P), Rec(R), SlotName(P.SlotName), Cvdecl(P.Cvdecl)
{ }
- SExpr *record() { return Rec.get(); }
- const SExpr *record() const { return Rec.get(); }
+ SExpr *record() { return Rec; }
+ const SExpr *record() const { return Rec; }
+
+ const clang::ValueDecl *clangDecl() const { return Cvdecl; }
- const clang::ValueDecl *clangValueDecl() const { return Cvdecl; }
+ bool isArrow() const { return (Flags & 0x01) != 0; }
+ void setArrow(bool b) {
+ if (b) Flags |= 0x01;
+ else Flags &= 0xFFFE;
+ }
StringRef slotName() const {
if (Cvdecl)
@@ -1014,7 +944,8 @@ public:
return Vs.reduceProject(*this, Nr);
}
- template <class C> typename C::CType compare(Project* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Project* E, C& Cmp) const {
typename C::CType Ct = Cmp.compare(record(), E->record());
if (Cmp.notTrue(Ct))
return Ct;
@@ -1022,13 +953,13 @@ public:
}
private:
- SExprRef Rec;
+ SExpr* Rec;
StringRef SlotName;
- clang::ValueDecl *Cvdecl;
+ const clang::ValueDecl *Cvdecl;
};
-// Call a function (after all arguments have been applied).
+/// Call a function (after all arguments have been applied).
class Call : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
@@ -1037,8 +968,8 @@ public:
: SExpr(COP_Call), Target(T), Cexpr(Ce) {}
Call(const Call &C, SExpr *T) : SExpr(C), Target(T), Cexpr(C.Cexpr) {}
- SExpr *target() { return Target.get(); }
- const SExpr *target() const { return Target.get(); }
+ SExpr *target() { return Target; }
+ const SExpr *target() const { return Target; }
const clang::CallExpr *clangCallExpr() const { return Cexpr; }
@@ -1048,17 +979,18 @@ public:
return Vs.reduceCall(*this, Nt);
}
- template <class C> typename C::CType compare(Call* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Call* E, C& Cmp) const {
return Cmp.compare(target(), E->target());
}
private:
- SExprRef Target;
+ SExpr* Target;
const clang::CallExpr *Cexpr;
};
-// Allocate memory for a new value on the heap or stack.
+/// Allocate memory for a new value on the heap or stack.
class Alloc : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
@@ -1073,8 +1005,8 @@ public:
AllocKind kind() const { return static_cast<AllocKind>(Flags); }
- SExpr *dataType() { return Dtype.get(); }
- const SExpr *dataType() const { return Dtype.get(); }
+ SExpr *dataType() { return Dtype; }
+ const SExpr *dataType() const { return Dtype; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -1082,7 +1014,8 @@ public:
return Vs.reduceAlloc(*this, Nd);
}
- template <class C> typename C::CType compare(Alloc* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Alloc* E, C& Cmp) const {
typename C::CType Ct = Cmp.compareIntegers(kind(), E->kind());
if (Cmp.notTrue(Ct))
return Ct;
@@ -1090,11 +1023,11 @@ public:
}
private:
- SExprRef Dtype;
+ SExpr* Dtype;
};
-// Load a value from memory.
+/// Load a value from memory.
class Load : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Load; }
@@ -1102,8 +1035,8 @@ public:
Load(SExpr *P) : SExpr(COP_Load), Ptr(P) {}
Load(const Load &L, SExpr *P) : SExpr(L), Ptr(P) {}
- SExpr *pointer() { return Ptr.get(); }
- const SExpr *pointer() const { return Ptr.get(); }
+ SExpr *pointer() { return Ptr; }
+ const SExpr *pointer() const { return Ptr; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -1111,17 +1044,18 @@ public:
return Vs.reduceLoad(*this, Np);
}
- template <class C> typename C::CType compare(Load* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Load* E, C& Cmp) const {
return Cmp.compare(pointer(), E->pointer());
}
private:
- SExprRef Ptr;
+ SExpr* Ptr;
};
-// Store a value to memory.
-// Source is a pointer, destination is the value to store.
+/// Store a value to memory.
+/// The destination is a pointer to a field, the source is the value to store.
class Store : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Store; }
@@ -1129,11 +1063,11 @@ public:
Store(SExpr *P, SExpr *V) : SExpr(COP_Store), Dest(P), Source(V) {}
Store(const Store &S, SExpr *P, SExpr *V) : SExpr(S), Dest(P), Source(V) {}
- SExpr *destination() { return Dest.get(); } // Address to store to
- const SExpr *destination() const { return Dest.get(); }
+ SExpr *destination() { return Dest; } // Address to store to
+ const SExpr *destination() const { return Dest; }
- SExpr *source() { return Source.get(); } // Value to store
- const SExpr *source() const { return Source.get(); }
+ SExpr *source() { return Source; } // Value to store
+ const SExpr *source() const { return Source; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -1142,7 +1076,8 @@ public:
return Vs.reduceStore(*this, Np, Nv);
}
- template <class C> typename C::CType compare(Store* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Store* E, C& Cmp) const {
typename C::CType Ct = Cmp.compare(destination(), E->destination());
if (Cmp.notTrue(Ct))
return Ct;
@@ -1150,13 +1085,13 @@ public:
}
private:
- SExprRef Dest;
- SExprRef Source;
+ SExpr* Dest;
+ SExpr* Source;
};
-// If p is a reference to an array, then first(p) is a reference to the first
-// element. The usual array notation p[i] becomes first(p + i).
+/// If p is a reference to an array, then p[i] is a reference to the i'th
+/// element of the array.
class ArrayIndex : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayIndex; }
@@ -1165,11 +1100,11 @@ public:
ArrayIndex(const ArrayIndex &E, SExpr *A, SExpr *N)
: SExpr(E), Array(A), Index(N) {}
- SExpr *array() { return Array.get(); }
- const SExpr *array() const { return Array.get(); }
+ SExpr *array() { return Array; }
+ const SExpr *array() const { return Array; }
- SExpr *index() { return Index.get(); }
- const SExpr *index() const { return Index.get(); }
+ SExpr *index() { return Index; }
+ const SExpr *index() const { return Index; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -1178,7 +1113,8 @@ public:
return Vs.reduceArrayIndex(*this, Na, Ni);
}
- template <class C> typename C::CType compare(ArrayIndex* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const ArrayIndex* E, C& Cmp) const {
typename C::CType Ct = Cmp.compare(array(), E->array());
if (Cmp.notTrue(Ct))
return Ct;
@@ -1186,14 +1122,14 @@ public:
}
private:
- SExprRef Array;
- SExprRef Index;
+ SExpr* Array;
+ SExpr* Index;
};
-// Pointer arithmetic, restricted to arrays only.
-// If p is a reference to an array, then p + n, where n is an integer, is
-// a reference to a subarray.
+/// Pointer arithmetic, restricted to arrays only.
+/// If p is a reference to an array, then p + n, where n is an integer, is
+/// a reference to a subarray.
class ArrayAdd : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayAdd; }
@@ -1202,11 +1138,11 @@ public:
ArrayAdd(const ArrayAdd &E, SExpr *A, SExpr *N)
: SExpr(E), Array(A), Index(N) {}
- SExpr *array() { return Array.get(); }
- const SExpr *array() const { return Array.get(); }
+ SExpr *array() { return Array; }
+ const SExpr *array() const { return Array; }
- SExpr *index() { return Index.get(); }
- const SExpr *index() const { return Index.get(); }
+ SExpr *index() { return Index; }
+ const SExpr *index() const { return Index; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -1215,7 +1151,8 @@ public:
return Vs.reduceArrayAdd(*this, Na, Ni);
}
- template <class C> typename C::CType compare(ArrayAdd* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const ArrayAdd* E, C& Cmp) const {
typename C::CType Ct = Cmp.compare(array(), E->array());
if (Cmp.notTrue(Ct))
return Ct;
@@ -1223,12 +1160,13 @@ public:
}
private:
- SExprRef Array;
- SExprRef Index;
+ SExpr* Array;
+ SExpr* Index;
};
-// Simple unary operation -- e.g. !, ~, etc.
+/// Simple arithmetic unary operations, e.g. negate and not.
+/// These operations have no side-effects.
class UnaryOp : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_UnaryOp; }
@@ -1242,8 +1180,8 @@ public:
return static_cast<TIL_UnaryOpcode>(Flags);
}
- SExpr *expr() { return Expr0.get(); }
- const SExpr *expr() const { return Expr0.get(); }
+ SExpr *expr() { return Expr0; }
+ const SExpr *expr() const { return Expr0; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -1251,7 +1189,8 @@ public:
return Vs.reduceUnaryOp(*this, Ne);
}
- template <class C> typename C::CType compare(UnaryOp* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const UnaryOp* E, C& Cmp) const {
typename C::CType Ct =
Cmp.compareIntegers(unaryOpcode(), E->unaryOpcode());
if (Cmp.notTrue(Ct))
@@ -1260,11 +1199,12 @@ public:
}
private:
- SExprRef Expr0;
+ SExpr* Expr0;
};
-// Simple binary operation -- e.g. +, -, etc.
+/// Simple arithmetic binary operations, e.g. +, -, etc.
+/// These operations have no side effects.
class BinaryOp : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_BinaryOp; }
@@ -1282,11 +1222,11 @@ public:
return static_cast<TIL_BinaryOpcode>(Flags);
}
- SExpr *expr0() { return Expr0.get(); }
- const SExpr *expr0() const { return Expr0.get(); }
+ SExpr *expr0() { return Expr0; }
+ const SExpr *expr0() const { return Expr0; }
- SExpr *expr1() { return Expr1.get(); }
- const SExpr *expr1() const { return Expr1.get(); }
+ SExpr *expr1() { return Expr1; }
+ const SExpr *expr1() const { return Expr1; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -1295,7 +1235,8 @@ public:
return Vs.reduceBinaryOp(*this, Ne0, Ne1);
}
- template <class C> typename C::CType compare(BinaryOp* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const BinaryOp* E, C& Cmp) const {
typename C::CType Ct =
Cmp.compareIntegers(binaryOpcode(), E->binaryOpcode());
if (Cmp.notTrue(Ct))
@@ -1307,12 +1248,14 @@ public:
}
private:
- SExprRef Expr0;
- SExprRef Expr1;
+ SExpr* Expr0;
+ SExpr* Expr1;
};
-// Cast expression
+/// Cast expressions.
+/// Cast expressions are essentially unary operations, but we treat them
+/// as a distinct AST node because they only change the type of the result.
class Cast : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Cast; }
@@ -1324,8 +1267,8 @@ public:
return static_cast<TIL_CastOpcode>(Flags);
}
- SExpr *expr() { return Expr0.get(); }
- const SExpr *expr() const { return Expr0.get(); }
+ SExpr *expr() { return Expr0; }
+ const SExpr *expr() const { return Expr0; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -1333,7 +1276,8 @@ public:
return Vs.reduceCast(*this, Ne);
}
- template <class C> typename C::CType compare(Cast* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Cast* E, C& Cmp) const {
typename C::CType Ct =
Cmp.compareIntegers(castOpcode(), E->castOpcode());
if (Cmp.notTrue(Ct))
@@ -1342,16 +1286,18 @@ public:
}
private:
- SExprRef Expr0;
+ SExpr* Expr0;
};
class SCFG;
+/// Phi Node, for code in SSA form.
+/// Each Phi node has an array of possible values that it can take,
+/// depending on where control flow comes from.
class Phi : public SExpr {
public:
- // TODO: change to SExprRef
typedef SimpleArray<SExpr *> ValArray;
// In minimal SSA form, all Phi nodes are MultiVal.
@@ -1365,9 +1311,12 @@ public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Phi; }
- Phi() : SExpr(COP_Phi) {}
- Phi(MemRegionRef A, unsigned Nvals) : SExpr(COP_Phi), Values(A, Nvals) {}
- Phi(const Phi &P, ValArray &&Vs) : SExpr(P), Values(std::move(Vs)) {}
+ Phi()
+ : SExpr(COP_Phi), Cvdecl(nullptr) {}
+ Phi(MemRegionRef A, unsigned Nvals)
+ : SExpr(COP_Phi), Values(A, Nvals), Cvdecl(nullptr) {}
+ Phi(const Phi &P, ValArray &&Vs)
+ : SExpr(P), Values(std::move(Vs)), Cvdecl(nullptr) {}
const ValArray &values() const { return Values; }
ValArray &values() { return Values; }
@@ -1375,6 +1324,12 @@ public:
Status status() const { return static_cast<Status>(Flags); }
void setStatus(Status s) { Flags = s; }
+ /// Return the clang declaration of the variable for this Phi node, if any.
+ const clang::ValueDecl *clangDecl() const { return Cvdecl; }
+
+ /// Set the clang variable associated with this Phi node.
+ void setClangDecl(const clang::ValueDecl *Cvd) { Cvdecl = Cvd; }
+
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
typename V::template Container<typename V::R_SExpr>
@@ -1386,72 +1341,268 @@ public:
return Vs.reducePhi(*this, Nvs);
}
- template <class C> typename C::CType compare(Phi *E, C &Cmp) {
+ template <class C>
+ typename C::CType compare(const Phi *E, C &Cmp) const {
// TODO: implement CFG comparisons
return Cmp.comparePointers(this, E);
}
private:
ValArray Values;
+ const clang::ValueDecl* Cvdecl;
+};
+
+
+/// Base class for basic block terminators: Branch, Goto, and Return.
+class Terminator : public SExpr {
+public:
+ static bool classof(const SExpr *E) {
+ return E->opcode() >= COP_Goto && E->opcode() <= COP_Return;
+ }
+
+protected:
+ Terminator(TIL_Opcode Op) : SExpr(Op) {}
+ Terminator(const SExpr &E) : SExpr(E) {}
+
+public:
+ /// Return the list of basic blocks that this terminator can branch to.
+ ArrayRef<BasicBlock*> successors();
+
+ ArrayRef<BasicBlock*> successors() const {
+ return const_cast<const Terminator*>(this)->successors();
+ }
+};
+
+
+/// Jump to another basic block.
+/// A goto instruction is essentially a tail-recursive call into another
+/// block. In addition to the block pointer, it specifies an index into the
+/// phi nodes of that block. The index can be used to retrieve the "arguments"
+/// of the call.
+class Goto : public Terminator {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Goto; }
+
+ Goto(BasicBlock *B, unsigned I)
+ : Terminator(COP_Goto), TargetBlock(B), Index(I) {}
+ Goto(const Goto &G, BasicBlock *B, unsigned I)
+ : Terminator(COP_Goto), TargetBlock(B), Index(I) {}
+
+ const BasicBlock *targetBlock() const { return TargetBlock; }
+ BasicBlock *targetBlock() { return TargetBlock; }
+
+ /// Returns the index into the
+ unsigned index() const { return Index; }
+
+ /// Return the list of basic blocks that this terminator can branch to.
+ ArrayRef<BasicBlock*> successors() {
+ return ArrayRef<BasicBlock*>(&TargetBlock, 1);
+ }
+
+ template <class V>
+ typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+ BasicBlock *Ntb = Vs.reduceBasicBlockRef(TargetBlock);
+ return Vs.reduceGoto(*this, Ntb);
+ }
+
+ template <class C>
+ typename C::CType compare(const Goto *E, C &Cmp) const {
+ // TODO: implement CFG comparisons
+ return Cmp.comparePointers(this, E);
+ }
+
+private:
+ BasicBlock *TargetBlock;
+ unsigned Index;
+};
+
+
+/// A conditional branch to two other blocks.
+/// Note that unlike Goto, Branch does not have an index. The target blocks
+/// must be child-blocks, and cannot have Phi nodes.
+class Branch : public Terminator {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Branch; }
+
+ Branch(SExpr *C, BasicBlock *T, BasicBlock *E)
+ : Terminator(COP_Branch), Condition(C) {
+ Branches[0] = T;
+ Branches[1] = E;
+ }
+ Branch(const Branch &Br, SExpr *C, BasicBlock *T, BasicBlock *E)
+ : Terminator(Br), Condition(C) {
+ Branches[0] = T;
+ Branches[1] = E;
+ }
+
+ const SExpr *condition() const { return Condition; }
+ SExpr *condition() { return Condition; }
+
+ const BasicBlock *thenBlock() const { return Branches[0]; }
+ BasicBlock *thenBlock() { return Branches[0]; }
+
+ const BasicBlock *elseBlock() const { return Branches[1]; }
+ BasicBlock *elseBlock() { return Branches[1]; }
+
+ /// Return the list of basic blocks that this terminator can branch to.
+ ArrayRef<BasicBlock*> successors() {
+ return ArrayRef<BasicBlock*>(Branches, 2);
+ }
+
+ template <class V>
+ typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+ auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx));
+ BasicBlock *Ntb = Vs.reduceBasicBlockRef(Branches[0]);
+ BasicBlock *Nte = Vs.reduceBasicBlockRef(Branches[1]);
+ return Vs.reduceBranch(*this, Nc, Ntb, Nte);
+ }
+
+ template <class C>
+ typename C::CType compare(const Branch *E, C &Cmp) const {
+ // TODO: implement CFG comparisons
+ return Cmp.comparePointers(this, E);
+ }
+
+private:
+ SExpr* Condition;
+ BasicBlock *Branches[2];
};
-// A basic block is part of an SCFG, and can be treated as a function in
-// continuation passing style. It consists of a sequence of phi nodes, which
-// are "arguments" to the function, followed by a sequence of instructions.
-// Both arguments and instructions define new variables. It ends with a
-// branch or goto to another basic block in the same SCFG.
+/// Return from the enclosing function, passing the return value to the caller.
+/// Only the exit block should end with a return statement.
+class Return : public Terminator {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Return; }
+
+ Return(SExpr* Rval) : Terminator(COP_Return), Retval(Rval) {}
+ Return(const Return &R, SExpr* Rval) : Terminator(R), Retval(Rval) {}
+
+ /// Return an empty list.
+ ArrayRef<BasicBlock*> successors() {
+ return ArrayRef<BasicBlock*>();
+ }
+
+ SExpr *returnValue() { return Retval; }
+ const SExpr *returnValue() const { return Retval; }
+
+ template <class V>
+ typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+ auto Ne = Vs.traverse(Retval, Vs.subExprCtx(Ctx));
+ return Vs.reduceReturn(*this, Ne);
+ }
+
+ template <class C>
+ typename C::CType compare(const Return *E, C &Cmp) const {
+ return Cmp.compare(Retval, E->Retval);
+ }
+
+private:
+ SExpr* Retval;
+};
+
+
+inline ArrayRef<BasicBlock*> Terminator::successors() {
+ switch (opcode()) {
+ case COP_Goto: return cast<Goto>(this)->successors();
+ case COP_Branch: return cast<Branch>(this)->successors();
+ case COP_Return: return cast<Return>(this)->successors();
+ default:
+ return ArrayRef<BasicBlock*>();
+ }
+}
+
+
+/// A basic block is part of an SCFG. It can be treated as a function in
+/// continuation passing style. A block consists of a sequence of phi nodes,
+/// which are "arguments" to the function, followed by a sequence of
+/// instructions. It ends with a Terminator, which is a Branch or Goto to
+/// another basic block in the same SCFG.
class BasicBlock : public SExpr {
public:
- typedef SimpleArray<Variable*> VarArray;
+ typedef SimpleArray<SExpr*> InstrArray;
typedef SimpleArray<BasicBlock*> BlockArray;
+ // TopologyNodes are used to overlay tree structures on top of the CFG,
+ // such as dominator and postdominator trees. Each block is assigned an
+ // ID in the tree according to a depth-first search. Tree traversals are
+ // always up, towards the parents.
+ struct TopologyNode {
+ TopologyNode() : NodeID(0), SizeOfSubTree(0), Parent(nullptr) {}
+
+ bool isParentOf(const TopologyNode& OtherNode) {
+ return OtherNode.NodeID > NodeID &&
+ OtherNode.NodeID < NodeID + SizeOfSubTree;
+ }
+
+ bool isParentOfOrEqual(const TopologyNode& OtherNode) {
+ return OtherNode.NodeID >= NodeID &&
+ OtherNode.NodeID < NodeID + SizeOfSubTree;
+ }
+
+ int NodeID;
+ int SizeOfSubTree; // Includes this node, so must be > 1.
+ BasicBlock *Parent; // Pointer to parent.
+ };
+
static bool classof(const SExpr *E) { return E->opcode() == COP_BasicBlock; }
- explicit BasicBlock(MemRegionRef A, BasicBlock* P = nullptr)
+ explicit BasicBlock(MemRegionRef A)
: SExpr(COP_BasicBlock), Arena(A), CFGPtr(nullptr), BlockID(0),
- Parent(P), Terminator(nullptr)
- { }
- BasicBlock(BasicBlock &B, VarArray &&As, VarArray &&Is, SExpr *T)
- : SExpr(COP_BasicBlock), Arena(B.Arena), CFGPtr(nullptr), BlockID(0),
- Parent(nullptr), Args(std::move(As)), Instrs(std::move(Is)),
- Terminator(T)
- { }
+ Visited(0), TermInstr(nullptr) {}
+ BasicBlock(BasicBlock &B, MemRegionRef A, InstrArray &&As, InstrArray &&Is,
+ Terminator *T)
+ : SExpr(COP_BasicBlock), Arena(A), CFGPtr(nullptr), BlockID(0),Visited(0),
+ Args(std::move(As)), Instrs(std::move(Is)), TermInstr(T) {}
+
+ /// Returns the block ID. Every block has a unique ID in the CFG.
+ int blockID() const { return BlockID; }
- unsigned blockID() const { return BlockID; }
- unsigned numPredecessors() const { return Predecessors.size(); }
+ /// Returns the number of predecessors.
+ size_t numPredecessors() const { return Predecessors.size(); }
+ size_t numSuccessors() const { return successors().size(); }
const SCFG* cfg() const { return CFGPtr; }
SCFG* cfg() { return CFGPtr; }
- const BasicBlock *parent() const { return Parent; }
- BasicBlock *parent() { return Parent; }
+ const BasicBlock *parent() const { return DominatorNode.Parent; }
+ BasicBlock *parent() { return DominatorNode.Parent; }
- const VarArray &arguments() const { return Args; }
- VarArray &arguments() { return Args; }
+ const InstrArray &arguments() const { return Args; }
+ InstrArray &arguments() { return Args; }
- const VarArray &instructions() const { return Instrs; }
- VarArray &instructions() { return Instrs; }
+ InstrArray &instructions() { return Instrs; }
+ const InstrArray &instructions() const { return Instrs; }
- const BlockArray &predecessors() const { return Predecessors; }
+ /// Returns a list of predecessors.
+ /// The order of predecessors in the list is important; each phi node has
+ /// exactly one argument for each precessor, in the same order.
BlockArray &predecessors() { return Predecessors; }
+ const BlockArray &predecessors() const { return Predecessors; }
+
+ ArrayRef<BasicBlock*> successors() { return TermInstr->successors(); }
+ ArrayRef<BasicBlock*> successors() const { return TermInstr->successors(); }
+
+ const Terminator *terminator() const { return TermInstr; }
+ Terminator *terminator() { return TermInstr; }
- const SExpr *terminator() const { return Terminator.get(); }
- SExpr *terminator() { return Terminator.get(); }
+ void setTerminator(Terminator *E) { TermInstr = E; }
- void setBlockID(unsigned i) { BlockID = i; }
- void setParent(BasicBlock *P) { Parent = P; }
- void setTerminator(SExpr *E) { Terminator.reset(E); }
+ bool Dominates(const BasicBlock &Other) {
+ return DominatorNode.isParentOfOrEqual(Other.DominatorNode);
+ }
+
+ bool PostDominates(const BasicBlock &Other) {
+ return PostDominatorNode.isParentOfOrEqual(Other.PostDominatorNode);
+ }
- // Add a new argument. V must define a phi-node.
- void addArgument(Variable *V) {
- V->setKind(Variable::VK_LetBB);
+ /// Add a new argument.
+ void addArgument(Phi *V) {
Args.reserveCheck(1, Arena);
Args.push_back(V);
}
- // Add a new instruction.
- void addInstruction(Variable *V) {
- V->setKind(Variable::VK_LetBB);
+ /// Add a new instruction.
+ void addInstruction(SExpr *V) {
Instrs.reserveCheck(1, Arena);
Instrs.push_back(V);
}
@@ -1468,34 +1619,29 @@ public:
// Reserve space for NumPreds predecessors, including space in phi nodes.
void reservePredecessors(unsigned NumPreds);
- // Return the index of BB, or Predecessors.size if BB is not a predecessor.
+ /// Return the index of BB, or Predecessors.size if BB is not a predecessor.
unsigned findPredecessorIndex(const BasicBlock *BB) const {
auto I = std::find(Predecessors.cbegin(), Predecessors.cend(), BB);
return std::distance(Predecessors.cbegin(), I);
}
- // Set id numbers for variables.
- void renumberVars();
-
template <class V>
typename V::R_BasicBlock traverse(V &Vs, typename V::R_Ctx Ctx) {
- typename V::template Container<Variable*> Nas(Vs, Args.size());
- typename V::template Container<Variable*> Nis(Vs, Instrs.size());
+ typename V::template Container<SExpr*> Nas(Vs, Args.size());
+ typename V::template Container<SExpr*> Nis(Vs, Instrs.size());
// Entering the basic block should do any scope initialization.
Vs.enterBasicBlock(*this);
- for (auto *A : Args) {
- auto Ne = Vs.traverse(A->Definition, Vs.subExprCtx(Ctx));
- Variable *Nvd = Vs.enterScope(*A, Ne);
- Nas.push_back(Nvd);
+ for (auto *E : Args) {
+ auto Ne = Vs.traverse(E, Vs.subExprCtx(Ctx));
+ Nas.push_back(Ne);
}
- for (auto *I : Instrs) {
- auto Ne = Vs.traverse(I->Definition, Vs.subExprCtx(Ctx));
- Variable *Nvd = Vs.enterScope(*I, Ne);
- Nis.push_back(Nvd);
+ for (auto *E : Instrs) {
+ auto Ne = Vs.traverse(E, Vs.subExprCtx(Ctx));
+ Nis.push_back(Ne);
}
- auto Nt = Vs.traverse(Terminator, Ctx);
+ auto Nt = Vs.traverse(TermInstr, Ctx);
// Exiting the basic block should handle any scope cleanup.
Vs.exitBasicBlock(*this);
@@ -1503,7 +1649,8 @@ public:
return Vs.reduceBasicBlock(*this, Nas, Nis, Nt);
}
- template <class C> typename C::CType compare(BasicBlock *E, C &Cmp) {
+ template <class C>
+ typename C::CType compare(const BasicBlock *E, C &Cmp) const {
// TODO: implement CFG comparisons
return Cmp.comparePointers(this, E);
}
@@ -1511,22 +1658,32 @@ public:
private:
friend class SCFG;
- MemRegionRef Arena;
+ int renumberInstrs(int id); // assign unique ids to all instructions
+ int topologicalSort(SimpleArray<BasicBlock*>& Blocks, int ID);
+ int topologicalFinalSort(SimpleArray<BasicBlock*>& Blocks, int ID);
+ void computeDominator();
+ void computePostDominator();
- SCFG *CFGPtr; // The CFG that contains this block.
- unsigned BlockID; // unique id for this BB in the containing CFG
- BasicBlock *Parent; // The parent block is the enclosing lexical scope.
- // The parent dominates this block.
- BlockArray Predecessors; // Predecessor blocks in the CFG.
- VarArray Args; // Phi nodes. One argument per predecessor.
- VarArray Instrs; // Instructions.
- SExprRef Terminator; // Branch or Goto
+private:
+ MemRegionRef Arena; // The arena used to allocate this block.
+ SCFG *CFGPtr; // The CFG that contains this block.
+ int BlockID : 31; // unique id for this BB in the containing CFG.
+ // IDs are in topological order.
+ bool Visited : 1; // Bit to determine if a block has been visited
+ // during a traversal.
+ BlockArray Predecessors; // Predecessor blocks in the CFG.
+ InstrArray Args; // Phi nodes. One argument per predecessor.
+ InstrArray Instrs; // Instructions.
+ Terminator* TermInstr; // Terminating instruction
+
+ TopologyNode DominatorNode; // The dominator tree
+ TopologyNode PostDominatorNode; // The post-dominator tree
};
-// An SCFG is a control-flow graph. It consists of a set of basic blocks, each
-// of which terminates in a branch to another basic block. There is one
-// entry point, and one exit point.
+/// An SCFG is a control-flow graph. It consists of a set of basic blocks,
+/// each of which terminates in a branch to another basic block. There is one
+/// entry point, and one exit point.
class SCFG : public SExpr {
public:
typedef SimpleArray<BasicBlock *> BlockArray;
@@ -1537,20 +1694,29 @@ public:
SCFG(MemRegionRef A, unsigned Nblocks)
: SExpr(COP_SCFG), Arena(A), Blocks(A, Nblocks),
- Entry(nullptr), Exit(nullptr) {
- Entry = new (A) BasicBlock(A, nullptr);
- Exit = new (A) BasicBlock(A, Entry);
- auto *V = new (A) Variable(new (A) Phi());
+ Entry(nullptr), Exit(nullptr), NumInstructions(0), Normal(false) {
+ Entry = new (A) BasicBlock(A);
+ Exit = new (A) BasicBlock(A);
+ auto *V = new (A) Phi();
Exit->addArgument(V);
+ Exit->setTerminator(new (A) Return(V));
add(Entry);
add(Exit);
}
SCFG(const SCFG &Cfg, BlockArray &&Ba) // steals memory from Ba
: SExpr(COP_SCFG), Arena(Cfg.Arena), Blocks(std::move(Ba)),
- Entry(nullptr), Exit(nullptr) {
+ Entry(nullptr), Exit(nullptr), NumInstructions(0), Normal(false) {
// TODO: set entry and exit!
}
+ /// Return true if this CFG is valid.
+ bool valid() const { return Entry && Exit && Blocks.size() > 0; }
+
+ /// Return true if this CFG has been normalized.
+ /// After normalization, blocks are in topological order, and block and
+ /// instruction IDs have been assigned.
+ bool normal() const { return Normal; }
+
iterator begin() { return Blocks.begin(); }
iterator end() { return Blocks.end(); }
@@ -1565,9 +1731,17 @@ public:
const BasicBlock *exit() const { return Exit; }
BasicBlock *exit() { return Exit; }
+ /// Return the number of blocks in the CFG.
+ /// Block::blockID() will return a number less than numBlocks();
+ size_t numBlocks() const { return Blocks.size(); }
+
+ /// Return the total number of instructions in the CFG.
+ /// This is useful for building instruction side-tables;
+ /// A call to SExpr::id() will return a number less than numInstructions().
+ unsigned numInstructions() { return NumInstructions; }
+
inline void add(BasicBlock *BB) {
- assert(BB->CFGPtr == nullptr || BB->CFGPtr == this);
- BB->setBlockID(Blocks.size());
+ assert(BB->CFGPtr == nullptr);
BB->CFGPtr = this;
Blocks.reserveCheck(1, Arena);
Blocks.push_back(BB);
@@ -1576,13 +1750,13 @@ public:
void setEntry(BasicBlock *BB) { Entry = BB; }
void setExit(BasicBlock *BB) { Exit = BB; }
- // Set varable ids in all blocks.
- void renumberVars();
+ void computeNormalForm();
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
Vs.enterCFG(*this);
typename V::template Container<BasicBlock *> Bbs(Vs, Blocks.size());
+
for (auto *B : Blocks) {
Bbs.push_back( B->traverse(Vs, Vs.subExprCtx(Ctx)) );
}
@@ -1590,100 +1764,28 @@ public:
return Vs.reduceSCFG(*this, Bbs);
}
- template <class C> typename C::CType compare(SCFG *E, C &Cmp) {
- // TODO -- implement CFG comparisons
+ template <class C>
+ typename C::CType compare(const SCFG *E, C &Cmp) const {
+ // TODO: implement CFG comparisons
return Cmp.comparePointers(this, E);
}
private:
+ void renumberInstrs(); // assign unique ids to all instructions
+
+private:
MemRegionRef Arena;
BlockArray Blocks;
BasicBlock *Entry;
BasicBlock *Exit;
+ unsigned NumInstructions;
+ bool Normal;
};
-class Goto : public SExpr {
-public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Goto; }
-
- Goto(BasicBlock *B, unsigned I)
- : SExpr(COP_Goto), TargetBlock(B), Index(I) {}
- Goto(const Goto &G, BasicBlock *B, unsigned I)
- : SExpr(COP_Goto), TargetBlock(B), Index(I) {}
- const BasicBlock *targetBlock() const { return TargetBlock; }
- BasicBlock *targetBlock() { return TargetBlock; }
-
- unsigned index() const { return Index; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- BasicBlock *Ntb = Vs.reduceBasicBlockRef(TargetBlock);
- return Vs.reduceGoto(*this, Ntb);
- }
-
- template <class C> typename C::CType compare(Goto *E, C &Cmp) {
- // TODO -- implement CFG comparisons
- return Cmp.comparePointers(this, E);
- }
-
-private:
- BasicBlock *TargetBlock;
- unsigned Index; // Index into Phi nodes of target block.
-};
-
-
-class Branch : public SExpr {
-public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Branch; }
-
- Branch(SExpr *C, BasicBlock *T, BasicBlock *E, unsigned TI, unsigned EI)
- : SExpr(COP_Branch), Condition(C), ThenBlock(T), ElseBlock(E),
- ThenIndex(TI), ElseIndex(EI)
- {}
- Branch(const Branch &Br, SExpr *C, BasicBlock *T, BasicBlock *E,
- unsigned TI, unsigned EI)
- : SExpr(COP_Branch), Condition(C), ThenBlock(T), ElseBlock(E),
- ThenIndex(TI), ElseIndex(EI)
- {}
-
- const SExpr *condition() const { return Condition; }
- SExpr *condition() { return Condition; }
-
- const BasicBlock *thenBlock() const { return ThenBlock; }
- BasicBlock *thenBlock() { return ThenBlock; }
-
- const BasicBlock *elseBlock() const { return ElseBlock; }
- BasicBlock *elseBlock() { return ElseBlock; }
-
- unsigned thenIndex() const { return ThenIndex; }
- unsigned elseIndex() const { return ElseIndex; }
-
- template <class V>
- typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
- auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx));
- BasicBlock *Ntb = Vs.reduceBasicBlockRef(ThenBlock);
- BasicBlock *Nte = Vs.reduceBasicBlockRef(ElseBlock);
- return Vs.reduceBranch(*this, Nc, Ntb, Nte);
- }
-
- template <class C> typename C::CType compare(Branch *E, C &Cmp) {
- // TODO -- implement CFG comparisons
- return Cmp.comparePointers(this, E);
- }
-
-private:
- SExpr *Condition;
- BasicBlock *ThenBlock;
- BasicBlock *ElseBlock;
- unsigned ThenIndex;
- unsigned ElseIndex;
-};
-
-
-// An identifier, e.g. 'foo' or 'x'.
-// This is a pseduo-term; it will be lowered to a variable or projection.
+/// An identifier, e.g. 'foo' or 'x'.
+/// This is a pseduo-term; it will be lowered to a variable or projection.
class Identifier : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Identifier; }
@@ -1698,7 +1800,8 @@ public:
return Vs.reduceIdentifier(*this);
}
- template <class C> typename C::CType compare(Identifier* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Identifier* E, C& Cmp) const {
return Cmp.compareStrings(name(), E->name());
}
@@ -1707,8 +1810,8 @@ private:
};
-// An if-then-else expression.
-// This is a pseduo-term; it will be lowered to a branch in a CFG.
+/// An if-then-else expression.
+/// This is a pseduo-term; it will be lowered to a branch in a CFG.
class IfThenElse : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_IfThenElse; }
@@ -1720,14 +1823,14 @@ public:
: SExpr(I), Condition(C), ThenExpr(T), ElseExpr(E)
{ }
- SExpr *condition() { return Condition.get(); } // Address to store to
- const SExpr *condition() const { return Condition.get(); }
+ SExpr *condition() { return Condition; } // Address to store to
+ const SExpr *condition() const { return Condition; }
- SExpr *thenExpr() { return ThenExpr.get(); } // Value to store
- const SExpr *thenExpr() const { return ThenExpr.get(); }
+ SExpr *thenExpr() { return ThenExpr; } // Value to store
+ const SExpr *thenExpr() const { return ThenExpr; }
- SExpr *elseExpr() { return ElseExpr.get(); } // Value to store
- const SExpr *elseExpr() const { return ElseExpr.get(); }
+ SExpr *elseExpr() { return ElseExpr; } // Value to store
+ const SExpr *elseExpr() const { return ElseExpr; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -1737,7 +1840,8 @@ public:
return Vs.reduceIfThenElse(*this, Nc, Nt, Ne);
}
- template <class C> typename C::CType compare(IfThenElse* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const IfThenElse* E, C& Cmp) const {
typename C::CType Ct = Cmp.compare(condition(), E->condition());
if (Cmp.notTrue(Ct))
return Ct;
@@ -1748,14 +1852,14 @@ public:
}
private:
- SExprRef Condition;
- SExprRef ThenExpr;
- SExprRef ElseExpr;
+ SExpr* Condition;
+ SExpr* ThenExpr;
+ SExpr* ElseExpr;
};
-// A let-expression, e.g. let x=t; u.
-// This is a pseduo-term; it will be lowered to instructions in a CFG.
+/// A let-expression, e.g. let x=t; u.
+/// This is a pseduo-term; it will be lowered to instructions in a CFG.
class Let : public SExpr {
public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Let; }
@@ -1770,8 +1874,8 @@ public:
Variable *variableDecl() { return VarDecl; }
const Variable *variableDecl() const { return VarDecl; }
- SExpr *body() { return Body.get(); }
- const SExpr *body() const { return Body.get(); }
+ SExpr *body() { return Body; }
+ const SExpr *body() const { return Body; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -1784,7 +1888,8 @@ public:
return Vs.reduceLet(*this, Nvd, E1);
}
- template <class C> typename C::CType compare(Let* E, C& Cmp) {
+ template <class C>
+ typename C::CType compare(const Let* E, C& Cmp) const {
typename C::CType Ct =
Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
if (Cmp.notTrue(Ct))
@@ -1797,17 +1902,18 @@ public:
private:
Variable *VarDecl;
- SExprRef Body;
+ SExpr* Body;
};
-SExpr *getCanonicalVal(SExpr *E);
-void simplifyIncompleteArg(Variable *V, til::Phi *Ph);
+const SExpr *getCanonicalVal(const SExpr *E);
+SExpr* simplifyToCanonicalVal(SExpr *E);
+void simplifyIncompleteArg(til::Phi *Ph);
} // end namespace til
} // end namespace threadSafety
} // end namespace clang
-#endif // LLVM_CLANG_THREAD_SAFETY_TIL_H
+#endif
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
index bc1490b4a4..541f0bfd17 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
@@ -14,11 +14,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
-#define LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTRAVERSE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTRAVERSE_H
#include "ThreadSafetyTIL.h"
+#include <ostream>
+
namespace clang {
namespace threadSafety {
namespace til {
@@ -56,11 +58,16 @@ public:
// Traverse an expression -- returning a result of type R_SExpr.
// Override this method to do something for every expression, regardless
// of which kind it is.
- typename R::R_SExpr traverse(SExprRef &E, typename R::R_Ctx Ctx) {
- return traverse(E.get(), Ctx);
+ // E is a reference, so this can be use for in-place updates.
+ // The type T must be a subclass of SExpr.
+ template <class T>
+ typename R::R_SExpr traverse(T* &E, typename R::R_Ctx Ctx) {
+ return traverseSExpr(E, Ctx);
}
- typename R::R_SExpr traverse(SExpr *E, typename R::R_Ctx Ctx) {
+ // Override this method to do something for every expression.
+ // Does not allow in-place updates.
+ typename R::R_SExpr traverseSExpr(SExpr *E, typename R::R_Ctx Ctx) {
return traverseByCase(E, Ctx);
}
@@ -73,6 +80,7 @@ public:
#include "ThreadSafetyOps.def"
#undef TIL_OPCODE_DEF
}
+ return self()->reduceNull();
}
// Traverse e, by static dispatch on the type "X" of e.
@@ -90,10 +98,10 @@ public:
class SimpleReducerBase {
public:
enum TraversalKind {
- TRV_Normal,
- TRV_Decl,
- TRV_Lazy,
- TRV_Type
+ TRV_Normal, // ordinary subexpressions
+ TRV_Decl, // declarations (e.g. function bodies)
+ TRV_Lazy, // expressions that require lazy evaluation
+ TRV_Type // type expressions
};
// R_Ctx defines a "context" for the traversal, which encodes information
@@ -145,153 +153,6 @@ protected:
};
-// Implements a traversal that makes a deep copy of an SExpr.
-// The default behavior of reduce##X(...) is to create a copy of the original.
-// Subclasses can override reduce##X to implement non-destructive rewriting
-// passes.
-template<class Self>
-class CopyReducer : public Traversal<Self, CopyReducerBase>,
- public CopyReducerBase {
-public:
- CopyReducer(MemRegionRef A) : CopyReducerBase(A) {}
-
-public:
- R_SExpr reduceNull() {
- return nullptr;
- }
- // R_SExpr reduceFuture(...) is never used.
-
- R_SExpr reduceUndefined(Undefined &Orig) {
- return new (Arena) Undefined(Orig);
- }
- R_SExpr reduceWildcard(Wildcard &Orig) {
- return new (Arena) Wildcard(Orig);
- }
-
- R_SExpr reduceLiteral(Literal &Orig) {
- return new (Arena) Literal(Orig);
- }
- template<class T>
- R_SExpr reduceLiteralT(LiteralT<T> &Orig) {
- return new (Arena) LiteralT<T>(Orig);
- }
- R_SExpr reduceLiteralPtr(LiteralPtr &Orig) {
- return new (Arena) LiteralPtr(Orig);
- }
-
- R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0) {
- return new (Arena) Function(Orig, Nvd, E0);
- }
- R_SExpr reduceSFunction(SFunction &Orig, Variable *Nvd, R_SExpr E0) {
- return new (Arena) SFunction(Orig, Nvd, E0);
- }
- R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1) {
- return new (Arena) Code(Orig, E0, E1);
- }
- R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1) {
- return new (Arena) Field(Orig, E0, E1);
- }
-
- R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1) {
- return new (Arena) Apply(Orig, E0, E1);
- }
- R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1) {
- return new (Arena) SApply(Orig, E0, E1);
- }
- R_SExpr reduceProject(Project &Orig, R_SExpr E0) {
- return new (Arena) Project(Orig, E0);
- }
- R_SExpr reduceCall(Call &Orig, R_SExpr E0) {
- return new (Arena) Call(Orig, E0);
- }
-
- R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0) {
- return new (Arena) Alloc(Orig, E0);
- }
- R_SExpr reduceLoad(Load &Orig, R_SExpr E0) {
- return new (Arena) Load(Orig, E0);
- }
- R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1) {
- return new (Arena) Store(Orig, E0, E1);
- }
- R_SExpr reduceArrayIndex(ArrayIndex &Orig, R_SExpr E0, R_SExpr E1) {
- return new (Arena) ArrayIndex(Orig, E0, E1);
- }
- R_SExpr reduceArrayAdd(ArrayAdd &Orig, R_SExpr E0, R_SExpr E1) {
- return new (Arena) ArrayAdd(Orig, E0, E1);
- }
- R_SExpr reduceUnaryOp(UnaryOp &Orig, R_SExpr E0) {
- return new (Arena) UnaryOp(Orig, E0);
- }
- R_SExpr reduceBinaryOp(BinaryOp &Orig, R_SExpr E0, R_SExpr E1) {
- return new (Arena) BinaryOp(Orig, E0, E1);
- }
- R_SExpr reduceCast(Cast &Orig, R_SExpr E0) {
- return new (Arena) Cast(Orig, E0);
- }
-
- R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> &Bbs) {
- return nullptr; // FIXME: implement CFG rewriting
- }
- R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As,
- Container<Variable *> &Is, R_SExpr T) {
- return nullptr; // FIXME: implement CFG rewriting
- }
- R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) {
- return new (Arena) Phi(Orig, std::move(As.Elems));
- }
- R_SExpr reduceGoto(Goto &Orig, BasicBlock *B) {
- return new (Arena) Goto(Orig, B, 0); // FIXME: set index
- }
- R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) {
- return new (Arena) Branch(O, C, B0, B1, 0, 0); // FIXME: set indices
- }
-
- R_SExpr reduceIdentifier(Identifier &Orig) {
- return new (Arena) Identifier(Orig);
- }
- R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E) {
- return new (Arena) IfThenElse(Orig, C, T, E);
- }
- R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B) {
- return new (Arena) Let(Orig, Nvd, B);
- }
-
- // Create a new variable from orig, and push it onto the lexical scope.
- Variable *enterScope(Variable &Orig, R_SExpr E0) {
- return new (Arena) Variable(Orig, E0);
- }
- // Exit the lexical scope of orig.
- void exitScope(const Variable &Orig) {}
-
- void enterCFG(SCFG &Cfg) {}
- void exitCFG(SCFG &Cfg) {}
- void enterBasicBlock(BasicBlock &BB) {}
- void exitBasicBlock(BasicBlock &BB) {}
-
- // Map Variable references to their rewritten definitions.
- Variable *reduceVariableRef(Variable *Ovd) { return Ovd; }
-
- // Map BasicBlock references to their rewritten definitions.
- BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; }
-};
-
-
-class SExprCopier : public CopyReducer<SExprCopier> {
-public:
- typedef SExpr *R_SExpr;
-
- SExprCopier(MemRegionRef A) : CopyReducer(A) { }
-
- // Create a copy of e in region a.
- static SExpr *copy(SExpr *E, MemRegionRef A) {
- SExprCopier Copier(A);
- return Copier.traverse(E, TRV_Normal);
- }
-};
-
-
-
// Base class for visit traversals.
class VisitReducerBase : public SimpleReducerBase {
public:
@@ -366,8 +227,8 @@ public:
R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> Bbs) {
return Bbs.Success;
}
- R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As,
- Container<Variable *> &Is, R_SExpr T) {
+ R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container<R_SExpr> &As,
+ Container<R_SExpr> &Is, R_SExpr T) {
return (As.Success && Is.Success && T);
}
R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) {
@@ -379,6 +240,9 @@ public:
R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) {
return C;
}
+ R_SExpr reduceReturn(Return &O, R_SExpr E) {
+ return E;
+ }
R_SExpr reduceIdentifier(Identifier &Orig) {
return true;
@@ -423,7 +287,7 @@ protected:
Self *self() { return reinterpret_cast<Self *>(this); }
public:
- bool compareByCase(SExpr *E1, SExpr* E2) {
+ bool compareByCase(const SExpr *E1, const SExpr* E2) {
switch (E1->opcode()) {
#define TIL_OPCODE_DEF(X) \
case COP_##X: \
@@ -431,6 +295,7 @@ public:
#include "ThreadSafetyOps.def"
#undef TIL_OPCODE_DEF
}
+ return false;
}
};
@@ -449,38 +314,86 @@ public:
bool compareStrings (StringRef s, StringRef r) { return s == r; }
bool comparePointers(const void* P, const void* Q) { return P == Q; }
- bool compare(SExpr *E1, SExpr* E2) {
+ bool compare(const SExpr *E1, const SExpr* E2) {
if (E1->opcode() != E2->opcode())
return false;
return compareByCase(E1, E2);
}
// TODO -- handle alpha-renaming of variables
- void enterScope(Variable* V1, Variable* V2) { }
+ void enterScope(const Variable* V1, const Variable* V2) { }
void leaveScope() { }
- bool compareVariableRefs(Variable* V1, Variable* V2) {
+ bool compareVariableRefs(const Variable* V1, const Variable* V2) {
return V1 == V2;
}
- static bool compareExprs(SExpr *E1, SExpr* E2) {
+ static bool compareExprs(const SExpr *E1, const SExpr* E2) {
EqualsComparator Eq;
return Eq.compare(E1, E2);
}
};
+
+class MatchComparator : public Comparator<MatchComparator> {
+public:
+ // Result type for the comparison, e.g. bool for simple equality,
+ // or int for lexigraphic comparison (-1, 0, 1). Must have one value which
+ // denotes "true".
+ typedef bool CType;
+
+ CType trueResult() { return true; }
+ bool notTrue(CType ct) { return !ct; }
+
+ bool compareIntegers(unsigned i, unsigned j) { return i == j; }
+ bool compareStrings (StringRef s, StringRef r) { return s == r; }
+ bool comparePointers(const void* P, const void* Q) { return P == Q; }
+
+ bool compare(const SExpr *E1, const SExpr* E2) {
+ // Wildcards match anything.
+ if (E1->opcode() == COP_Wildcard || E2->opcode() == COP_Wildcard)
+ return true;
+ // otherwise normal equality.
+ if (E1->opcode() != E2->opcode())
+ return false;
+ return compareByCase(E1, E2);
+ }
+
+ // TODO -- handle alpha-renaming of variables
+ void enterScope(const Variable* V1, const Variable* V2) { }
+ void leaveScope() { }
+
+ bool compareVariableRefs(const Variable* V1, const Variable* V2) {
+ return V1 == V2;
+ }
+
+ static bool compareExprs(const SExpr *E1, const SExpr* E2) {
+ MatchComparator Matcher;
+ return Matcher.compare(E1, E2);
+ }
+};
+
+
+
+// inline std::ostream& operator<<(std::ostream& SS, StringRef R) {
+// return SS.write(R.data(), R.size());
+// }
+
// Pretty printer for TIL expressions
template <typename Self, typename StreamType>
class PrettyPrinter {
private:
bool Verbose; // Print out additional information
bool Cleanup; // Omit redundant decls.
+ bool CStyle; // Print exprs in C-like syntax.
public:
- PrettyPrinter(bool V = false, bool C = true) : Verbose(V), Cleanup(C) { }
+ PrettyPrinter(bool V = false, bool C = true, bool CS = true)
+ : Verbose(V), Cleanup(C), CStyle(CS)
+ {}
- static void print(SExpr *E, StreamType &SS) {
+ static void print(const SExpr *E, StreamType &SS) {
Self printer;
printer.printSExpr(E, SS, Prec_MAX);
}
@@ -502,7 +415,7 @@ protected:
static const unsigned Prec_MAX = 6;
// Return the precedence of a given node, for use in pretty printing.
- unsigned precedence(SExpr *E) {
+ unsigned precedence(const SExpr *E) {
switch (E->opcode()) {
case COP_Future: return Prec_Atom;
case COP_Undefined: return Prec_Atom;
@@ -529,13 +442,14 @@ protected:
case COP_UnaryOp: return Prec_Unary;
case COP_BinaryOp: return Prec_Binary;
- case COP_Cast: return Prec_Unary;
+ case COP_Cast: return Prec_Atom;
case COP_SCFG: return Prec_Decl;
case COP_BasicBlock: return Prec_MAX;
case COP_Phi: return Prec_Atom;
case COP_Goto: return Prec_Atom;
case COP_Branch: return Prec_Atom;
+ case COP_Return: return Prec_Other;
case COP_Identifier: return Prec_Atom;
case COP_IfThenElse: return Prec_Other;
@@ -544,22 +458,29 @@ protected:
return Prec_MAX;
}
- void printBlockLabel(StreamType & SS, BasicBlock *BB, unsigned index) {
+ void printBlockLabel(StreamType & SS, const BasicBlock *BB, int index) {
if (!BB) {
SS << "BB_null";
return;
}
SS << "BB_";
SS << BB->blockID();
- SS << ":";
- SS << index;
+ if (index >= 0) {
+ SS << ":";
+ SS << index;
+ }
}
- void printSExpr(SExpr *E, StreamType &SS, unsigned P) {
+
+ void printSExpr(const SExpr *E, StreamType &SS, unsigned P, bool Sub=true) {
if (!E) {
self()->printNull(SS);
return;
}
+ if (Sub && E->block() && E->opcode() != COP_Variable) {
+ SS << "_x" << E->id();
+ return;
+ }
if (self()->precedence(E) > P) {
// Wrap expr in () if necessary.
SS << "(";
@@ -582,28 +503,28 @@ protected:
SS << "#null";
}
- void printFuture(Future *E, StreamType &SS) {
+ void printFuture(const Future *E, StreamType &SS) {
self()->printSExpr(E->maybeGetResult(), SS, Prec_Atom);
}
- void printUndefined(Undefined *E, StreamType &SS) {
+ void printUndefined(const Undefined *E, StreamType &SS) {
SS << "#undefined";
}
- void printWildcard(Wildcard *E, StreamType &SS) {
- SS << "_";
+ void printWildcard(const Wildcard *E, StreamType &SS) {
+ SS << "*";
}
template<class T>
- void printLiteralT(LiteralT<T> *E, StreamType &SS) {
+ void printLiteralT(const LiteralT<T> *E, StreamType &SS) {
SS << E->value();
}
- void printLiteralT(LiteralT<uint8_t> *E, StreamType &SS) {
+ void printLiteralT(const LiteralT<uint8_t> *E, StreamType &SS) {
SS << "'" << E->value() << "'";
}
- void printLiteral(Literal *E, StreamType &SS) {
+ void printLiteral(const Literal *E, StreamType &SS) {
if (E->clangExpr()) {
SS << getSourceLiteralString(E->clangExpr());
return;
@@ -685,25 +606,18 @@ protected:
SS << "#lit";
}
- void printLiteralPtr(LiteralPtr *E, StreamType &SS) {
+ void printLiteralPtr(const LiteralPtr *E, StreamType &SS) {
SS << E->clangDecl()->getNameAsString();
}
- void printVariable(Variable *V, StreamType &SS, bool IsVarDecl = false) {
- if (!IsVarDecl && Cleanup) {
- SExpr* E = getCanonicalVal(V);
- if (E != V) {
- printSExpr(E, SS, Prec_Atom);
- return;
- }
- }
- if (V->kind() == Variable::VK_LetBB)
- SS << V->name() << V->getBlockID() << "_" << V->getID();
+ void printVariable(const Variable *V, StreamType &SS, bool IsVarDecl=false) {
+ if (CStyle && V->kind() == Variable::VK_SFun)
+ SS << "this";
else
- SS << V->name() << V->getID();
+ SS << V->name() << V->id();
}
- void printFunction(Function *E, StreamType &SS, unsigned sugared = 0) {
+ void printFunction(const Function *E, StreamType &SS, unsigned sugared = 0) {
switch (sugared) {
default:
SS << "\\("; // Lambda
@@ -719,7 +633,7 @@ protected:
SS << ": ";
self()->printSExpr(E->variableDecl()->definition(), SS, Prec_MAX);
- SExpr *B = E->body();
+ const SExpr *B = E->body();
if (B && B->opcode() == COP_Function)
self()->printFunction(cast<Function>(B), SS, 2);
else {
@@ -728,29 +642,29 @@ protected:
}
}
- void printSFunction(SFunction *E, StreamType &SS) {
+ void printSFunction(const SFunction *E, StreamType &SS) {
SS << "@";
self()->printVariable(E->variableDecl(), SS, true);
SS << " ";
self()->printSExpr(E->body(), SS, Prec_Decl);
}
- void printCode(Code *E, StreamType &SS) {
+ void printCode(const Code *E, StreamType &SS) {
SS << ": ";
self()->printSExpr(E->returnType(), SS, Prec_Decl-1);
SS << " -> ";
self()->printSExpr(E->body(), SS, Prec_Decl);
}
- void printField(Field *E, StreamType &SS) {
+ void printField(const Field *E, StreamType &SS) {
SS << ": ";
self()->printSExpr(E->range(), SS, Prec_Decl-1);
SS << " = ";
self()->printSExpr(E->body(), SS, Prec_Decl);
}
- void printApply(Apply *E, StreamType &SS, bool sugared = false) {
- SExpr *F = E->fun();
+ void printApply(const Apply *E, StreamType &SS, bool sugared = false) {
+ const SExpr *F = E->fun();
if (F->opcode() == COP_Apply) {
printApply(cast<Apply>(F), SS, true);
SS << ", ";
@@ -763,7 +677,7 @@ protected:
SS << ")$";
}
- void printSApply(SApply *E, StreamType &SS) {
+ void printSApply(const SApply *E, StreamType &SS) {
self()->printSExpr(E->sfun(), SS, Prec_Postfix);
if (E->isDelegation()) {
SS << "@(";
@@ -772,14 +686,36 @@ protected:
}
}
- void printProject(Project *E, StreamType &SS) {
+ void printProject(const Project *E, StreamType &SS) {
+ if (CStyle) {
+ // Omit the this->
+ if (const SApply *SAP = dyn_cast<SApply>(E->record())) {
+ if (const Variable *V = dyn_cast<Variable>(SAP->sfun())) {
+ if (!SAP->isDelegation() && V->kind() == Variable::VK_SFun) {
+ SS << E->slotName();
+ return;
+ }
+ }
+ }
+ if (isa<Wildcard>(E->record())) {
+ // handle existentials
+ SS << "&";
+ SS << E->clangDecl()->getQualifiedNameAsString();
+ return;
+ }
+ }
self()->printSExpr(E->record(), SS, Prec_Postfix);
- SS << ".";
+ if (CStyle && E->isArrow()) {
+ SS << "->";
+ }
+ else {
+ SS << ".";
+ }
SS << E->slotName();
}
- void printCall(Call *E, StreamType &SS) {
- SExpr *T = E->target();
+ void printCall(const Call *E, StreamType &SS) {
+ const SExpr *T = E->target();
if (T->opcode() == COP_Apply) {
self()->printApply(cast<Apply>(T), SS, true);
SS << ")";
@@ -790,52 +726,60 @@ protected:
}
}
- void printAlloc(Alloc *E, StreamType &SS) {
+ void printAlloc(const Alloc *E, StreamType &SS) {
SS << "new ";
self()->printSExpr(E->dataType(), SS, Prec_Other-1);
}
- void printLoad(Load *E, StreamType &SS) {
+ void printLoad(const Load *E, StreamType &SS) {
self()->printSExpr(E->pointer(), SS, Prec_Postfix);
- SS << "^";
+ if (!CStyle)
+ SS << "^";
}
- void printStore(Store *E, StreamType &SS) {
+ void printStore(const Store *E, StreamType &SS) {
self()->printSExpr(E->destination(), SS, Prec_Other-1);
SS << " := ";
self()->printSExpr(E->source(), SS, Prec_Other-1);
}
- void printArrayIndex(ArrayIndex *E, StreamType &SS) {
+ void printArrayIndex(const ArrayIndex *E, StreamType &SS) {
self()->printSExpr(E->array(), SS, Prec_Postfix);
SS << "[";
self()->printSExpr(E->index(), SS, Prec_MAX);
SS << "]";
}
- void printArrayAdd(ArrayAdd *E, StreamType &SS) {
+ void printArrayAdd(const ArrayAdd *E, StreamType &SS) {
self()->printSExpr(E->array(), SS, Prec_Postfix);
SS << " + ";
self()->printSExpr(E->index(), SS, Prec_Atom);
}
- void printUnaryOp(UnaryOp *E, StreamType &SS) {
+ void printUnaryOp(const UnaryOp *E, StreamType &SS) {
SS << getUnaryOpcodeString(E->unaryOpcode());
self()->printSExpr(E->expr(), SS, Prec_Unary);
}
- void printBinaryOp(BinaryOp *E, StreamType &SS) {
+ void printBinaryOp(const BinaryOp *E, StreamType &SS) {
self()->printSExpr(E->expr0(), SS, Prec_Binary-1);
SS << " " << getBinaryOpcodeString(E->binaryOpcode()) << " ";
self()->printSExpr(E->expr1(), SS, Prec_Binary-1);
}
- void printCast(Cast *E, StreamType &SS) {
- SS << "%";
+ void printCast(const Cast *E, StreamType &SS) {
+ if (!CStyle) {
+ SS << "cast[";
+ SS << E->castOpcode();
+ SS << "](";
+ self()->printSExpr(E->expr(), SS, Prec_Unary);
+ SS << ")";
+ return;
+ }
self()->printSExpr(E->expr(), SS, Prec_Unary);
}
- void printSCFG(SCFG *E, StreamType &SS) {
+ void printSCFG(const SCFG *E, StreamType &SS) {
SS << "CFG {\n";
for (auto BBI : *E) {
printBasicBlock(BBI, SS);
@@ -844,39 +788,45 @@ protected:
newline(SS);
}
- void printBasicBlock(BasicBlock *E, StreamType &SS) {
+
+ void printBBInstr(const SExpr *E, StreamType &SS) {
+ bool Sub = false;
+ if (E->opcode() == COP_Variable) {
+ auto *V = cast<Variable>(E);
+ SS << "let " << V->name() << V->id() << " = ";
+ E = V->definition();
+ Sub = true;
+ }
+ else if (E->opcode() != COP_Store) {
+ SS << "let _x" << E->id() << " = ";
+ }
+ self()->printSExpr(E, SS, Prec_MAX, Sub);
+ SS << ";";
+ newline(SS);
+ }
+
+ void printBasicBlock(const BasicBlock *E, StreamType &SS) {
SS << "BB_" << E->blockID() << ":";
if (E->parent())
SS << " BB_" << E->parent()->blockID();
newline(SS);
- for (auto *A : E->arguments()) {
- SS << "let ";
- self()->printVariable(A, SS, true);
- SS << " = ";
- self()->printSExpr(A->definition(), SS, Prec_MAX);
- SS << ";";
- newline(SS);
- }
- for (auto *I : E->instructions()) {
- if (I->definition()->opcode() != COP_Store) {
- SS << "let ";
- self()->printVariable(I, SS, true);
- SS << " = ";
- }
- self()->printSExpr(I->definition(), SS, Prec_MAX);
- SS << ";";
- newline(SS);
- }
- SExpr *T = E->terminator();
+
+ for (auto *A : E->arguments())
+ printBBInstr(A, SS);
+
+ for (auto *I : E->instructions())
+ printBBInstr(I, SS);
+
+ const SExpr *T = E->terminator();
if (T) {
- self()->printSExpr(T, SS, Prec_MAX);
+ self()->printSExpr(T, SS, Prec_MAX, false);
SS << ";";
newline(SS);
}
newline(SS);
}
- void printPhi(Phi *E, StreamType &SS) {
+ void printPhi(const Phi *E, StreamType &SS) {
SS << "phi(";
if (E->status() == Phi::PH_SingleVal)
self()->printSExpr(E->values()[0], SS, Prec_MAX);
@@ -891,25 +841,38 @@ protected:
SS << ")";
}
- void printGoto(Goto *E, StreamType &SS) {
+ void printGoto(const Goto *E, StreamType &SS) {
SS << "goto ";
printBlockLabel(SS, E->targetBlock(), E->index());
}
- void printBranch(Branch *E, StreamType &SS) {
+ void printBranch(const Branch *E, StreamType &SS) {
SS << "branch (";
self()->printSExpr(E->condition(), SS, Prec_MAX);
SS << ") ";
- printBlockLabel(SS, E->thenBlock(), E->thenIndex());
+ printBlockLabel(SS, E->thenBlock(), -1);
SS << " ";
- printBlockLabel(SS, E->elseBlock(), E->elseIndex());
+ printBlockLabel(SS, E->elseBlock(), -1);
}
- void printIdentifier(Identifier *E, StreamType &SS) {
+ void printReturn(const Return *E, StreamType &SS) {
+ SS << "return ";
+ self()->printSExpr(E->returnValue(), SS, Prec_Other);
+ }
+
+ void printIdentifier(const Identifier *E, StreamType &SS) {
SS << E->name();
}
- void printIfThenElse(IfThenElse *E, StreamType &SS) {
+ void printIfThenElse(const IfThenElse *E, StreamType &SS) {
+ if (CStyle) {
+ printSExpr(E->condition(), SS, Prec_Unary);
+ SS << " ? ";
+ printSExpr(E->thenExpr(), SS, Prec_Unary);
+ SS << " : ";
+ printSExpr(E->elseExpr(), SS, Prec_Unary);
+ return;
+ }
SS << "if (";
printSExpr(E->condition(), SS, Prec_MAX);
SS << ") then ";
@@ -918,7 +881,7 @@ protected:
printSExpr(E->elseExpr(), SS, Prec_Other);
}
- void printLet(Let *E, StreamType &SS) {
+ void printLet(const Let *E, StreamType &SS) {
SS << "let ";
printVariable(E->variableDecl(), SS, true);
SS << " = ";
@@ -929,6 +892,10 @@ protected:
};
+class StdPrinter : public PrettyPrinter<StdPrinter, std::ostream> { };
+
+
+
} // end namespace til
} // end namespace threadSafety
} // end namespace clang
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
index 31200a3a72..5a7572425c 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_THREAD_SAFETY_UTIL_H
-#define LLVM_CLANG_THREAD_SAFETY_UTIL_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYUTIL_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYUTIL_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/AlignOf.h"
@@ -24,6 +24,7 @@
#include <cstddef>
#include <vector>
#include <utility>
+#include <ostream>
namespace clang {
namespace threadSafety {
@@ -142,18 +143,35 @@ public:
assert(i < Size && "Array index out of bounds.");
return Data[i];
}
+ T &back() {
+ assert(Size && "No elements in the array.");
+ return Data[Size - 1];
+ }
+ const T &back() const {
+ assert(Size && "No elements in the array.");
+ return Data[Size - 1];
+ }
iterator begin() { return Data; }
- iterator end() { return Data + Size; }
+ iterator end() { return Data + Size; }
+
+ const_iterator begin() const { return Data; }
+ const_iterator end() const { return Data + Size; }
const_iterator cbegin() const { return Data; }
- const_iterator cend() const { return Data + Size; }
+ const_iterator cend() const { return Data + Size; }
void push_back(const T &Elem) {
assert(Size < Capacity);
Data[Size++] = Elem;
}
+ // drop last n elements from array
+ void drop(unsigned n = 0) {
+ assert(Size > n);
+ Size -= n;
+ }
+
void setValues(unsigned Sz, const T& C) {
assert(Sz <= Capacity);
Size = Sz;
@@ -171,6 +189,37 @@ public:
return J - Osz;
}
+ // An adaptor to reverse a simple array
+ class ReverseAdaptor {
+ public:
+ ReverseAdaptor(SimpleArray &Array) : Array(Array) {}
+ // A reverse iterator used by the reverse adaptor
+ class Iterator {
+ public:
+ Iterator(T *Data) : Data(Data) {}
+ T &operator*() { return *Data; }
+ const T &operator*() const { return *Data; }
+ Iterator &operator++() {
+ --Data;
+ return *this;
+ }
+ bool operator!=(Iterator Other) { return Data != Other.Data; }
+
+ private:
+ T *Data;
+ };
+ Iterator begin() { return Array.end() - 1; }
+ Iterator end() { return Array.begin() - 1; }
+ const Iterator begin() const { return Array.end() - 1; }
+ const Iterator end() const { return Array.begin() - 1; }
+
+ private:
+ SimpleArray &Array;
+ };
+
+ const ReverseAdaptor reverse() const { return ReverseAdaptor(*this); }
+ ReverseAdaptor reverse() { return ReverseAdaptor(*this); }
+
private:
// std::max is annoying here, because it requires a reference,
// thus forcing InitialCapacity to be initialized outside the .h file.
@@ -185,6 +234,7 @@ private:
size_t Capacity;
};
+
} // end namespace til
@@ -310,6 +360,11 @@ private:
};
+inline std::ostream& operator<<(std::ostream& ss, const StringRef str) {
+ return ss.write(str.data(), str.size());
+}
+
+
} // end namespace threadSafety
} // end namespace clang
diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h
index 188722d94b..53ff20c235 100644
--- a/include/clang/Analysis/Analyses/UninitializedValues.h
+++ b/include/clang/Analysis/Analyses/UninitializedValues.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_UNINIT_VALS_H
-#define LLVM_CLANG_UNINIT_VALS_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
#include "clang/AST/Stmt.h"
#include "llvm/ADT/SmallVector.h"
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index 08e335418a..0ebdf15f2c 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -17,6 +17,7 @@
#include "clang/AST/Decl.h"
#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/CodeInjector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Allocator.h"
@@ -143,6 +144,14 @@ public:
/// \sa getBody
bool isBodyAutosynthesized() const;
+ /// \brief Checks if the body of the Decl is generated by the BodyFarm from a
+ /// model file.
+ ///
+ /// Note, the lookup is not free. We are going to call getBody behind
+ /// the scenes.
+ /// \sa getBody
+ bool isBodyAutosynthesizedFromModelFile() const;
+
CFG *getCFG();
CFGStmtMap *getCFGStmtMap();
@@ -398,6 +407,10 @@ class AnalysisDeclContextManager {
ContextMap Contexts;
LocationContextManager LocContexts;
CFG::BuildOptions cfgBuildOptions;
+
+ /// Pointer to an interface that can provide function bodies for
+ /// declarations from external source.
+ std::unique_ptr<CodeInjector> Injector;
/// Flag to indicate whether or not bodies should be synthesized
/// for well-known functions.
@@ -410,7 +423,8 @@ public:
bool addTemporaryDtors = false,
bool synthesizeBodies = false,
bool addStaticInitBranches = false,
- bool addCXXNewAllocator = true);
+ bool addCXXNewAllocator = true,
+ CodeInjector* injector = nullptr);
~AnalysisDeclContextManager();
diff --git a/include/clang/Analysis/AnalysisDiagnostic.h b/include/clang/Analysis/AnalysisDiagnostic.h
index 33c940e7bb..8d28971cfe 100644
--- a/include/clang/Analysis/AnalysisDiagnostic.h
+++ b/include/clang/Analysis/AnalysisDiagnostic.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_DIAGNOSTICANALYSIS_H
-#define LLVM_CLANG_DIAGNOSTICANALYSIS_H
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSISDIAGNOSTIC_H
+#define LLVM_CLANG_ANALYSIS_ANALYSISDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 891fb90691..beea867228 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CFG_H
-#define LLVM_CLANG_CFG_H
+#ifndef LLVM_CLANG_ANALYSIS_CFG_H
+#define LLVM_CLANG_ANALYSIS_CFG_H
#include "clang/AST/Stmt.h"
#include "clang/Analysis/Support/BumpVector.h"
@@ -811,10 +811,9 @@ public:
ImplTy I;
};
- /// buildCFG - Builds a CFG from an AST. The responsibility to free the
- /// constructed CFG belongs to the caller.
- static CFG* buildCFG(const Decl *D, Stmt *AST, ASTContext *C,
- const BuildOptions &BO);
+ /// buildCFG - Builds a CFG from an AST.
+ static std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *AST, ASTContext *C,
+ const BuildOptions &BO);
/// createBlock - Create a new block in the CFG. The CFG owns the block;
/// the caller should not directly free it.
diff --git a/include/clang/Analysis/CFGStmtMap.h b/include/clang/Analysis/CFGStmtMap.h
index 6e8e140afb..4dfa91df0f 100644
--- a/include/clang/Analysis/CFGStmtMap.h
+++ b/include/clang/Analysis/CFGStmtMap.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CFGSTMTMAP_H
-#define LLVM_CLANG_CFGSTMTMAP_H
+#ifndef LLVM_CLANG_ANALYSIS_CFGSTMTMAP_H
+#define LLVM_CLANG_ANALYSIS_CFGSTMTMAP_H
#include "clang/Analysis/CFG.h"
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h
index 593ba575c7..eda22a57e8 100644
--- a/include/clang/Analysis/CallGraph.h
+++ b/include/clang/Analysis/CallGraph.h
@@ -14,8 +14,8 @@
// edges to all externally available functions.
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH
-#define LLVM_CLANG_ANALYSIS_CALLGRAPH
+#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH_H
+#define LLVM_CLANG_ANALYSIS_CALLGRAPH_H
#include "clang/AST/DeclBase.h"
#include "clang/AST/RecursiveASTVisitor.h"
diff --git a/include/clang/Analysis/CodeInjector.h b/include/clang/Analysis/CodeInjector.h
new file mode 100644
index 0000000000..413a55b05b
--- /dev/null
+++ b/include/clang/Analysis/CodeInjector.h
@@ -0,0 +1,46 @@
+//===-- CodeInjector.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::CodeInjector interface which is responsible for
+/// injecting AST of function definitions that may not be available in the
+/// original source.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CODEINJECTOR_H
+#define LLVM_CLANG_ANALYSIS_CODEINJECTOR_H
+
+namespace clang {
+
+class Stmt;
+class FunctionDecl;
+class ObjCMethodDecl;
+
+/// \brief CodeInjector is an interface which is responsible for injecting AST
+/// of function definitions that may not be available in the original source.
+///
+/// The getBody function will be called each time the static analyzer examines a
+/// function call that has no definition available in the current translation
+/// unit. If the returned statement is not a null pointer, it is assumed to be
+/// the body of a function which will be used for the analysis. The source of
+/// the body can be arbitrary, but it is advised to use memoization to avoid
+/// unnecessary reparsing of the external source that provides the body of the
+/// functions.
+class CodeInjector {
+public:
+ CodeInjector();
+ virtual ~CodeInjector();
+
+ virtual Stmt *getBody(const FunctionDecl *D) = 0;
+ virtual Stmt *getBody(const ObjCMethodDecl *D) = 0;
+};
+}
+
+#endif
diff --git a/include/clang/Analysis/DomainSpecific/CocoaConventions.h b/include/clang/Analysis/DomainSpecific/CocoaConventions.h
index e6a2f13a0b..8b3fcff52d 100644
--- a/include/clang/Analysis/DomainSpecific/CocoaConventions.h
+++ b/include/clang/Analysis/DomainSpecific/CocoaConventions.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYSIS_DS_COCOA
-#define LLVM_CLANG_ANALYSIS_DS_COCOA
+#ifndef LLVM_CLANG_ANALYSIS_DOMAINSPECIFIC_COCOACONVENTIONS_H
+#define LLVM_CLANG_ANALYSIS_DOMAINSPECIFIC_COCOACONVENTIONS_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
diff --git a/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h
index 930c2bd092..f9e800a4a4 100644
--- a/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h
+++ b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYSIS_DS_OBJCNORETURN
-#define LLVM_CLANG_ANALYSIS_DS_OBJCNORETURN
+#ifndef LLVM_CLANG_ANALYSIS_DOMAINSPECIFIC_OBJCNORETURN_H
+#define LLVM_CLANG_ANALYSIS_DOMAINSPECIFIC_OBJCNORETURN_H
#include "clang/Basic/IdentifierTable.h"
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 57324d0429..f87271550c 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT
-#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT
+#ifndef LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
+#define LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Analysis/CFG.h"
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
index 6d0427ba92..841adf6455 100644
--- a/include/clang/Analysis/Support/BumpVector.h
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -16,8 +16,8 @@
// refactor this core logic into something common that is shared between
// the two. The main thing that is different is the allocation strategy.
-#ifndef LLVM_CLANG_BUMP_VECTOR
-#define LLVM_CLANG_BUMP_VECTOR
+#ifndef LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H
+#define LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Allocator.h"
@@ -241,4 +241,4 @@ void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) {
}
} // end: clang namespace
-#endif // end: LLVM_CLANG_BUMP_VECTOR
+#endif
diff --git a/include/clang/Basic/ABI.h b/include/clang/Basic/ABI.h
index 9e8ef2e3ee..bd246792fe 100644
--- a/include/clang/Basic/ABI.h
+++ b/include/clang/Basic/ABI.h
@@ -13,8 +13,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef CLANG_BASIC_ABI_H
-#define CLANG_BASIC_ABI_H
+#ifndef LLVM_CLANG_BASIC_ABI_H
+#define LLVM_CLANG_BASIC_ABI_H
#include "llvm/Support/DataTypes.h"
@@ -24,14 +24,15 @@ namespace clang {
enum CXXCtorType {
Ctor_Complete, ///< Complete object ctor
Ctor_Base, ///< Base object ctor
- Ctor_CompleteAllocating ///< Complete object allocating ctor
+ Ctor_Comdat ///< The COMDAT used for ctors
};
/// \brief C++ destructor types.
enum CXXDtorType {
Dtor_Deleting, ///< Deleting dtor
Dtor_Complete, ///< Complete object dtor
- Dtor_Base ///< Base object dtor
+ Dtor_Base, ///< Base object dtor
+ Dtor_Comdat ///< The COMDAT used for dtors
};
/// \brief A return adjustment.
@@ -204,4 +205,4 @@ struct ThunkInfo {
} // end namespace clang
-#endif // CLANG_BASIC_ABI_H
+#endif
diff --git a/include/clang/Basic/AllDiagnostics.h b/include/clang/Basic/AllDiagnostics.h
index 7304c8f673..18a2b8a318 100644
--- a/include/clang/Basic/AllDiagnostics.h
+++ b/include/clang/Basic/AllDiagnostics.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ALL_DIAGNOSTICS_H
-#define LLVM_CLANG_ALL_DIAGNOSTICS_H
+#ifndef LLVM_CLANG_BASIC_ALLDIAGNOSTICS_H
+#define LLVM_CLANG_BASIC_ALLDIAGNOSTICS_H
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/CommentDiagnostic.h"
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index eebcf46db3..2450bdd6ad 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -186,10 +186,11 @@ class Spelling<string name, string variety> {
class GNU<string name> : Spelling<name, "GNU">;
class Declspec<string name> : Spelling<name, "Declspec">;
-class CXX11<string namespace, string name> : Spelling<name, "CXX11"> {
+class CXX11<string namespace, string name, int version = 1>
+ : Spelling<name, "CXX11"> {
string Namespace = namespace;
-}
-class Keyword<string name> : Spelling<name, "Keyword">;
+ int Version = version;
+} class Keyword<string name> : Spelling<name, "Keyword">;
class Pragma<string namespace, string name> : Spelling<name, "Pragma"> {
string Namespace = namespace;
}
@@ -354,6 +355,24 @@ def Aligned : InheritableAttr {
let Documentation = [Undocumented];
}
+def AlignValue : Attr {
+ let Spellings = [
+ // Unfortunately, this is semantically an assertion, not a directive
+ // (something else must ensure the alignment), so aligned_value is a
+ // probably a better name. We might want to add an aligned_value spelling in
+ // the future (and a corresponding C++ attribute), but this can be done
+ // later once we decide if we also want them to have slightly-different
+ // semantics than Intel's align_value.
+ GNU<"align_value">
+ // Intel's compiler on Windows also supports:
+ // , Declspec<"align_value">
+ ];
+ let Args = [ExprArgument<"Alignment">];
+ let Subjects = SubjectList<[Var, TypedefName], WarnDiag,
+ "ExpectedVariableOrTypedef">;
+ let Documentation = [AlignValueDocs];
+}
+
def AlignMac68k : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
@@ -434,7 +453,8 @@ def Bounded : IgnoredAttr {
}
def CarriesDependency : InheritableParamAttr {
- let Spellings = [GNU<"carries_dependency">, CXX11<"","carries_dependency">];
+ let Spellings = [GNU<"carries_dependency">,
+ CXX11<"","carries_dependency", 200809>];
let Subjects = SubjectList<[ParmVar, ObjCMethod, Function], ErrorDiag>;
let Documentation = [CarriesDependencyDocs];
}
@@ -541,6 +561,13 @@ def CUDAHost : InheritableAttr {
let Documentation = [Undocumented];
}
+def CUDAInvalidTarget : InheritableAttr {
+ let Spellings = [];
+ let Subjects = SubjectList<[Function]>;
+ let LangOpts = [CUDA];
+ let Documentation = [Undocumented];
+}
+
def CUDALaunchBounds : InheritableAttr {
let Spellings = [GNU<"launch_bounds">];
let Args = [IntArgument<"MaxThreads">, DefaultIntArgument<"MinBlocks", 0>];
@@ -568,7 +595,7 @@ def C11NoReturn : InheritableAttr {
}
def CXX11NoReturn : InheritableAttr {
- let Spellings = [CXX11<"","noreturn">];
+ let Spellings = [CXX11<"","noreturn", 200809>];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [CXX11NoReturnDocs];
}
@@ -622,7 +649,7 @@ def Kernel : Attr {
def Deprecated : InheritableAttr {
let Spellings = [GCC<"deprecated">, Declspec<"deprecated">,
- CXX11<"","deprecated">];
+ CXX11<"","deprecated", 201309>];
let Args = [StringArgument<"Message", 1>];
let Documentation = [Undocumented];
}
@@ -660,7 +687,7 @@ def FastCall : InheritableAttr {
let Spellings = [GCC<"fastcall">, Keyword<"__fastcall">,
Keyword<"_fastcall">];
// let Subjects = [Function, ObjCMethod];
- let Documentation = [Undocumented];
+ let Documentation = [FastCallDocs];
}
def Final : InheritableAttr {
@@ -759,7 +786,7 @@ def MayAlias : InheritableAttr {
def MSABI : InheritableAttr {
let Spellings = [GCC<"ms_abi">];
// let Subjects = [Function, ObjCMethod];
- let Documentation = [Undocumented];
+ let Documentation = [MSABIDocs];
}
def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> {
@@ -815,7 +842,7 @@ def NoCommon : InheritableAttr {
}
def NoDebug : InheritableAttr {
- let Spellings = [GNU<"nodebug">];
+ let Spellings = [GCC<"nodebug">];
let Documentation = [Undocumented];
}
@@ -850,21 +877,32 @@ def NonNull : InheritableAttr {
let Args = [VariadicUnsignedArgument<"Args">];
let AdditionalMembers =
[{bool isNonNull(unsigned idx) const {
+ if (!args_size())
+ return true;
for (const auto &V : args())
if (V == idx)
return true;
return false;
} }];
+ // FIXME: We should merge duplicates into a single nonnull attribute.
+ let DuplicatesAllowedWhileMerging = 1;
let Documentation = [Undocumented];
}
def ReturnsNonNull : InheritableAttr {
let Spellings = [GCC<"returns_nonnull">];
- let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag,
+ let Subjects = SubjectList<[ObjCMethod, Function], WarnDiag,
"ExpectedFunctionOrMethod">;
let Documentation = [Undocumented];
}
+def AssumeAligned : InheritableAttr {
+ let Spellings = [GCC<"assume_aligned">];
+ let Subjects = SubjectList<[ObjCMethod, Function]>;
+ let Args = [ExprArgument<"Alignment">, ExprArgument<"Offset", 1>];
+ let Documentation = [AssumeAlignedDocs];
+}
+
def NoReturn : InheritableAttr {
let Spellings = [GCC<"noreturn">, Declspec<"noreturn">];
// FIXME: Does GCC allow this on the function instead?
@@ -994,6 +1032,13 @@ def ObjCDesignatedInitializer : Attr {
let Documentation = [Undocumented];
}
+def ObjCRuntimeName : Attr {
+ let Spellings = [GNU<"objc_runtime_name">];
+ let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag>;
+ let Args = [StringArgument<"MetadataName">];
+ let Documentation = [ObjCRuntimeNameDocs];
+}
+
def OptimizeNone : InheritableAttr {
let Spellings = [GNU<"optnone">, CXX11<"clang", "optnone">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
@@ -1066,7 +1111,7 @@ def Pure : InheritableAttr {
def Regparm : TypeAttr {
let Spellings = [GCC<"regparm">];
let Args = [UnsignedArgument<"NumParams">];
- let Documentation = [Undocumented];
+ let Documentation = [RegparmDocs];
}
def ReqdWorkGroupSize : InheritableAttr {
@@ -1113,7 +1158,7 @@ def Sentinel : InheritableAttr {
def StdCall : InheritableAttr {
let Spellings = [GCC<"stdcall">, Keyword<"__stdcall">, Keyword<"_stdcall">];
// let Subjects = [Function, ObjCMethod];
- let Documentation = [Undocumented];
+ let Documentation = [StdCallDocs];
}
def SysVABI : InheritableAttr {
@@ -1126,7 +1171,14 @@ def ThisCall : InheritableAttr {
let Spellings = [GCC<"thiscall">, Keyword<"__thiscall">,
Keyword<"_thiscall">];
// let Subjects = [Function, ObjCMethod];
- let Documentation = [Undocumented];
+ let Documentation = [ThisCallDocs];
+}
+
+def VectorCall : InheritableAttr {
+ let Spellings = [GNU<"vectorcall">, Keyword<"__vectorcall">,
+ Keyword<"_vectorcall">];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [VectorCallDocs];
}
def Pascal : InheritableAttr {
@@ -1765,19 +1817,38 @@ def MSVtorDisp : InheritableAttr {
let Documentation = [Undocumented];
}
+def InitSeg : Attr {
+ let Spellings = [Pragma<"", "init_seg">];
+ let Args = [StringArgument<"Section">];
+ let SemaHandler = 0;
+ let Documentation = [InitSegDocs];
+ let AdditionalMembers = [{
+ void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
+ OS << '(' << getSection() << ')';
+ }
+ }];
+}
+
def Unaligned : IgnoredAttr {
let Spellings = [Keyword<"__unaligned">];
}
def LoopHint : Attr {
- /// vectorize: vectorizes loop operations if 'value != 0'.
- /// vectorize_width: vectorize loop operations with width 'value'.
- /// interleave: interleave multiple loop iterations if 'value != 0'.
- /// interleave_count: interleaves 'value' loop interations.
- /// unroll: unroll loop if 'value != 0'.
- /// unroll_count: unrolls loop 'value' times.
-
- let Spellings = [Pragma<"clang", "loop">];
+ /// #pragma clang loop <option> directive
+ /// vectorize: vectorizes loop operations if State == Enable.
+ /// vectorize_width: vectorize loop operations with width 'Value'.
+ /// interleave: interleave multiple loop iterations if State == Enable.
+ /// interleave_count: interleaves 'Value' loop interations.
+ /// unroll: fully unroll loop if State == Enable.
+ /// unroll_count: unrolls loop 'Value' times.
+
+ /// #pragma unroll <argument> directive
+ /// <no arg>: fully unrolls loop.
+ /// boolean: fully unrolls loop if State == Enable.
+ /// expression: unrolls loop 'Value' times.
+
+ let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">,
+ Pragma<"", "nounroll">];
/// State of the loop optimization specified by the spelling.
let Args = [EnumArgument<"Option", "OptionType",
@@ -1785,10 +1856,13 @@ def LoopHint : Attr {
"unroll", "unroll_count"],
["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",
"Unroll", "UnrollCount"]>,
- DefaultIntArgument<"Value", 1>];
+ EnumArgument<"State", "LoopHintState",
+ ["default", "enable", "disable"],
+ ["Default", "Enable", "Disable"]>,
+ ExprArgument<"Value">];
let AdditionalMembers = [{
- static StringRef getOptionName(int Option) {
+ static const char *getOptionName(int Option) {
switch(Option) {
case Vectorize: return "vectorize";
case VectorizeWidth: return "vectorize_width";
@@ -1800,22 +1874,68 @@ def LoopHint : Attr {
llvm_unreachable("Unhandled LoopHint option.");
}
- static StringRef getValueName(int Value) {
- if (Value)
- return "enable";
- return "disable";
+ void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
+ unsigned SpellingIndex = getSpellingListIndex();
+ // For "#pragma unroll" and "#pragma nounroll" the string "unroll" or
+ // "nounroll" is already emitted as the pragma name.
+ if (SpellingIndex == Pragma_nounroll) {
+ OS << "\n";
+ return;
+ }
+ else if (SpellingIndex == Pragma_unroll) {
+ OS << getValueString(Policy) << "\n";
+ return;
+ }
+
+ assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
+ OS << getOptionName(option) << getValueString(Policy) << "\n";
}
- void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
- OS << getOptionName(option) << "(";
+ // Return a string containing the loop hint argument including the
+ // enclosing parentheses.
+ std::string getValueString(const PrintingPolicy &Policy) const {
+ std::string ValueName;
+ llvm::raw_string_ostream OS(ValueName);
+ OS << "(";
if (option == VectorizeWidth || option == InterleaveCount ||
option == UnrollCount)
- OS << value;
+ value->printPretty(OS, nullptr, Policy);
+ else if (state == Default)
+ return "";
+ else if (state == Enable)
+ OS << (option == Unroll ? "full" : "enable");
else
- OS << getValueName(value);
- OS << ")\n";
+ OS << "disable";
+ OS << ")";
+ return OS.str();
+ }
+
+ // Return a string suitable for identifying this attribute in diagnostics.
+ std::string getDiagnosticName(const PrintingPolicy &Policy) const {
+ unsigned SpellingIndex = getSpellingListIndex();
+ if (SpellingIndex == Pragma_nounroll)
+ return "#pragma nounroll";
+ else if (SpellingIndex == Pragma_unroll)
+ return "#pragma unroll" + getValueString(Policy);
+
+ assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
+ return getOptionName(option) + getValueString(Policy);
}
}];
- let Documentation = [LoopHintDocs];
+ let Documentation = [LoopHintDocs, UnrollHintDocs];
+}
+
+def CapturedRecord : InheritableAttr {
+ // This attribute has no spellings as it is only ever created implicitly.
+ let Spellings = [];
+ let SemaHandler = 0;
+ let Documentation = [Undocumented];
+}
+
+def OMPThreadPrivateDecl : InheritableAttr {
+ // This attribute has no spellings as it is only ever created implicitly.
+ let Spellings = [];
+ let SemaHandler = 0;
+ let Documentation = [Undocumented];
}
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 947c9ba014..cf8b662357 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -36,6 +36,22 @@ global variable or function should be in after translation.
let Heading = "section (gnu::section, __declspec(allocate))";
}
+def InitSegDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The attribute applied by ``pragma init_seg()`` controls the section into
+which global initialization function pointers are emitted. It is only
+available with ``-fms-extensions``. Typically, this function pointer is
+emitted into ``.CRT$XCU`` on Windows. The user can change the order of
+initialization by using a different section name with the same
+``.CRT$XC`` prefix and a suffix that sorts lexicographically before or
+after the standard ``.CRT$XCU`` sections. See the init_seg_
+documentation on MSDN for more information.
+
+.. _init_seg: http://msdn.microsoft.com/en-us/library/7977wcck(v=vs.110).aspx
+ }];
+}
+
def TLSModelDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
@@ -56,9 +72,9 @@ def ThreadDocs : Documentation {
let Content = [{
The ``__declspec(thread)`` attribute declares a variable with thread local
storage. It is available under the ``-fms-extensions`` flag for MSVC
-compatibility. Documentation for the Visual C++ attribute is available on MSDN_.
+compatibility. See the documentation for `__declspec(thread)`_ on MSDN.
-.. _MSDN: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx
+.. _`__declspec(thread)`: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx
In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the
GNU ``__thread`` keyword. The variable must not have a destructor and must have
@@ -138,6 +154,30 @@ def ReleaseCapabilityDocs : Documentation {
Marks a function as releasing a capability.
}];
}
+
+def AssumeAlignedDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Use ``__attribute__((assume_aligned(<alignment>[,<offset>]))`` on a function
+declaration to specify that the return value of the function (which must be a
+pointer type) has the specified offset, in bytes, from an address with the
+specified alignment. The offset is taken to be zero if omitted.
+
+.. code-block:: c++
+
+ // The returned pointer value has 32-byte alignment.
+ void *a() __attribute__((assume_aligned (32)));
+
+ // The returned pointer value is 4 bytes greater than an address having
+ // 32-byte alignment.
+ void *b() __attribute__((assume_aligned (32, 4)));
+
+Note that this attribute provides information to the compiler regarding a
+condition that the code already ensures is true. It does not cause the compiler
+to enforce the provided alignment assumption.
+ }];
+}
+
def EnableIfDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -426,6 +466,27 @@ implementation of an override in a subclass does not call super. For example:
}];
}
+def ObjCRuntimeNameDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+By default, the Objective-C interface or protocol identifier is used
+in the metadata name for that object. The `objc_runtime_name`
+attribute allows annotated interfaces or protocols to use the
+specified string argument in the object's metadata name instead of the
+default name.
+
+**Usage**: ``__attribute__((objc_runtime_name("MyLocalName")))``. This attribute
+can only be placed before an @protocol or @interface declaration:
+
+.. code-block:: objc
+
+ __attribute__((objc_runtime_name("MyLocalName")))
+ @interface Message
+ @end
+
+ }];
+}
+
def AvailabilityDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -612,15 +673,120 @@ The semantics are as follows:
}];
}
+def DocCatCallingConvs : DocumentationCategory<"Calling Conventions"> {
+ let Content = [{
+Clang supports several different calling conventions, depending on the target
+platform and architecture. The calling convention used for a function determines
+how parameters are passed, how results are returned to the caller, and other
+low-level details of calling a function.
+ }];
+}
+
def PcsDocs : Documentation {
- let Category = DocCatFunction;
+ let Category = DocCatCallingConvs;
let Content = [{
-On ARM targets, this can attribute can be used to select calling conventions,
+On ARM targets, this attribute can be used to select calling conventions
similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and
"aapcs-vfp".
}];
}
+def RegparmDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On 32-bit x86 targets, the regparm attribute causes the compiler to pass
+the first three integer parameters in EAX, EDX, and ECX instead of on the
+stack. This attribute has no effect on variadic functions, and all parameters
+are passed via the stack as normal.
+ }];
+}
+
+def SysVABIDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On Windows x86_64 targets, this attribute changes the calling convention of a
+function to match the default convention used on Sys V targets such as Linux,
+Mac, and BSD. This attribute has no effect on other targets.
+ }];
+}
+
+def MSABIDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On non-Windows x86_64 targets, this attribute changes the calling convention of
+a function to match the default convention used on Windows x86_64. This
+attribute has no effect on Windows targets or non-x86_64 targets.
+ }];
+}
+
+def StdCallDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On 32-bit x86 targets, this attribute changes the calling convention of a
+function to clear parameters off of the stack on return. This convention does
+not support variadic calls or unprototyped functions in C, and has no effect on
+x86_64 targets. This calling convention is used widely by the Windows API and
+COM applications. See the documentation for `__stdcall`_ on MSDN.
+
+.. _`__stdcall`: http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx
+ }];
+}
+
+def FastCallDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On 32-bit x86 targets, this attribute changes the calling convention of a
+function to use ECX and EDX as register parameters and clear parameters off of
+the stack on return. This convention does not support variadic calls or
+unprototyped functions in C, and has no effect on x86_64 targets. This calling
+convention is supported primarily for compatibility with existing code. Users
+seeking register parameters should use the ``regparm`` attribute, which does
+not require callee-cleanup. See the documentation for `__fastcall`_ on MSDN.
+
+.. _`__fastcall`: http://msdn.microsoft.com/en-us/library/6xa169sk.aspx
+ }];
+}
+
+def ThisCallDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On 32-bit x86 targets, this attribute changes the calling convention of a
+function to use ECX for the first parameter (typically the implicit ``this``
+parameter of C++ methods) and clear parameters off of the stack on return. This
+convention does not support variadic calls or unprototyped functions in C, and
+has no effect on x86_64 targets. See the documentation for `__thiscall`_ on
+MSDN.
+
+.. _`__thiscall`: http://msdn.microsoft.com/en-us/library/ek8tkfbw.aspx
+ }];
+}
+
+def VectorCallDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On 32-bit x86 *and* x86_64 targets, this attribute changes the calling
+convention of a function to pass vector parameters in SSE registers.
+
+On 32-bit x86 targets, this calling convention is similar to ``__fastcall``.
+The first two integer parameters are passed in ECX and EDX. Subsequent integer
+parameters are passed in memory, and callee clears the stack. On x86_64
+targets, the callee does *not* clear the stack, and integer parameters are
+passed in RCX, RDX, R8, and R9 as is done for the default Windows x64 calling
+convention.
+
+On both 32-bit x86 and x86_64 targets, vector and floating point arguments are
+passed in XMM0-XMM5. Homogenous vector aggregates of up to four elements are
+passed in sequential SSE registers if enough are available. If AVX is enabled,
+256 bit vectors are passed in YMM0-YMM5. Any vector or aggregate type that
+cannot be passed in registers for any reason is passed by reference, which
+allows the caller to align the parameter memory.
+
+See the documentation for `__vectorcall`_ on MSDN for more details.
+
+.. _`__vectorcall`: http://msdn.microsoft.com/en-us/library/dn375768.aspx
+ }];
+}
+
def DocCatConsumed : DocumentationCategory<"Consumed Annotation Checking"> {
let Content = [{
Clang supports additional attributes for checking basic resource management
@@ -950,6 +1116,26 @@ Clang implements two kinds of checks with this attribute.
}];
}
+def AlignValueDocs : Documentation {
+ let Category = DocCatType;
+ let Content = [{
+The align_value attribute can be added to the typedef of a pointer type or the
+declaration of a variable of pointer or reference type. It specifies that the
+pointer will point to, or the reference will bind to, only objects with at
+least the provided alignment. This alignment value must be some positive power
+of 2.
+
+ .. code-block:: c
+
+ typedef double * aligned_double_ptr __attribute__((align_value(64)));
+ void foo(double & x __attribute__((align_value(128)),
+ aligned_double_ptr y) { ... }
+
+If the pointer value does not have the specified alignment at runtime, the
+behavior of the program is undefined.
+ }];
+}
+
def MSInheritanceDocs : Documentation {
let Category = DocCatType;
let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance";
@@ -1014,6 +1200,7 @@ This attribute is incompatible with the ``always_inline`` attribute.
def LoopHintDocs : Documentation {
let Category = DocCatStmt;
+ let Heading = "#pragma clang loop";
let Content = [{
The ``#pragma clang loop`` directive allows loop optimization hints to be
specified for the subsequent loop. The directive allows vectorization,
@@ -1024,3 +1211,57 @@ as interleave and unrolling count can be manually specified. See
for details.
}];
}
+
+def UnrollHintDocs : Documentation {
+ let Category = DocCatStmt;
+ let Heading = "#pragma unroll, #pragma nounroll";
+ let Content = [{
+Loop unrolling optimization hints can be specified with ``#pragma unroll`` and
+``#pragma nounroll``. The pragma is placed immediately before a for, while,
+do-while, or c++11 range-based for loop.
+
+Specifying ``#pragma unroll`` without a parameter directs the loop unroller to
+attempt to fully unroll the loop if the trip count is known at compile time:
+
+.. code-block:: c++
+
+ #pragma unroll
+ for (...) {
+ ...
+ }
+
+Specifying the optional parameter, ``#pragma unroll _value_``, directs the
+unroller to unroll the loop ``_value_`` times. The parameter may optionally be
+enclosed in parentheses:
+
+.. code-block:: c++
+
+ #pragma unroll 16
+ for (...) {
+ ...
+ }
+
+ #pragma unroll(16)
+ for (...) {
+ ...
+ }
+
+Specifying ``#pragma nounroll`` indicates that the loop should not be unrolled:
+
+.. code-block:: c++
+
+ #pragma nounroll
+ for (...) {
+ ...
+ }
+
+``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to
+``#pragma clang loop unroll(full)`` and
+``#pragma clang loop unroll_count(_value_)`` respectively. ``#pragma nounroll``
+is equivalent to ``#pragma clang loop unroll(disable)``. See
+`language extensions
+<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
+for further details including limitations of the unroll hints.
+ }];
+}
+
diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h
index 150a30e73d..f0b0a6445d 100644
--- a/include/clang/Basic/AttrKinds.h
+++ b/include/clang/Basic/AttrKinds.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ATTRKINDS_H
-#define LLVM_CLANG_ATTRKINDS_H
+#ifndef LLVM_CLANG_BASIC_ATTRKINDS_H
+#define LLVM_CLANG_BASIC_ATTRKINDS_H
namespace clang {
diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h
index 5783b3bff5..982e12d9f2 100644
--- a/include/clang/Basic/Attributes.h
+++ b/include/clang/Basic/Attributes.h
@@ -30,11 +30,11 @@ enum class AttrSyntax {
Pragma
};
-/// \brief Return true if we recognize and implement the attribute specified by
-/// the given information.
-bool hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
- const IdentifierInfo *Attr, const llvm::Triple &T,
- const LangOptions &LangOpts);
+/// \brief Return the version number associated with the attribute if we
+/// recognize and implement the attribute specified by the given information.
+int hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
+ const IdentifierInfo *Attr, const llvm::Triple &T,
+ const LangOptions &LangOpts);
} // end namespace clang
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index a7a7f428d4..dc668a161c 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -412,6 +412,7 @@ BUILTIN(__builtin_va_start, "vA.", "nt")
BUILTIN(__builtin_va_end, "vA", "n")
BUILTIN(__builtin_va_copy, "vAA", "n")
BUILTIN(__builtin_stdarg_start, "vA.", "n")
+BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nc")
BUILTIN(__builtin_bcmp, "iv*v*z", "n")
BUILTIN(__builtin_bcopy, "vv*v*z", "n")
BUILTIN(__builtin_bzero, "vv*z", "nF")
@@ -540,6 +541,12 @@ BUILTIN(__sync_fetch_and_xor_4, "iiD*i.", "tn")
BUILTIN(__sync_fetch_and_xor_8, "LLiLLiD*LLi.", "tn")
BUILTIN(__sync_fetch_and_xor_16, "LLLiLLLiD*LLLi.", "tn")
+BUILTIN(__sync_fetch_and_nand, "v.", "t")
+BUILTIN(__sync_fetch_and_nand_1, "ccD*c.", "tn")
+BUILTIN(__sync_fetch_and_nand_2, "ssD*s.", "tn")
+BUILTIN(__sync_fetch_and_nand_4, "iiD*i.", "tn")
+BUILTIN(__sync_fetch_and_nand_8, "LLiLLiD*LLi.", "tn")
+BUILTIN(__sync_fetch_and_nand_16, "LLLiLLLiD*LLLi.", "tn")
BUILTIN(__sync_add_and_fetch, "v.", "t")
BUILTIN(__sync_add_and_fetch_1, "ccD*c.", "tn")
@@ -576,6 +583,13 @@ BUILTIN(__sync_xor_and_fetch_4, "iiD*i.", "tn")
BUILTIN(__sync_xor_and_fetch_8, "LLiLLiD*LLi.", "tn")
BUILTIN(__sync_xor_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
+BUILTIN(__sync_nand_and_fetch, "v.", "t")
+BUILTIN(__sync_nand_and_fetch_1, "ccD*c.", "tn")
+BUILTIN(__sync_nand_and_fetch_2, "ssD*s.", "tn")
+BUILTIN(__sync_nand_and_fetch_4, "iiD*i.", "tn")
+BUILTIN(__sync_nand_and_fetch_8, "LLiLLiD*LLi.", "tn")
+BUILTIN(__sync_nand_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
+
BUILTIN(__sync_bool_compare_and_swap, "v.", "t")
BUILTIN(__sync_bool_compare_and_swap_1, "bcD*cc.", "tn")
BUILTIN(__sync_bool_compare_and_swap_2, "bsD*ss.", "tn")
@@ -679,7 +693,7 @@ BUILTIN(__builtin_rindex, "c*cC*i", "Fn")
// Microsoft builtins. These are only active with -fms-extensions.
LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__noop, "v.", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)
@@ -689,6 +703,7 @@ LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__readfsdword, "ULiULi", "n", ALL_MS_LANGUAGES)
// C99 library functions
// C99 stdlib.h
@@ -1173,6 +1188,9 @@ LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
// Annotation function
BUILTIN(__builtin_annotation, "v.", "tn")
+// Invariants
+BUILTIN(__builtin_assume, "vb", "n")
+
// Multiprecision Arithmetic Builtins.
BUILTIN(__builtin_addcb, "UcUcCUcCUcCUc*", "n")
BUILTIN(__builtin_addcs, "UsUsCUsCUsCUs*", "n")
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
index c3852fbb42..9d223c3e85 100644
--- a/include/clang/Basic/BuiltinsAArch64.def
+++ b/include/clang/Basic/BuiltinsAArch64.def
@@ -27,6 +27,14 @@ BUILTIN(__builtin_arm_clrex, "v", "")
BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
BUILTIN(__builtin_arm_rbit64, "LUiLUi", "nc")
+// HINT
+BUILTIN(__builtin_arm_nop, "v", "")
+BUILTIN(__builtin_arm_yield, "v", "")
+BUILTIN(__builtin_arm_wfe, "v", "")
+BUILTIN(__builtin_arm_wfi, "v", "")
+BUILTIN(__builtin_arm_sev, "v", "")
+BUILTIN(__builtin_arm_sevl, "v", "")
+
// CRC32
BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc")
BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc")
@@ -37,4 +45,12 @@ BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc")
BUILTIN(__builtin_arm_crc32d, "UiUiLUi", "nc")
BUILTIN(__builtin_arm_crc32cd, "UiUiLUi", "nc")
+// Memory barrier
+BUILTIN(__builtin_arm_dmb, "vUi", "nc")
+BUILTIN(__builtin_arm_dsb, "vUi", "nc")
+BUILTIN(__builtin_arm_isb, "vUi", "nc")
+
+// Prefetch
+BUILTIN(__builtin_arm_prefetch, "vvC*UiUiUiUi", "nc")
+
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index d1cf9a76fb..1f2f9a3840 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -68,17 +68,22 @@ BUILTIN(__builtin_arm_crc32d, "UiUiLLUi", "nc")
BUILTIN(__builtin_arm_crc32cd, "UiUiLLUi", "nc")
// HINT
+BUILTIN(__builtin_arm_nop, "v", "")
BUILTIN(__builtin_arm_yield, "v", "")
BUILTIN(__builtin_arm_wfe, "v", "")
BUILTIN(__builtin_arm_wfi, "v", "")
BUILTIN(__builtin_arm_sev, "v", "")
BUILTIN(__builtin_arm_sevl, "v", "")
+BUILTIN(__builtin_arm_dbg, "vUi", "")
// Data barrier
BUILTIN(__builtin_arm_dmb, "vUi", "nc")
BUILTIN(__builtin_arm_dsb, "vUi", "nc")
BUILTIN(__builtin_arm_isb, "vUi", "nc")
+// Prefetch
+BUILTIN(__builtin_arm_prefetch, "vvC*UiUi", "nc")
+
// MSVC
LANGBUILTIN(__yield, "v", "", ALL_MS_LANGUAGES)
LANGBUILTIN(__wfe, "v", "", ALL_MS_LANGUAGES)
diff --git a/include/clang/Basic/BuiltinsLe64.def b/include/clang/Basic/BuiltinsLe64.def
new file mode 100644
index 0000000000..532860603c
--- /dev/null
+++ b/include/clang/Basic/BuiltinsLe64.def
@@ -0,0 +1,19 @@
+//==- BuiltinsLe64.def - Le64 Builtin function database ----------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Le64-specific builtin function database. Users of this
+// file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+BUILTIN(__clear_cache, "vv*v*", "i")
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
index 8a751e4ce8..e42af42441 100644
--- a/include/clang/Basic/BuiltinsPPC.def
+++ b/include/clang/Basic/BuiltinsPPC.def
@@ -204,6 +204,25 @@ BUILTIN(__builtin_altivec_vcmpgtsw_p, "iiV4SiV4Si", "")
BUILTIN(__builtin_altivec_vcmpgtuw_p, "iiV4UiV4Ui", "")
BUILTIN(__builtin_altivec_vcmpgtfp_p, "iiV4fV4f", "")
+// VSX built-ins.
+
+BUILTIN(__builtin_vsx_lxvd2x, "V2divC*", "")
+BUILTIN(__builtin_vsx_lxvw4x, "V4iivC*", "")
+
+BUILTIN(__builtin_vsx_stxvd2x, "vV2div*", "")
+BUILTIN(__builtin_vsx_stxvw4x, "vV4iiv*", "")
+
+BUILTIN(__builtin_vsx_xvmaxdp, "V2dV2dV2d", "")
+BUILTIN(__builtin_vsx_xvmaxsp, "V4fV4fV4f", "")
+BUILTIN(__builtin_vsx_xsmaxdp, "ddd", "")
+
+BUILTIN(__builtin_vsx_xvmindp, "V2dV2dV2d", "")
+BUILTIN(__builtin_vsx_xvminsp, "V4fV4fV4f", "")
+BUILTIN(__builtin_vsx_xsmindp, "ddd", "")
+
+BUILTIN(__builtin_vsx_xvdivdp, "V2dV2dV2d", "")
+BUILTIN(__builtin_vsx_xvdivsp, "V4fV4fV4f", "")
+
// FIXME: Obviously incomplete.
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsR600.def b/include/clang/Basic/BuiltinsR600.def
index e0812d7945..79a82f7b4b 100644
--- a/include/clang/Basic/BuiltinsR600.def
+++ b/include/clang/Basic/BuiltinsR600.def
@@ -16,5 +16,19 @@
BUILTIN(__builtin_amdgpu_div_scale, "dddbb*", "n")
BUILTIN(__builtin_amdgpu_div_scalef, "fffbb*", "n")
+BUILTIN(__builtin_amdgpu_div_fmas, "ddddb", "nc")
+BUILTIN(__builtin_amdgpu_div_fmasf, "ffffb", "nc")
+BUILTIN(__builtin_amdgpu_div_fixup, "dddd", "nc")
+BUILTIN(__builtin_amdgpu_div_fixupf, "ffff", "nc")
+BUILTIN(__builtin_amdgpu_trig_preop, "ddi", "nc")
+BUILTIN(__builtin_amdgpu_trig_preopf, "ffi", "nc")
+BUILTIN(__builtin_amdgpu_rcp, "dd", "nc")
+BUILTIN(__builtin_amdgpu_rcpf, "ff", "nc")
+BUILTIN(__builtin_amdgpu_rsq, "dd", "nc")
+BUILTIN(__builtin_amdgpu_rsqf, "ff", "nc")
+BUILTIN(__builtin_amdgpu_rsq_clamped, "dd", "nc")
+BUILTIN(__builtin_amdgpu_rsq_clampedf, "ff", "nc")
+BUILTIN(__builtin_amdgpu_ldexp, "ddi", "nc")
+BUILTIN(__builtin_amdgpu_ldexpf, "ffi", "nc")
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 1f377a8ab1..79bfd4b5b2 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -303,12 +303,12 @@ BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "")
BUILTIN(__builtin_ia32_mwait, "vUiUi", "")
BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "")
BUILTIN(__builtin_ia32_palignr128, "V16cV16cV16cIc", "")
-BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fi", "")
+BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fIc", "")
BUILTIN(__builtin_ia32_pblendvb128, "V16cV16cV16cV16c", "")
-BUILTIN(__builtin_ia32_pblendw128, "V8sV8sV8sIi", "")
-BUILTIN(__builtin_ia32_blendpd, "V2dV2dV2dIi", "")
-BUILTIN(__builtin_ia32_blendps, "V4fV4fV4fIi", "")
+BUILTIN(__builtin_ia32_pblendw128, "V8sV8sV8sIc", "")
+BUILTIN(__builtin_ia32_blendpd, "V2dV2dV2dIc", "")
+BUILTIN(__builtin_ia32_blendps, "V4fV4fV4fIc", "")
BUILTIN(__builtin_ia32_blendvpd, "V2dV2dV2dV2d", "")
BUILTIN(__builtin_ia32_blendvps, "V4fV4fV4fV4f", "")
@@ -339,13 +339,13 @@ BUILTIN(__builtin_ia32_roundps, "V4fV4fi", "")
BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fi", "")
BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2di", "")
BUILTIN(__builtin_ia32_roundpd, "V2dV2di", "")
-BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fi", "")
-BUILTIN(__builtin_ia32_dppd, "V2dV2dV2di", "")
+BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fIc", "")
+BUILTIN(__builtin_ia32_dppd, "V2dV2dV2dIc", "")
BUILTIN(__builtin_ia32_movntdqa, "V2LLiV2LLi*", "")
BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "")
BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "")
BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "")
-BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16ci", "")
+BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16cIc", "")
BUILTIN(__builtin_ia32_phminposuw128, "V8sV8s", "")
// SSE 4.2
@@ -404,11 +404,11 @@ BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2LLi", "")
BUILTIN(__builtin_ia32_vpermilvarps, "V4fV4fV4i", "")
BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4LLi", "")
BUILTIN(__builtin_ia32_vpermilvarps256, "V8fV8fV8i", "")
-BUILTIN(__builtin_ia32_blendpd256, "V4dV4dV4dIi", "")
-BUILTIN(__builtin_ia32_blendps256, "V8fV8fV8fIi", "")
+BUILTIN(__builtin_ia32_blendpd256, "V4dV4dV4dIc", "")
+BUILTIN(__builtin_ia32_blendps256, "V8fV8fV8fIc", "")
BUILTIN(__builtin_ia32_blendvpd256, "V4dV4dV4dV4d", "")
BUILTIN(__builtin_ia32_blendvps256, "V8fV8fV8fV8f", "")
-BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fIi", "")
+BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fIc", "")
BUILTIN(__builtin_ia32_cmppd256, "V4dV4dV4dc", "")
BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fc", "")
BUILTIN(__builtin_ia32_vextractf128_pd256, "V2dV4dIc", "")
@@ -472,7 +472,7 @@ BUILTIN(__builtin_ia32_maskstorepd256, "vV4d*V4dV4d", "")
BUILTIN(__builtin_ia32_maskstoreps256, "vV8f*V8fV8f", "")
// AVX2
-BUILTIN(__builtin_ia32_mpsadbw256, "V32cV32cV32ci", "")
+BUILTIN(__builtin_ia32_mpsadbw256, "V32cV32cV32cIc", "")
BUILTIN(__builtin_ia32_pabsb256, "V32cV32c", "")
BUILTIN(__builtin_ia32_pabsw256, "V16sV16s", "")
BUILTIN(__builtin_ia32_pabsd256, "V8iV8i", "")
@@ -492,7 +492,7 @@ BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIc", "")
BUILTIN(__builtin_ia32_pavgb256, "V32cV32cV32c", "")
BUILTIN(__builtin_ia32_pavgw256, "V16sV16sV16s", "")
BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "")
-BUILTIN(__builtin_ia32_pblendw256, "V16sV16sV16sIi", "")
+BUILTIN(__builtin_ia32_pblendw256, "V16sV16sV16sIc", "")
BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "")
BUILTIN(__builtin_ia32_phaddd256, "V8iV8iV8i", "")
BUILTIN(__builtin_ia32_phaddsw256, "V16sV16sV16s", "")
@@ -559,8 +559,8 @@ BUILTIN(__builtin_ia32_vbroadcastss_ps, "V4fV4f", "")
BUILTIN(__builtin_ia32_vbroadcastss_ps256, "V8fV4f", "")
BUILTIN(__builtin_ia32_vbroadcastsd_pd256, "V4dV2d", "")
BUILTIN(__builtin_ia32_vbroadcastsi256, "V4LLiV2LLi", "")
-BUILTIN(__builtin_ia32_pblendd128, "V4iV4iV4iIi", "")
-BUILTIN(__builtin_ia32_pblendd256, "V8iV8iV8iIi", "")
+BUILTIN(__builtin_ia32_pblendd128, "V4iV4iV4iIc", "")
+BUILTIN(__builtin_ia32_pblendd256, "V8iV8iV8iIc", "")
BUILTIN(__builtin_ia32_pbroadcastb256, "V32cV16c", "")
BUILTIN(__builtin_ia32_pbroadcastw256, "V16sV8s", "")
BUILTIN(__builtin_ia32_pbroadcastd256, "V8iV4i", "")
@@ -615,14 +615,34 @@ BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iV4iC*V4LLiV4iIc", "")
// F16C
BUILTIN(__builtin_ia32_vcvtps2ph, "V8sV4fIi", "")
BUILTIN(__builtin_ia32_vcvtps2ph256, "V8sV8fIi", "")
+BUILTIN(__builtin_ia32_vcvtps2ph512, "V16sV16fIi", "")
BUILTIN(__builtin_ia32_vcvtph2ps, "V4fV8s", "")
BUILTIN(__builtin_ia32_vcvtph2ps256, "V8fV8s", "")
+BUILTIN(__builtin_ia32_vcvtph2ps512, "V16fV16s", "")
// RDRAND
BUILTIN(__builtin_ia32_rdrand16_step, "UiUs*", "")
BUILTIN(__builtin_ia32_rdrand32_step, "UiUi*", "")
BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "")
+// FSGSBASE
+BUILTIN(__builtin_ia32_rdfsbase32, "Ui", "")
+BUILTIN(__builtin_ia32_rdfsbase64, "ULLi", "")
+BUILTIN(__builtin_ia32_rdgsbase32, "Ui", "")
+BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "")
+BUILTIN(__builtin_ia32_wrfsbase32, "vUi", "")
+BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "")
+BUILTIN(__builtin_ia32_wrgsbase32, "vUi", "")
+BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "")
+
+// ADX
+BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "")
+BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "")
+BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "")
+BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "")
+BUILTIN(__builtin_ia32_subborrow_u32, "UcUcUiUiUi*", "")
+BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "")
+
// RDSEED
BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "")
BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "")
@@ -653,7 +673,7 @@ BUILTIN(__builtin_ia32_sha256rnds2, "V4iV4iV4iV4i", "")
BUILTIN(__builtin_ia32_sha256msg1, "V4iV4iV4i", "")
BUILTIN(__builtin_ia32_sha256msg2, "V4iV4iV4i", "")
-// FMA4
+// FMA
BUILTIN(__builtin_ia32_vfmaddps, "V4fV4fV4fV4f", "")
BUILTIN(__builtin_ia32_vfmaddpd, "V2dV2dV2dV2d", "")
BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "")
@@ -686,6 +706,12 @@ BUILTIN(__builtin_ia32_vfmaddsubps256, "V8fV8fV8fV8f", "")
BUILTIN(__builtin_ia32_vfmaddsubpd256, "V4dV4dV4dV4d", "")
BUILTIN(__builtin_ia32_vfmsubaddps256, "V8fV8fV8fV8f", "")
BUILTIN(__builtin_ia32_vfmsubaddpd256, "V4dV4dV4dV4d", "")
+BUILTIN(__builtin_ia32_vfmaddpd512_mask, "V8dV8dV8dV8dUci", "")
+BUILTIN(__builtin_ia32_vfmsubpd512_mask, "V8dV8dV8dV8dUci", "")
+BUILTIN(__builtin_ia32_vfnmaddpd512_mask, "V8dV8dV8dV8dUci", "")
+BUILTIN(__builtin_ia32_vfmaddps512_mask, "V16fV16fV16fV16fUsi", "")
+BUILTIN(__builtin_ia32_vfmsubps512_mask, "V16fV16fV16fV16fUsi", "")
+BUILTIN(__builtin_ia32_vfnmaddps512_mask, "V16fV16fV16fV16fUsi", "")
// XOP
BUILTIN(__builtin_ia32_vpmacssww, "V8sV8sV8sV8s", "")
@@ -761,4 +787,119 @@ BUILTIN(__builtin_ia32_rdpmc, "ULLii", "")
BUILTIN(__builtin_ia32_rdtsc, "ULLi", "")
BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "")
+// AVX-512
+BUILTIN(__builtin_ia32_sqrtpd512_mask, "V8dV8dV8dUcCi", "")
+BUILTIN(__builtin_ia32_sqrtps512_mask, "V16fV16fV16fUsCi", "")
+BUILTIN(__builtin_ia32_rsqrt14sd_mask, "V2dV2dV2dV2dUc", "")
+BUILTIN(__builtin_ia32_rsqrt14ss_mask, "V4fV4fV4fV4fUc", "")
+BUILTIN(__builtin_ia32_rsqrt14pd512_mask, "V8dV8dV8dUc", "")
+BUILTIN(__builtin_ia32_rsqrt14ps512_mask, "V16fV16fV16fUs", "")
+BUILTIN(__builtin_ia32_rsqrt28sd_mask, "V2dV2dV2dV2dUcCi", "")
+BUILTIN(__builtin_ia32_rsqrt28ss_mask, "V4fV4fV4fV4fUcCi", "")
+BUILTIN(__builtin_ia32_rsqrt28pd_mask, "V8dV8dV8dUcCi", "")
+BUILTIN(__builtin_ia32_rsqrt28ps_mask, "V16fV16fV16fUsCi", "")
+BUILTIN(__builtin_ia32_rcp14sd_mask, "V2dV2dV2dV2dUc", "")
+BUILTIN(__builtin_ia32_rcp14ss_mask, "V4fV4fV4fV4fUc", "")
+BUILTIN(__builtin_ia32_rcp14pd512_mask, "V8dV8dV8dUc", "")
+BUILTIN(__builtin_ia32_rcp14ps512_mask, "V16fV16fV16fUs", "")
+BUILTIN(__builtin_ia32_rcp28sd_mask, "V2dV2dV2dV2dUcCi", "")
+BUILTIN(__builtin_ia32_rcp28ss_mask, "V4fV4fV4fV4fUcCi", "")
+BUILTIN(__builtin_ia32_rcp28pd_mask, "V8dV8dV8dUcCi", "")
+BUILTIN(__builtin_ia32_rcp28ps_mask, "V16fV16fV16fUsCi", "")
+BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsCi", "")
+BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsCi", "")
+BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcCi", "")
+BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUcCi", "")
+BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fCiUsi", "")
+BUILTIN(__builtin_ia32_pcmpeqb512_mask, "LLiV64cV64cLLi", "")
+BUILTIN(__builtin_ia32_pcmpeqd512_mask, "sV16iV16is", "")
+BUILTIN(__builtin_ia32_pcmpeqq512_mask, "cV8LLiV8LLic", "")
+BUILTIN(__builtin_ia32_pcmpeqw512_mask, "iV32sV32si", "")
+BUILTIN(__builtin_ia32_pcmpeqb256_mask, "iV32cV32ci", "")
+BUILTIN(__builtin_ia32_pcmpeqd256_mask, "cV8iV8ic", "")
+BUILTIN(__builtin_ia32_pcmpeqq256_mask, "cV4LLiV4LLic", "")
+BUILTIN(__builtin_ia32_pcmpeqw256_mask, "sV16sV16ss", "")
+BUILTIN(__builtin_ia32_pcmpeqb128_mask, "sV16cV16cs", "")
+BUILTIN(__builtin_ia32_pcmpeqd128_mask, "cV4iV4ic", "")
+BUILTIN(__builtin_ia32_pcmpeqq128_mask, "cV2LLiV2LLic", "")
+BUILTIN(__builtin_ia32_pcmpeqw128_mask, "cV8sV8sc", "")
+BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dCiUci", "")
+BUILTIN(__builtin_ia32_rndscaleps_mask, "V16fV16fCiV16fUsCi", "")
+BUILTIN(__builtin_ia32_rndscalepd_mask, "V8dV8dCiV8dUcCi", "")
+BUILTIN(__builtin_ia32_cvtps2dq512_mask, "V16iV16fV16iUsCi", "")
+BUILTIN(__builtin_ia32_cvtpd2dq512_mask, "V8iV8dV8iUcCi", "")
+BUILTIN(__builtin_ia32_cvtps2udq512_mask, "V16iV16fV16iUsCi", "")
+BUILTIN(__builtin_ia32_cvtpd2udq512_mask, "V8iV8dV8iUcCi", "")
+BUILTIN(__builtin_ia32_minps512_mask, "V16fV16fV16fV16fUsCi", "")
+BUILTIN(__builtin_ia32_minpd512_mask, "V8dV8dV8dV8dUcCi", "")
+BUILTIN(__builtin_ia32_maxps512_mask, "V16fV16fV16fV16fUsCi", "")
+BUILTIN(__builtin_ia32_maxpd512_mask, "V8dV8dV8dV8dUcCi", "")
+BUILTIN(__builtin_ia32_cvtdq2ps512_mask, "V16fV16iV16fUsCi", "")
+BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsCi", "")
+BUILTIN(__builtin_ia32_cvtdq2pd512_mask, "V8dV8iV8dUc", "")
+BUILTIN(__builtin_ia32_cvtudq2pd512_mask, "V8dV8iV8dUc", "")
+BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcCi", "")
+BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fCiV16sUs", "")
+BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsCi", "")
+BUILTIN(__builtin_ia32_pabsd512_mask, "V16iV16iV16iUs", "")
+BUILTIN(__builtin_ia32_pabsq512_mask, "V8LLiV8LLiV8LLiUc", "")
+BUILTIN(__builtin_ia32_pmaxsd512_mask, "V16iV16iV16iV16iUs", "")
+BUILTIN(__builtin_ia32_pmaxsq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "")
+BUILTIN(__builtin_ia32_pmaxud512_mask, "V16iV16iV16iV16iUs", "")
+BUILTIN(__builtin_ia32_pmaxuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "")
+BUILTIN(__builtin_ia32_pminsd512_mask, "V16iV16iV16iV16iUs", "")
+BUILTIN(__builtin_ia32_pminsq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "")
+BUILTIN(__builtin_ia32_pminud512_mask, "V16iV16iV16iV16iUs", "")
+BUILTIN(__builtin_ia32_pminuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "")
+BUILTIN(__builtin_ia32_pmuldq512_mask, "V8LLiV16iV16iV8LLiUc", "")
+BUILTIN(__builtin_ia32_pmuludq512_mask, "V8LLiV16iV16iV8LLiUc", "")
+BUILTIN(__builtin_ia32_blendmd_512_mask, "V16iV16iV16iUs", "")
+BUILTIN(__builtin_ia32_blendmq_512_mask, "V8LLiV8LLiV8LLiUc", "")
+BUILTIN(__builtin_ia32_blendmps_512_mask, "V16fV16fV16fUs", "")
+BUILTIN(__builtin_ia32_blendmpd_512_mask, "V8dV8dV8dUc", "")
+BUILTIN(__builtin_ia32_ptestmd512, "UsV16iV16iUs", "")
+BUILTIN(__builtin_ia32_ptestmq512, "UcV8LLiV8LLiUc", "")
+BUILTIN(__builtin_ia32_pbroadcastd512_gpr_mask, "V16iiV16iUs", "")
+BUILTIN(__builtin_ia32_pbroadcastq512_gpr_mask, "V8LLiLLiV8LLiUc", "")
+BUILTIN(__builtin_ia32_pbroadcastq512_mem_mask, "V8LLiLLiV8LLiUc", "")
+BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16ivC*V16iUs", "")
+BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLivC*V8LLiUc", "")
+BUILTIN(__builtin_ia32_loadups512_mask, "V16fvC*V16fUs", "")
+BUILTIN(__builtin_ia32_loadupd512_mask, "V8dvC*V8dUc", "")
+BUILTIN(__builtin_ia32_storedqudi512_mask, "vv*V8LLiUc", "")
+BUILTIN(__builtin_ia32_storedqusi512_mask, "vv*V16iUs", "")
+BUILTIN(__builtin_ia32_storeupd512_mask, "vv*V8dUc", "")
+BUILTIN(__builtin_ia32_storeups512_mask, "vv*V16fUs", "")
+BUILTIN(__builtin_ia32_vpermt2vard512_mask, "V16iV16iV16iV16iUs", "")
+BUILTIN(__builtin_ia32_vpermt2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "")
+BUILTIN(__builtin_ia32_vpermt2varps512_mask, "V16fV16iV16fV16fUs", "")
+BUILTIN(__builtin_ia32_vpermt2varpd512_mask, "V8dV8LLiV8dV8dUc", "")
+BUILTIN(__builtin_ia32_alignq512_mask, "V8LLiV8LLiV8LLiUcV8LLiUc", "")
+BUILTIN(__builtin_ia32_alignd512_mask, "V16iV16iV16iUcV16iUc", "")
+BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dv*V8iUcCi", "")
+BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fv*UsCi", "")
+BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dv*V8LLiUcCi", "")
+BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fv*V8LLiUcCi", "")
+BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLiv*V8iUcCi", "")
+BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16iv*UsCi", "")
+BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLiv*V8LLiUcCi", "")
+BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8iv*V8LLiUcCi", "")
+BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8dCi", "")
+BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fCi", "")
+BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8LLiV8dCi", "")
+BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8LLiV8fCi", "")
+BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8LLiCi", "")
+BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iCi", "")
+BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8LLiV8LLiCi", "")
+BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8LLiV8iCi", "")
+BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8iv*CiCi", "")
+BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16iv*CiCi", "")
+BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLiv*CiCi", "")
+BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLiv*CiCi", "")
+BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*CiCi", "")
+BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*CiCi", "")
+BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiv*CiCi", "")
+BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLiv*CiCi", "")
+BUILTIN(__builtin_ia32_knothi, "UsUs", "")
+
#undef BUILTIN
diff --git a/include/clang/Basic/CharInfo.h b/include/clang/Basic/CharInfo.h
index d0afda4370..dd9c55431e 100644
--- a/include/clang/Basic/CharInfo.h
+++ b/include/clang/Basic/CharInfo.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_BASIC_CHARINFO_H
-#define CLANG_BASIC_CHARINFO_H
+#ifndef LLVM_CLANG_BASIC_CHARINFO_H
+#define LLVM_CLANG_BASIC_CHARINFO_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
diff --git a/include/clang/Basic/CommentOptions.h b/include/clang/Basic/CommentOptions.h
index 7991875838..92419f91b7 100644
--- a/include/clang/Basic/CommentOptions.h
+++ b/include/clang/Basic/CommentOptions.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_COMMENTOPTIONS_H
-#define LLVM_CLANG_COMMENTOPTIONS_H
+#ifndef LLVM_CLANG_BASIC_COMMENTOPTIONS_H
+#define LLVM_CLANG_BASIC_COMMENTOPTIONS_H
#include <string>
#include <vector>
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 4dc8aebe95..31a29fa200 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_DIAGNOSTIC_H
-#define LLVM_CLANG_DIAGNOSTIC_H
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTIC_H
+#define LLVM_CLANG_BASIC_DIAGNOSTIC_H
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/DiagnosticOptions.h"
@@ -187,7 +187,7 @@ private:
IntrusiveRefCntPtr<DiagnosticIDs> Diags;
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
DiagnosticConsumer *Client;
- bool OwnsDiagClient;
+ std::unique_ptr<DiagnosticConsumer> Owner;
SourceManager *SourceMgr;
/// \brief Mapping information for diagnostics.
@@ -302,7 +302,6 @@ private:
unsigned NumWarnings; ///< Number of warnings reported
unsigned NumErrors; ///< Number of errors reported
- unsigned NumErrorsSuppressed; ///< Number of errors suppressed
/// \brief A function pointer that converts an opaque diagnostic
/// argument to a strings.
@@ -348,7 +347,6 @@ public:
DiagnosticOptions *DiagOpts,
DiagnosticConsumer *client = nullptr,
bool ShouldOwnClient = true);
- ~DiagnosticsEngine();
const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
return Diags;
@@ -369,14 +367,11 @@ public:
const DiagnosticConsumer *getClient() const { return Client; }
/// \brief Determine whether this \c DiagnosticsEngine object own its client.
- bool ownsClient() const { return OwnsDiagClient; }
-
+ bool ownsClient() const { return Owner != nullptr; }
+
/// \brief Return the current diagnostic client along with ownership of that
/// client.
- DiagnosticConsumer *takeClient() {
- OwnsDiagClient = false;
- return Client;
- }
+ std::unique_ptr<DiagnosticConsumer> takeClient() { return std::move(Owner); }
bool hasSourceManager() const { return SourceMgr != nullptr; }
SourceManager &getSourceManager() const {
@@ -542,9 +537,13 @@ public:
/// \returns true (and ignores the request) if "Group" was unknown, false
/// otherwise.
///
+ /// \param Flavor The flavor of group to affect. -Rfoo does not affect the
+ /// state of the -Wfoo group and vice versa.
+ ///
/// \param Loc The source location that this change of diagnostic state should
/// take affect. It can be null if we are setting the state from command-line.
- bool setSeverityForGroup(StringRef Group, diag::Severity Map,
+ bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group,
+ diag::Severity Map,
SourceLocation Loc = SourceLocation());
/// \brief Set the warning-as-error flag for the given diagnostic group.
@@ -561,11 +560,12 @@ public:
/// \returns True if the given group is unknown, false otherwise.
bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled);
- /// \brief Add the specified mapping to all diagnostics.
+ /// \brief Add the specified mapping to all diagnostics of the specified
+ /// flavor.
///
/// Mainly to be used by -Wno-everything to disable all warnings but allow
/// subsequent -W options to enable specific warnings.
- void setSeverityForAll(diag::Severity Map,
+ void setSeverityForAll(diag::Flavor Flavor, diag::Severity Map,
SourceLocation Loc = SourceLocation());
bool hasErrorOccurred() const { return ErrorOccurred; }
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index 8d5a1c7723..d353b451aa 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -141,6 +141,13 @@ def note_constexpr_calls_suppressed : Note<
"(skipping %0 call%s0 in backtrace; use -fconstexpr-backtrace-limit=0 to "
"see all)">;
def note_constexpr_call_here : Note<"in call to '%0'">;
+def note_constexpr_baa_insufficient_alignment : Note<
+ "%select{alignment of|offset of the aligned pointer from}0 the base pointee "
+ "object (%1 %plural{1:byte|:bytes}1) is %select{less than|not a multiple of}0 the "
+ "asserted %2 %plural{1:byte|:bytes}2">;
+def note_constexpr_baa_value_insufficient_alignment : Note<
+ "value of the aligned pointer (%0) is not a multiple of the asserted %1 "
+ "%plural{1:byte|:bytes}1">;
def warn_integer_constant_overflow : Warning<
"overflow in expression; result is %0 with type %1">,
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index b3c77b8f5f..ff9ed69022 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -81,6 +81,8 @@ def err_deleted_non_function : Error<
"only functions can have deleted definitions">;
def err_module_not_found : Error<"module '%0' not found">, DefaultFatal;
def err_module_not_built : Error<"could not build module '%0'">, DefaultFatal;
+def err_module_lock_failure : Error<
+ "could not acquire lock file for module '%0'">, DefaultFatal;
def err_module_cycle : Error<"cyclic dependency in module '%0': %1">,
DefaultFatal;
def note_pragma_entered_here : Note<"#pragma entered here">;
@@ -102,10 +104,12 @@ def ext_cxx11_longlong : Extension<
def warn_cxx98_compat_longlong : Warning<
"'long long' is incompatible with C++98">,
InGroup<CXX98CompatPedantic>, DefaultIgnore;
-def err_integer_too_large : Error<
- "integer constant is larger than the largest unsigned integer type">;
-def ext_integer_too_large_for_signed : ExtWarn<
- "integer constant is larger than the largest signed integer type">,
+def err_integer_literal_too_large : Error<
+ "integer literal is too large to be represented in any %select{signed |}0"
+ "integer type">;
+def ext_integer_literal_too_large_for_signed : ExtWarn<
+ "integer literal is too large to be represented in a signed integer type, "
+ "interpreting as unsigned">,
InGroup<DiagGroup<"implicitly-unsigned-literal">>;
// Sema && AST
@@ -121,6 +125,8 @@ def err_target_unknown_abi : Error<"unknown target ABI '%0'">;
def err_target_unknown_fpmath : Error<"unknown FP unit '%0'">;
def err_target_unsupported_fpmath : Error<
"the '%0' unit is not supported with this instruction set">;
+def err_target_unsupported_unaligned : Error<
+ "the %0 sub-architecture does not support unaligned accesses">;
// Source manager
def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal;
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index b5a807ecf2..41c78ee669 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -22,6 +22,8 @@ def err_drv_unknown_stdin_type_clang_cl : Error<
def err_drv_unknown_language : Error<"language not recognized: '%0'">;
def err_drv_invalid_arch_name : Error<
"invalid arch name '%0'">;
+def err_drv_invalid_thread_model_for_target : Error<
+ "invalid thread model '%0' in '%1' for this target">;
def err_drv_invalid_linker_name : Error<
"invalid linker name in argument '%0'">;
def err_drv_invalid_rtlib_name : Error<
@@ -100,10 +102,6 @@ def err_drv_cc_print_options_failure : Error<
"unable to open CC_PRINT_OPTIONS file: %0">;
def err_drv_preamble_format : Error<
"incorrect format for -preamble-bytes=N,END">;
-def err_drv_conflicting_deployment_targets : Error<
- "conflicting deployment targets, both '%0' and '%1' are present in environment">;
-def err_drv_invalid_arch_for_deployment_target : Error<
- "invalid architecture '%0' for deployment target '%1'">;
def err_drv_objc_gc_arr : Error<
"cannot specify both '-fobjc-arc' and '%0'">;
def err_arc_unsupported_on_runtime : Error<
@@ -118,10 +116,13 @@ def err_drv_emit_llvm_link : Error<
"-emit-llvm cannot be used when linking">;
def err_drv_optimization_remark_pattern : Error<
"%0 in '%1'">;
+def err_drv_no_neon_modifier : Error<"[no]neon is not accepted as modifier, please use [no]simd instead">;
def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>;
-def warn_drv_optimization_value : Warning<"optimization level '%0' is unsupported; using '%1%2' instead">,
+def warn_drv_optimization_value : Warning<"optimization level '%0' is not supported; using '%1%2' instead">,
InGroup<InvalidCommandLineArgument>;
+def warn_ignored_gcc_optimization : Warning<"optimization flag '%0' is not supported">,
+ InGroup<IgnoredOptimizationArgument>;
def warn_c_kext : Warning<
"ignoring -fapple-kext which is valid for C++ and Objective-C++ only">;
def warn_drv_input_file_unused : Warning<
@@ -162,9 +163,11 @@ def warn_debug_compression_unavailable : Warning<"cannot compress debug sections
def note_drv_command_failed_diag_msg : Note<
"diagnostic msg: %0">;
-def note_drv_t_option_is_global :
- Note<"The last /TC or /TP option takes precedence over earlier instances">;
-
+def note_drv_t_option_is_global : Note<
+ "The last /TC or /TP option takes precedence over earlier instances">;
+def note_drv_address_sanitizer_debug_runtime : Note<
+ "AddressSanitizer doesn't support linking with debug runtime libraries yet">;
+
def err_analyzer_config_no_value : Error<
"analyzer-config option '%0' has a key but no value">;
def err_analyzer_config_multiple_values : Error<
@@ -172,7 +175,7 @@ def err_analyzer_config_multiple_values : Error<
def err_drv_modules_validate_once_requires_timestamp : Error<
"option '-fmodules-validate-once-per-build-session' requires "
- "'-fbuild-session-timestamp=<seconds since Epoch>'">;
+ "'-fbuild-session-timestamp=<seconds since Epoch>' or '-fbuild-session-file=<file>'">;
def warn_drv_invoking_fallback : Warning<"falling back to %0">,
InGroup<Fallback>;
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index c08ac992ee..15f74b1169 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -36,14 +36,26 @@ def remark_fe_backend_plugin: Remark<"%0">, BackendInfo, InGroup<RemarkBackendPl
def note_fe_backend_plugin: Note<"%0">, BackendInfo;
def remark_fe_backend_optimization_remark : Remark<"%0">, BackendInfo,
- InGroup<BackendOptimizationRemark>, DefaultRemark;
+ InGroup<BackendOptimizationRemark>;
def remark_fe_backend_optimization_remark_missed : Remark<"%0">, BackendInfo,
- InGroup<BackendOptimizationRemarkMissed>, DefaultRemark;
+ InGroup<BackendOptimizationRemarkMissed>;
def remark_fe_backend_optimization_remark_analysis : Remark<"%0">, BackendInfo,
- InGroup<BackendOptimizationRemarkAnalysis>, DefaultRemark;
+ InGroup<BackendOptimizationRemarkAnalysis>;
+def warn_fe_backend_optimization_failure : Warning<"%0">, BackendInfo,
+ InGroup<BackendOptimizationFailure>, DefaultWarn;
def note_fe_backend_optimization_remark_invalid_loc : Note<"could "
"not determine the original source location for %0:%1:%2">;
+def remark_sanitize_address_insert_extra_padding_accepted : Remark<
+ "-fsanitize-address-field-padding applied to %0">, ShowInSystemHeader,
+ InGroup<SanitizeAddressRemarks>;
+def remark_sanitize_address_insert_extra_padding_rejected : Remark<
+ "-fsanitize-address-field-padding ignored for %0 because it "
+ "%select{is not C++|is packed|is a union|is trivially copyable|"
+ "has trivial destructor|is standard layout|is in a blacklisted file|"
+ "is blacklisted}1">, ShowInSystemHeader,
+ InGroup<SanitizeAddressRemarks>;
+
def err_fe_invalid_code_complete_file : Error<
"cannot locate code-completion file %0">, DefaultFatal;
def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
@@ -83,9 +95,12 @@ def err_fe_no_pch_in_dir : Error<
def err_fe_action_not_available : Error<
"action %0 not compiled in">;
+def warn_fe_serialized_diag_merge_failure : Warning<
+ "unable to merge a subprocess's serialized diagnostics">,
+ InGroup<SerializedDiagnostics>;
def warn_fe_serialized_diag_failure : Warning<
"unable to open file %0 for serializing diagnostics (%1)">,
- InGroup<DiagGroup<"serialized-diagnostics">>;
+ InGroup<SerializedDiagnostics>;
def err_verify_missing_line : Error<
"missing or invalid line number following '@' in expected %0">;
@@ -124,17 +139,8 @@ def err_relocatable_without_isysroot : Error<
"must specify system root with -isysroot when building a relocatable "
"PCH file">;
-def warn_unknown_warning_option : Warning<
- "unknown warning option '%0'">,
- InGroup<UnknownWarningOption>;
-def warn_unknown_negative_warning_option : Warning<
- "unknown warning option '%0'">,
- InGroup<UnknownWarningOption>;
-def warn_unknown_warning_option_suggest : Warning<
- "unknown warning option '%0'; did you mean '%1'?">,
- InGroup<UnknownWarningOption>;
-def warn_unknown_negative_warning_option_suggest : Warning<
- "unknown warning option '%0'; did you mean '%1'?">,
+def warn_unknown_diag_option : Warning<
+ "unknown %select{warning|remark}0 option '%1'%select{|; did you mean '%3'?}2">,
InGroup<UnknownWarningOption>;
def warn_unknown_warning_specifier : Warning<
"unknown %0 warning specifier: '%1'">,
@@ -142,12 +148,15 @@ def warn_unknown_warning_specifier : Warning<
def err_unknown_analyzer_checker : Error<
"no analyzer checkers are associated with '%0'">;
+def note_suggest_disabling_all_checkers : Note<
+ "use -analyzer-disable-all-checks to disable all static analyzer checkers">;
+
def warn_incompatible_analyzer_plugin_api : Warning<
"checker plugin '%0' is not compatible with this version of the analyzer">,
InGroup<DiagGroup<"analyzer-incompatible-plugin"> >;
def note_incompatible_analyzer_plugin_api : Note<
"current API version is '%0', but plugin was compiled with version '%1'">;
-
+
def err_module_map_not_found : Error<"module map file '%0' not found">,
DefaultFatal;
def err_missing_module_name : Error<
@@ -174,7 +183,19 @@ def warn_module_config_macro_undef : Warning<
def note_module_def_undef_here : Note<
"macro was %select{defined|#undef'd}0 here">;
def remark_module_build : Remark<"building module '%0' as '%1'">,
- InGroup<DiagGroup<"module-build">>, DefaultIgnore;
+ InGroup<ModuleBuild>;
+def remark_module_build_done : Remark<"finished building module '%0'">,
+ InGroup<ModuleBuild>;
+
+def err_conflicting_module_names : Error<
+ "conflicting module names specified: '-fmodule-name=%0' and "
+ "'-fmodule-implementation-of %1'">;
+def err_conflicting_module_files : Error<
+ "module '%0' is defined in both '%1' and '%2'">;
+def err_module_file_not_found : Error<
+ "file '%0' is not a precompiled module file">, DefaultFatal;
+def err_module_file_not_module : Error<
+ "AST file '%0' was not built as a module">, DefaultFatal;
def err_missing_vfs_overlay_file : Error<
"virtual filesystem overlay file '%0' not found">, DefaultFatal;
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 3d10fcfef0..cc4508a894 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -71,6 +71,7 @@ def GNUDesignator : DiagGroup<"gnu-designator">;
def GNUStringLiteralOperatorTemplate :
DiagGroup<"gnu-string-literal-operator-template">;
+def DeleteIncomplete : DiagGroup<"delete-incomplete">;
def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
def AbstractFinalClass : DiagGroup<"abstract-final-class">;
@@ -118,9 +119,9 @@ def FormatExtraArgs : DiagGroup<"format-extra-args">;
def FormatZeroLength : DiagGroup<"format-zero-length">;
// Warnings for C++1y code which is not compatible with prior C++ standards.
-def CXXPre1yCompat : DiagGroup<"c++98-c++11-compat">;
-def CXXPre1yCompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic",
- [CXXPre1yCompat]>;
+def CXXPre14Compat : DiagGroup<"c++98-c++11-compat">;
+def CXXPre14CompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic",
+ [CXXPre14Compat]>;
def CXXPre1zCompat : DiagGroup<"c++98-c++11-c++14-compat">;
def CXXPre1zCompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic",
[CXXPre1zCompat]>;
@@ -133,19 +134,21 @@ def CXX98CompatUnnamedTypeTemplateArgs :
DiagGroup<"c++98-compat-unnamed-type-template-args">;
def CXX98Compat : DiagGroup<"c++98-compat",
- [CXX98CompatBindToTemporaryCopy,
- CXX98CompatLocalTypeTemplateArgs,
+ [CXX98CompatLocalTypeTemplateArgs,
CXX98CompatUnnamedTypeTemplateArgs,
- CXXPre1yCompat,
+ CXXPre14Compat,
CXXPre1zCompat]>;
// Warnings for C++11 features which are Extensions in C++98 mode.
def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
[CXX98Compat,
- CXXPre1yCompatPedantic,
+ CXX98CompatBindToTemporaryCopy,
+ CXXPre14CompatPedantic,
CXXPre1zCompatPedantic]>;
def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
+def CXX11WarnOverrideMethod : DiagGroup<"inconsistent-missing-override">;
+
// Original name of this warning in Clang
def : DiagGroup<"c++0x-narrowing", [CXX11Narrowing]>;
@@ -162,11 +165,11 @@ def CXX11Compat : DiagGroup<"c++11-compat",
[CXX11Narrowing,
CXX11CompatReservedUserDefinedLiteral,
CXX11CompatDeprecatedWritableStr,
- CXXPre1yCompat,
+ CXXPre14Compat,
CXXPre1zCompat]>;
def : DiagGroup<"c++0x-compat", [CXX11Compat]>;
def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic",
- [CXXPre1yCompatPedantic,
+ [CXXPre14CompatPedantic,
CXXPre1zCompatPedantic]>;
def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre1zCompat]>;
@@ -198,11 +201,13 @@ def IncompatiblePointerTypes
: DiagGroup<"incompatible-pointer-types",
[IncompatiblePointerTypesDiscardsQualifiers]>;
def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">;
-def IncompleteModule : DiagGroup<"incomplete-module", [IncompleteUmbrella]>;
def NonModularIncludeInFrameworkModule
: DiagGroup<"non-modular-include-in-framework-module">;
def NonModularIncludeInModule : DiagGroup<"non-modular-include-in-module",
[NonModularIncludeInFrameworkModule]>;
+def IncompleteModule : DiagGroup<"incomplete-module",
+ [IncompleteUmbrella, NonModularIncludeInModule]>;
+
def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">;
def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">;
@@ -231,6 +236,7 @@ def MismatchedParameterTypes : DiagGroup<"mismatched-parameter-types">;
def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">;
def MismatchedTags : DiagGroup<"mismatched-tags">;
def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
+def ModuleBuild : DiagGroup<"module-build">;
def ModuleConflict : DiagGroup<"module-conflict">;
def NewlineEOF : DiagGroup<"newline-eof">;
def NullArithmetic : DiagGroup<"null-arithmetic">;
@@ -268,6 +274,7 @@ def ObjCRootClass : DiagGroup<"objc-root-class">;
def ObjCPointerIntrospectPerformSelector : DiagGroup<"deprecated-objc-pointer-introspection-performSelector">;
def ObjCPointerIntrospect : DiagGroup<"deprecated-objc-pointer-introspection", [ObjCPointerIntrospectPerformSelector]>;
def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
+def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
def Packed : DiagGroup<"packed">;
def Padded : DiagGroup<"padded">;
def PointerArith : DiagGroup<"pointer-arith">;
@@ -349,6 +356,7 @@ def InvalidOffsetof : DiagGroup<"invalid-offsetof">;
def : DiagGroup<"strict-prototypes">;
def StrictSelector : DiagGroup<"strict-selector-match">;
def MethodDuplicate : DiagGroup<"duplicate-method-match">;
+def ObjCCStringFormat : DiagGroup<"cstring-format-directive">;
def CoveredSwitchDefault : DiagGroup<"covered-switch-default">;
def SwitchBool : DiagGroup<"switch-bool">;
def SwitchEnum : DiagGroup<"switch-enum">;
@@ -383,7 +391,9 @@ def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args",
def UnsupportedFriend : DiagGroup<"unsupported-friend">;
def UnusedArgument : DiagGroup<"unused-argument">;
def UnusedCommandLineArgument : DiagGroup<"unused-command-line-argument">;
-def InvalidCommandLineArgument : DiagGroup<"invalid-command-line-argument">;
+def IgnoredOptimizationArgument : DiagGroup<"ignored-optimization-argument">;
+def InvalidCommandLineArgument : DiagGroup<"invalid-command-line-argument",
+ [IgnoredOptimizationArgument]>;
def UnusedComparison : DiagGroup<"unused-comparison">;
def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">;
def UnneededInternalDecl : DiagGroup<"unneeded-internal-declaration">;
@@ -399,6 +409,7 @@ def UnusedValue : DiagGroup<"unused-value", [UnusedComparison, UnusedResult]>;
def UnusedConstVariable : DiagGroup<"unused-const-variable">;
def UnusedVariable : DiagGroup<"unused-variable",
[UnusedConstVariable]>;
+def UnusedLocalTypedef : DiagGroup<"unused-local-typedef">;
def UnusedPropertyIvar : DiagGroup<"unused-property-ivar">;
def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">;
def UserDefinedLiterals : DiagGroup<"user-defined-literals">;
@@ -426,6 +437,9 @@ def DeallocInCategory:DiagGroup<"dealloc-in-category">;
def SelectorTypeMismatch : DiagGroup<"selector-type-mismatch">;
def Selector : DiagGroup<"selector", [SelectorTypeMismatch]>;
def Protocol : DiagGroup<"protocol">;
+def AtProtocol : DiagGroup<"at-protocol">;
+def PropertyAccessDotSyntax: DiagGroup<"property-access-dot-syntax">;
+def PropertyAttr : DiagGroup<"property-attribute-mismatch">;
def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">;
def VariadicMacros : DiagGroup<"variadic-macros">;
@@ -520,7 +534,7 @@ def Unused : DiagGroup<"unused",
[UnusedArgument, UnusedFunction, UnusedLabel,
// UnusedParameter, (matches GCC's behavior)
// UnusedMemberFunction, (clean-up llvm before enabling)
- UnusedPrivateField,
+ UnusedPrivateField, UnusedLocalTypedef,
UnusedValue, UnusedVariable, UnusedPropertyIvar]>,
DiagCategory<"Unused Entity Issue">;
@@ -585,10 +599,14 @@ def Most : DiagGroup<"most", [
def ThreadSafetyAttributes : DiagGroup<"thread-safety-attributes">;
def ThreadSafetyAnalysis : DiagGroup<"thread-safety-analysis">;
def ThreadSafetyPrecise : DiagGroup<"thread-safety-precise">;
+def ThreadSafetyReference : DiagGroup<"thread-safety-reference">;
+def ThreadSafetyNegative : DiagGroup<"thread-safety-negative">;
def ThreadSafety : DiagGroup<"thread-safety",
[ThreadSafetyAttributes,
ThreadSafetyAnalysis,
- ThreadSafetyPrecise]>;
+ ThreadSafetyPrecise,
+ ThreadSafetyReference]>;
+def ThreadSafetyVerbose : DiagGroup<"thread-safety-verbose">;
def ThreadSafetyBeta : DiagGroup<"thread-safety-beta">;
// Uniqueness Analysis warnings
@@ -614,6 +632,8 @@ def : DiagGroup<"int-conversions",
[IntConversion]>; // -Wint-conversions = -Wint-conversion
def : DiagGroup<"vector-conversions",
[VectorConversion]>; // -Wvector-conversions = -Wvector-conversion
+def : DiagGroup<"unused-local-typedefs", [UnusedLocalTypedef]>;
+ // -Wunused-local-typedefs = -Wunused-local-typedef
// A warning group for warnings that we want to have on by default in clang,
// but which aren't on by default in GCC.
@@ -624,15 +644,17 @@ def NonGCC : DiagGroup<"non-gcc",
// earlier C++ versions.
def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11LongLong]>;
-// A warning group for warnings about using C++1y features as extensions in
+// A warning group for warnings about using C++14 features as extensions in
// earlier C++ versions.
-def CXX1y : DiagGroup<"c++1y-extensions">;
+def CXX14 : DiagGroup<"c++14-extensions">;
// A warning group for warnings about using C++1z features as extensions in
// earlier C++ versions.
def CXX1z : DiagGroup<"c++1z-extensions">;
def : DiagGroup<"c++0x-extensions", [CXX11]>;
+def : DiagGroup<"c++1y-extensions", [CXX14]>;
+
def DelegatingCtorCycles :
DiagGroup<"delegating-ctor-cycles">;
@@ -704,7 +726,18 @@ def RemarkBackendPlugin : DiagGroup<"remark-backend-plugin">;
def BackendOptimizationRemark : DiagGroup<"pass">;
def BackendOptimizationRemarkMissed : DiagGroup<"pass-missed">;
def BackendOptimizationRemarkAnalysis : DiagGroup<"pass-analysis">;
+def BackendOptimizationFailure : DiagGroup<"pass-failed">;
// Instrumentation based profiling warnings.
def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">;
+
+// AddressSanitizer frontent instrumentation remarks.
+def SanitizeAddressRemarks : DiagGroup<"sanitize-address">;
+
+// Issues with serialized diagnostics.
+def SerializedDiagnostics : DiagGroup<"serialized-diagnostics">;
+
+// A warning group for warnings about code that clang accepts when
+// compiling CUDA C/C++ but which is not compatible with the CUDA spec.
+def CudaCompat : DiagGroup<"cuda-compat">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index 8eba2f65ba..99b469d70e 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_DIAGNOSTICIDS_H
-#define LLVM_CLANG_DIAGNOSTICIDS_H
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -33,7 +33,7 @@ namespace clang {
DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + 100,
DIAG_START_LEX = DIAG_START_SERIALIZATION + 120,
DIAG_START_PARSE = DIAG_START_LEX + 300,
- DIAG_START_AST = DIAG_START_PARSE + 400,
+ DIAG_START_AST = DIAG_START_PARSE + 500,
DIAG_START_COMMENT = DIAG_START_AST + 100,
DIAG_START_SEMA = DIAG_START_COMMENT + 100,
DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000,
@@ -67,6 +67,15 @@ namespace clang {
Error = 4, ///< Present this diagnostic as an error.
Fatal = 5 ///< Present this diagnostic as a fatal error.
};
+
+ /// Flavors of diagnostics we can emit. Used to filter for a particular
+ /// kind of diagnostic (for instance, for -W/-R flags).
+ enum class Flavor {
+ WarningOrError, ///< A diagnostic that indicates a problem or potential
+ ///< problem. Can be made fatal by -Werror.
+ Remark ///< A diagnostic that indicates normal progress through
+ ///< compilation.
+ };
}
class DiagnosticMapping {
@@ -228,15 +237,16 @@ public:
///
/// \param[out] Diags - On return, the diagnostics in the group.
/// \returns \c true if the given group is unknown, \c false otherwise.
- bool getDiagnosticsInGroup(StringRef Group,
+ bool getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group,
SmallVectorImpl<diag::kind> &Diags) const;
/// \brief Get the set of all diagnostic IDs.
- void getAllDiagnostics(SmallVectorImpl<diag::kind> &Diags) const;
+ void getAllDiagnostics(diag::Flavor Flavor,
+ SmallVectorImpl<diag::kind> &Diags) const;
- /// \brief Get the warning option with the closest edit distance to the given
- /// group name.
- static StringRef getNearestWarningOption(StringRef Group);
+ /// \brief Get the diagnostic option with the closest edit distance to the
+ /// given group name.
+ static StringRef getNearestOption(diag::Flavor Flavor, StringRef Group);
private:
/// \brief Classify the specified diagnostic ID into a Level, consumable by
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 86def87883..2fcfa02c39 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -161,8 +161,8 @@ def err_invalid_suffix_integer_constant : Error<
def err_invalid_suffix_float_constant : Error<
"invalid suffix '%0' on floating constant">;
def warn_cxx11_compat_digit_separator : Warning<
- "digit separators are incompatible with C++ standards before C++1y">,
- InGroup<CXXPre1yCompat>, DefaultIgnore;
+ "digit separators are incompatible with C++ standards before C++14">,
+ InGroup<CXXPre14Compat>, DefaultIgnore;
def err_digit_separator_not_between_digits : Error<
"digit separator cannot appear at %select{start|end}0 of digit sequence">;
def warn_extraneous_char_constant : Warning<
@@ -182,11 +182,11 @@ def ext_hexconstant_invalid : Extension<
"hexadecimal floating constants are a C99 feature">, InGroup<C99>;
def ext_binary_literal : Extension<
"binary integer literals are a GNU extension">, InGroup<GNUBinaryLiteral>;
-def ext_binary_literal_cxx1y : Extension<
- "binary integer literals are a C++1y extension">, InGroup<CXX1y>;
+def ext_binary_literal_cxx14 : Extension<
+ "binary integer literals are a C++14 extension">, InGroup<CXX14>;
def warn_cxx11_compat_binary_literal : Warning<
- "binary integer literals are incompatible with C++ standards before C++1y">,
- InGroup<CXXPre1yCompatPedantic>, DefaultIgnore;
+ "binary integer literals are incompatible with C++ standards before C++14">,
+ InGroup<CXXPre14CompatPedantic>, DefaultIgnore;
def err_pascal_string_too_long : Error<"Pascal string is too long">;
def err_octal_escape_too_large : Error<"octal escape sequence out of range">;
def err_hex_escape_too_large : Error<"hex escape sequence out of range">;
@@ -201,6 +201,9 @@ def warn_c99_compat_unicode_literal : Warning<
def warn_cxx98_compat_unicode_literal : Warning<
"unicode literals are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
+def warn_cxx14_compat_u8_character_literal : Warning<
+ "unicode literals are incompatible with C++ standards before C++1z">,
+ InGroup<CXXPre1zCompat>, DefaultIgnore;
def warn_cxx11_compat_user_defined_literal : Warning<
"identifier after literal will be treated as a user-defined literal suffix "
"in C++11">, InGroup<CXX11Compat>, DefaultIgnore;
@@ -615,9 +618,6 @@ def warn_auto_module_import : Warning<
def warn_uncovered_module_header : Warning<
"umbrella header for module '%0' does not include header '%1'">,
InGroup<IncompleteUmbrella>;
-def warn_forgotten_module_header : Warning<
- "header '%0' is included in module '%1' but not listed in module map">,
- InGroup<IncompleteModule>, DefaultIgnore;
def err_expected_id_building_module : Error<
"expected a module name in '__building_module' expression">;
def error_use_of_private_header_outside_module : Error<
diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h
index a9c8cf5fc2..3e4d0eefbc 100644
--- a/include/clang/Basic/DiagnosticOptions.h
+++ b/include/clang/Basic/DiagnosticOptions.h
@@ -58,6 +58,10 @@ public:
/// prefixes removed.
std::vector<std::string> Warnings;
+ /// The list of -R... options used to alter the diagnostic mappings, with the
+ /// prefixes removed.
+ std::vector<std::string> Remarks;
+
public:
// Define accessors/mutators for diagnostic options of enumeration type.
#define DIAGOPT(Name, Bits, Default)
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 69e2fb3110..6bf19108b1 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -121,6 +121,8 @@ def ext_c11_alignment : Extension<
def ext_c11_noreturn : Extension<
"_Noreturn functions are a C11-specific feature">, InGroup<C11>;
+def err_c11_noreturn_misplaced : Error<
+ "'_Noreturn' keyword must precede function declarator">;
def ext_gnu_indirect_goto : Extension<
"use of GNU indirect-goto extension">, InGroup<GNULabelsAsValue>;
@@ -167,6 +169,9 @@ def err_expected_fn_body : Error<
def warn_attribute_on_function_definition : Warning<
"GCC does not allow %0 attribute in this position on a function definition">,
InGroup<GccCompat>;
+def warn_gcc_attribute_location : Warning<
+ "GCC does not allow an attribute in this position on a function declaration">,
+ InGroup<GccCompat>;
def warn_attribute_no_decl : Warning<
"attribute %0 ignored, because it is not attached to a declaration">,
InGroup<IgnoredAttributes>;
@@ -194,11 +199,19 @@ def err_expected_semi_after_namespace_name : Error<
"expected ';' after namespace name">;
def err_unexpected_namespace_attributes_alias : Error<
"attributes cannot be specified on namespace alias">;
+def err_unexpected_nested_namespace_attribute : Error<
+ "attributes cannot be specified on a nested namespace definition">;
def err_inline_namespace_alias : Error<"namespace alias cannot be inline">;
def err_namespace_nonnamespace_scope : Error<
"namespaces can only be defined in global or namespace scope">;
-def err_nested_namespaces_with_double_colon : Error<
- "nested namespace definition must define each namespace separately">;
+def ext_nested_namespace_definition : ExtWarn<
+ "nested namespace definition is a C++1z extension; "
+ "define each namespace separately">, InGroup<CXX1z>;
+def warn_cxx14_compat_nested_namespace_definition : Warning<
+ "nested namespace definition is incompatible with C++ standards before C++1z">,
+ InGroup<CXXPre1zCompat>, DefaultIgnore;
+def err_inline_nested_namespace_definition : Error<
+ "nested namespace definition cannot be 'inline'">;
def err_expected_semi_after_attribute_list : Error<
"expected ';' after attribute list">;
def err_expected_semi_after_static_assert : Error<
@@ -268,10 +281,10 @@ def ext_auto_storage_class : ExtWarn<
"'auto' storage class specifier is not permitted in C++11, and will not "
"be supported in future releases">, InGroup<DiagGroup<"auto-storage-class">>;
def ext_decltype_auto_type_specifier : ExtWarn<
- "'decltype(auto)' type specifier is a C++1y extension">, InGroup<CXX1y>;
+ "'decltype(auto)' type specifier is a C++14 extension">, InGroup<CXX14>;
def warn_cxx11_compat_decltype_auto_type_specifier : Warning<
"'decltype(auto)' type specifier is incompatible with C++ standards before "
- "C++1y">, InGroup<CXXPre1yCompat>, DefaultIgnore;
+ "C++14">, InGroup<CXXPre14Compat>, DefaultIgnore;
def ext_for_range : ExtWarn<
"range-based for loop is a C++11 extension">, InGroup<CXX11>;
def warn_cxx98_compat_for_range : Warning<
@@ -280,7 +293,7 @@ def warn_cxx98_compat_for_range : Warning<
def ext_for_range_identifier : ExtWarn<
"range-based for loop with implicit deduced type is a C++1z extension">,
InGroup<CXX1z>;
-def warn_cxx1y_compat_for_range_identifier : Warning<
+def warn_cxx14_compat_for_range_identifier : Warning<
"range-based for loop with implicit deduced type is incompatible with "
"C++ standards before C++1z">,
InGroup<CXXPre1zCompat>, DefaultIgnore;
@@ -303,6 +316,8 @@ def err_expected_class_name_not_template :
Error<"'typename' is redundant; base classes are implicitly types">;
def err_unspecified_vla_size_with_static : Error<
"'static' may not be used with an unspecified variable length array size">;
+def err_unspecified_size_with_static : Error<
+ "'static' may not be used without an array size">;
def warn_deprecated_register : Warning<
"'register' storage class specifier is deprecated">,
InGroup<DeprecatedRegister>;
@@ -332,10 +347,12 @@ def err_invalid_vector_decl_spec_combination : Error<
def err_invalid_pixel_decl_spec_combination : Error<
"'__pixel' must be preceded by '__vector'. "
"'%0' declaration specifier not allowed here">;
-def err_invalid_vector_decl_spec : Error<
- "cannot use '%0' with '__vector'">;
def err_invalid_vector_bool_decl_spec : Error<
"cannot use '%0' with '__vector bool'">;
+def err_invalid_vector_double_decl_spec : Error <
+ "use of 'double' with '__vector' requires VSX support to be enabled (available on the POWER7 or later)">;
+def err_invalid_vector_long_double_decl_spec : Error<
+ "cannot use 'long double' with '__vector'">;
def warn_vector_long_decl_spec_combination : Warning<
"Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>;
def err_friend_invalid_in_context : Error<
@@ -363,6 +380,8 @@ def err_function_definition_not_allowed : Error<
"function definition is not allowed here">;
def err_expected_end_of_enumerator : Error<
"expected '= constant-expression' or end of enumerator definition">;
+def err_expected_coloncolon_after_super : Error<
+ "expected '::' after '__super'">;
/// Objective-C parser diagnostics
def err_expected_minus_or_plus : Error<
@@ -477,6 +496,8 @@ def ext_ellipsis_exception_spec : Extension<
InGroup<Microsoft>;
def err_dynamic_and_noexcept_specification : Error<
"cannot have both throw() and noexcept() clause on the same function">;
+def err_except_spec_unparsed : Error<
+ "unexpected end of exception specification">;
def warn_cxx98_compat_noexcept_decl : Warning<
"noexcept specifications are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
@@ -487,6 +508,8 @@ def err_constructor_bad_name : Error<
"missing return type for function %0; did you mean the constructor name %1?">;
def err_destructor_tilde_identifier : Error<
"expected a class name after '~' to name a destructor">;
+def err_destructor_tilde_scope : Error<
+ "'~' in destructor name should be after nested name specifier">;
def err_destructor_template_id : Error<
"destructor name %0 does not refer to a template">;
def err_default_arg_unparsed : Error<
@@ -498,11 +521,24 @@ def note_bracket_depth : Note<
def err_misplaced_ellipsis_in_declaration : Error<
"'...' must %select{immediately precede declared identifier|"
"be innermost component of anonymous pack declaration}0">;
+def warn_misplaced_ellipsis_vararg : Warning<
+ "'...' in this location creates a C-style varargs function"
+ "%select{, not a function parameter pack|}0">,
+ InGroup<DiagGroup<"ambiguous-ellipsis">>;
+def note_misplaced_ellipsis_vararg_existing_ellipsis : Note<
+ "preceding '...' declares a function parameter pack">;
+def note_misplaced_ellipsis_vararg_add_ellipsis : Note<
+ "place '...' %select{immediately before declared identifier|here}0 "
+ "to declare a function parameter pack">;
+def note_misplaced_ellipsis_vararg_add_comma : Note<
+ "insert ',' before '...' to silence this warning">;
def ext_abstract_pack_declarator_parens : ExtWarn<
"ISO C++11 requires a parenthesized pack declaration to have a name">,
InGroup<DiagGroup<"anonymous-pack-parens">>;
def err_function_is_not_record : Error<
"unexpected %0 in function call; perhaps remove the %0?">;
+def err_super_in_using_declaration : Error<
+ "'__super' cannot be used with a using declaration">;
// C++ derived classes
def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
@@ -529,6 +565,10 @@ def warn_cxx98_compat_noexcept_expr : Warning<
def warn_cxx98_compat_nullptr : Warning<
"'nullptr' is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
+def warn_cxx14_compat_attribute : Warning<
+ "attributes on %select{a namespace|an enumerator}0 declaration are "
+ "incompatible with C++ standards before C++1z">,
+ InGroup<CXXPre1zCompat>, DefaultIgnore;
def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def warn_cxx98_compat_attribute : Warning<
@@ -576,7 +616,7 @@ def err_class_on_template_template_param : Error<
def ext_template_template_param_typename : ExtWarn<
"template template parameter using 'typename' is a C++1z extension">,
InGroup<CXX1z>;
-def warn_cxx1y_compat_template_template_param_typename : Warning<
+def warn_cxx14_compat_template_template_param_typename : Warning<
"template template parameter using 'typename' is "
"incompatible with C++ standards before C++1z">,
InGroup<CXXPre1zCompat>, DefaultIgnore;
@@ -597,14 +637,16 @@ def warn_cxx11_right_shift_in_template_arg : Warning<
def warn_cxx98_compat_two_right_angle_brackets : Warning<
"consecutive right angle brackets are incompatible with C++98 (use '> >')">,
InGroup<CXX98Compat>, DefaultIgnore;
+def err_templated_invalid_declaration : Error<
+ "a static_assert declaration cannot be a template">;
def err_multiple_template_declarators : Error<
- "%select{|a template declaration|an explicit template specialization|"
- "an explicit template instantiation}0 can "
- "only %select{|declare|declare|instantiate}0 a single entity">;
+ "%select{|a template declaration|an explicit template specialization|"
+ "an explicit template instantiation}0 can "
+ "only %select{|declare|declare|instantiate}0 a single entity">;
def err_explicit_instantiation_with_definition : Error<
- "explicit template instantiation cannot have a definition; if this "
- "definition is meant to be an explicit specialization, add '<>' after the "
- "'template' keyword">;
+ "explicit template instantiation cannot have a definition; if this "
+ "definition is meant to be an explicit specialization, add '<>' after the "
+ "'template' keyword">;
def err_template_defn_explicit_instantiation : Error<
"%select{function|class|variable}0 cannot be defined in an explicit instantiation; if this "
"declaration is meant to be a %select{function|class|variable}0 definition, remove the 'template' keyword">;
@@ -612,7 +654,7 @@ def err_friend_explicit_instantiation : Error<
"friend cannot be declared in an explicit instantiation; if this "
"declaration is meant to be a friend declaration, remove the 'template' keyword">;
def err_explicit_instantiation_enum : Error<
- "enumerations cannot be explicitly instantiated">;
+ "enumerations cannot be explicitly instantiated">;
def err_expected_template_parameter : Error<"expected template parameter">;
def err_missing_dependent_template_keyword : Error<
@@ -654,7 +696,18 @@ def err_explicit_spec_non_template : Error<
def err_default_template_template_parameter_not_template : Error<
"default template argument for a template template parameter must be a class "
"template">;
-
+
+def ext_fold_expression : ExtWarn<
+ "pack fold expression is a C++1z extension">,
+ InGroup<CXX1z>;
+def warn_cxx14_compat_fold_expression : Warning<
+ "pack fold expression is incompatible with C++ standards before C++1z">,
+ InGroup<CXXPre1zCompat>, DefaultIgnore;
+def err_expected_fold_operator : Error<
+ "expected a foldable binary operator in fold expression">;
+def err_fold_operator_mismatch : Error<
+ "operators in fold expression must be the same">;
+
def err_ctor_init_missing_comma : Error<
"missing ',' between base or member initializers">;
@@ -699,7 +752,7 @@ def err_alias_declaration_not_identifier : Error<
"name defined in alias declaration must be an identifier">;
def err_alias_declaration_specialization : Error<
"%select{partial specialization|explicit specialization|explicit instantiation}0 of alias templates is not permitted">;
-
+
// C++11 override control
def ext_override_control_keyword : ExtWarn<
"'%0' keyword is a C++11 extension">, InGroup<CXX11>;
@@ -751,6 +804,9 @@ def err_lambda_missing_parens : Error<
// Availability attribute
def err_expected_version : Error<
"expected a version of the form 'major[.minor[.subminor]]'">;
+def warn_expected_consistent_version_separator : Warning<
+ "use same version number separators '_' or '.'; as in "
+ "'major[.minor[.subminor]]'">, InGroup<Availability>;
def err_zero_version : Error<
"version number must have non-zero major, minor, or sub-minor version">;
def err_availability_expected_platform : Error<
@@ -800,6 +856,9 @@ def warn_pragma_expected_section_push_pop_or_name : Warning<
def warn_pragma_expected_section_label_or_name : Warning<
"expected a stack label or a string literal for the section name in '#pragma %0' - ignored">,
InGroup<IgnoredPragmas>;
+def warn_pragma_expected_init_seg : Warning<
+ "expected 'compiler', 'lib', 'user', or a string literal for the section name in '#pragma %0' - ignored">,
+ InGroup<IgnoredPragmas>;
def warn_pragma_expected_integer : Warning<
"expected integer between %0 and %1 inclusive in '#pragma %2' - ignored">,
InGroup<IgnoredPragmas>;
@@ -811,6 +870,11 @@ def warn_pragma_extra_tokens_at_eol : Warning<
InGroup<IgnoredPragmas>;
def warn_pragma_expected_punc : Warning<
"expected ')' or ',' in '#pragma %0'">, InGroup<IgnoredPragmas>;
+def warn_pragma_expected_non_wide_string : Warning<
+ "expected non-wide string literal in '#pragma %0'">, InGroup<IgnoredPragmas>;
+// - Generic errors
+def err_pragma_missing_argument : Error<
+ "missing argument to '#pragma %0'%select{|; expected %2}1">;
// - #pragma options
def warn_pragma_options_expected_align : Warning<
"expected 'align' following '#pragma options' - ignored">,
@@ -841,6 +905,11 @@ def warn_pragma_pack_malformed : Warning<
def warn_pragma_unused_expected_var : Warning<
"expected '#pragma unused' argument to be a variable name">,
InGroup<IgnoredPragmas>;
+// - #pragma init_seg
+def warn_pragma_init_seg_unsupported_target : Warning<
+ "'#pragma init_seg' is only supported when targeting a "
+ "Microsoft environment">,
+ InGroup<IgnoredPragmas>;
// - #pragma fp_contract
def err_pragma_fp_contract_scope : Error<
"'#pragma fp_contract' can only appear at file scope or at the start of a "
@@ -858,8 +927,6 @@ def err_pragma_pointers_to_members_unknown_kind : Error<
"unexpected %0, expected to see one of %select{|'best_case', 'full_generality', }1"
"'single_inheritance', 'multiple_inheritance', or 'virtual_inheritance'">;
// - #pragma clang optimize on/off
-def err_pragma_optimize_missing_argument : Error<
- "missing argument to '#pragma clang optimize'; expected 'on' or 'off'">;
def err_pragma_optimize_invalid_argument : Error<
"unexpected argument '%0' to '#pragma clang optimize'; "
"expected 'on' or 'off'">;
@@ -901,18 +968,30 @@ def err_omp_unknown_directive : Error<
def err_omp_unexpected_directive : Error<
"unexpected OpenMP directive '#pragma omp %0'">;
def err_omp_expected_punc : Error<
- "expected ',' or ')' in '%0' clause">;
+ "expected ',' or ')' in '%0' %select{clause|directive}1">;
def err_omp_unexpected_clause : Error<
"unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
def err_omp_more_one_clause : Error<
"directive '#pragma omp %0' cannot contain more than one '%1' clause">;
+def err_omp_immediate_directive : Error<
+ "'#pragma omp %0' cannot be an immediate substatement">;
+def err_omp_expected_identifier_for_critical : Error<
+ "expected identifier specifying the name of the 'omp critical' directive">;
// Pragma loop support.
+def err_pragma_loop_missing_argument : Error<
+ "missing argument; expected %select{an integer value|"
+ "'%select{enable|full}1' or 'disable'}0">;
def err_pragma_loop_invalid_option : Error<
"%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
"vectorize_width, interleave, interleave_count, unroll, or unroll_count">;
-def err_pragma_loop_missing_argument : Error<
- "missing argument to loop pragma %0">;
+def err_pragma_invalid_keyword : Error<
+ "invalid argument; expected '%select{enable|full}0' or 'disable'">;
+
+// Pragma unroll support.
+def warn_pragma_unroll_cuda_value_in_parens : Warning<
+ "argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">,
+ InGroup<CudaCompat>;
} // end of Parse Issue category.
let CategoryName = "Modules Issue" in {
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 5ab9aef94e..aa93e63a4d 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -84,6 +84,9 @@ def note_ice_conversion_here : Note<
def err_ice_ambiguous_conversion : Error<
"ambiguous conversion from type %0 to an integral or unscoped "
"enumeration type">;
+def err_ice_too_large : Error<
+ "integer constant expression evaluates to value %0 that cannot be "
+ "represented in a %1-bit %select{signed|unsigned}2 integer type">;
// Semantic analysis of constant literals.
def ext_predef_outside_function : Warning<
@@ -172,6 +175,9 @@ def warn_unused_parameter : Warning<"unused parameter %0">,
InGroup<UnusedParameter>, DefaultIgnore;
def warn_unused_variable : Warning<"unused variable %0">,
InGroup<UnusedVariable>, DefaultIgnore;
+def warn_unused_local_typedef : Warning<
+ "unused %select{typedef|type alias}0 %1">,
+ InGroup<UnusedLocalTypedef>, DefaultIgnore;
def warn_unused_property_backing_ivar :
Warning<"ivar %0 which backs the property is not "
"referenced in this property's accessor">,
@@ -349,7 +355,7 @@ def err_invalid_thread : Error<
def err_thread_non_global : Error<
"'%0' variables must have global storage">;
def err_thread_unsupported : Error<
- "thread-local storage is unsupported for the current target">;
+ "thread-local storage is not supported for the current target">;
def warn_maybe_falloff_nonvoid_function : Warning<
"control may reach end of non-void function">,
@@ -387,21 +393,11 @@ def note_unreachable_silence : Note<
/// Built-in functions.
def ext_implicit_lib_function_decl : ExtWarn<
"implicitly declaring library function '%0' with type %1">;
-def note_please_include_header : Note<
- "please include the header <%0> or explicitly provide a "
- "declaration for '%1'">;
+def note_include_header_or_declare : Note<
+ "include the header <%0> or explicitly provide a declaration for '%1'">;
def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">;
-def warn_implicit_decl_requires_stdio : Warning<
- "declaration of built-in function '%0' requires inclusion of the header "
- "<stdio.h>">,
- InGroup<BuiltinRequiresHeader>;
-def warn_implicit_decl_requires_setjmp : Warning<
- "declaration of built-in function '%0' requires inclusion of the header "
- "<setjmp.h>">,
- InGroup<BuiltinRequiresHeader>;
-def warn_implicit_decl_requires_ucontext : Warning<
- "declaration of built-in function '%0' requires inclusion of the header "
- "<ucontext.h>">,
+def warn_implicit_decl_requires_sysheader : Warning<
+ "declaration of built-in function '%1' requires inclusion of the header <%0>">,
InGroup<BuiltinRequiresHeader>;
def warn_redecl_library_builtin : Warning<
"incompatible redeclaration of library function %0">,
@@ -454,6 +450,14 @@ def note_strncat_wrong_size : Note<
"change the argument to be the free space in the destination buffer minus "
"the terminating null byte">;
+def warn_assume_side_effects : Warning<
+ "the argument to %0 has side effects that will be discarded">,
+ InGroup<DiagGroup<"assume">>;
+
+def warn_memcpy_chk_overflow : Warning<
+ "%0 will always overflow destination buffer">,
+ InGroup<DiagGroup<"builtin-memcpy-chk-size">>;
+
/// main()
// static main() is not an error in C, just in C++.
def warn_static_main : Warning<"'main' should not be declared static">,
@@ -527,6 +531,11 @@ def warn_cxx_ms_struct :
"with base classes or virtual functions">,
DefaultError, InGroup<IncompatibleMSStruct>;
def err_section_conflict : Error<"%0 causes a section type conflict with %1">;
+def err_no_base_classes : Error<"invalid use of '__super', %0 has no base classes">;
+def err_invalid_super_scope : Error<"invalid use of '__super', "
+ "this keyword can only be used inside class or member function scope">;
+def err_super_in_lambda_unsupported : Error<
+ "use of '__super' inside a lambda is unsupported">;
def warn_pragma_unused_undeclared_var : Warning<
"undeclared variable %0 used as an argument for '#pragma unused'">,
@@ -542,15 +551,14 @@ def err_pragma_pop_visibility_mismatch : Error<
"#pragma visibility pop with no matching #pragma visibility push">;
def note_surrounding_namespace_starts_here : Note<
"surrounding namespace with visibility attribute starts here">;
-def err_pragma_loop_invalid_value : Error<
- "invalid argument; expected a positive integer value">;
-def err_pragma_loop_invalid_keyword : Error<
- "invalid argument; expected 'enable' or 'disable'">;
+def err_pragma_loop_invalid_argument_type : Error<
+ "invalid argument of type %0; expected an integer type">;
+def err_pragma_loop_invalid_argument_value : Error<
+ "%select{invalid value '%0'; must be positive|value '%0' is too large}1">;
def err_pragma_loop_compatibility : Error<
- "%select{incompatible|duplicate}0 directives '%1(%2)' and '%3(%4)'">;
+ "%select{incompatible|duplicate}0 directives '%1' and '%2'">;
def err_pragma_loop_precedes_nonloop : Error<
- "expected a for, while, or do-while loop to follow the '#pragma clang loop' "
- "directive">;
+ "expected a for, while, or do-while loop to follow '%0'">;
/// Objective-C parser diagnostics
def err_duplicate_class_def : Error<
@@ -570,14 +578,18 @@ def err_protocol_has_circular_dependency : Error<
"protocol has circular dependency">;
def err_undeclared_protocol : Error<"cannot find protocol declaration for %0">;
def warn_undef_protocolref : Warning<"cannot find protocol definition for %0">;
+def warn_atprotocol_protocol : Warning<
+ "@protocol is using a forward protocol declaration of %0">, InGroup<AtProtocol>;
def warn_readonly_property : Warning<
"attribute 'readonly' of property %0 restricts attribute "
"'readwrite' of property inherited from %1">;
def warn_property_attribute : Warning<
- "'%1' attribute on property %0 does not match the property inherited from %2">;
+ "'%1' attribute on property %0 does not match the property inherited from %2">,
+ InGroup<PropertyAttr>;
def warn_property_types_are_incompatible : Warning<
- "property type %0 is incompatible with type %1 inherited from %2">;
+ "property type %0 is incompatible with type %1 inherited from %2">,
+ InGroup<DiagGroup<"incompatible-property-type">>;
def warn_protocol_property_mismatch : Warning<
"property of type %0 was selected for synthesis">,
InGroup<DiagGroup<"protocol-property-synthesis-ambiguity">>;
@@ -594,6 +606,8 @@ def note_class_declared : Note<
"class is declared here">;
def note_receiver_class_declared : Note<
"receiver is instance of class declared here">;
+def note_receiver_expr_here : Note<
+ "receiver expression is here">;
def note_receiver_is_id : Note<
"receiver is treated with 'id' type for purpose of method lookup">;
def note_suppressed_class_declare : Note<
@@ -717,6 +731,11 @@ def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
def warn_duplicate_method_decl :
Warning<"multiple declarations of method %0 found and ignored">,
InGroup<MethodDuplicate>, DefaultIgnore;
+def warn_objc_cdirective_format_string :
+ Warning<"using %0 directive in %select{NSString|CFString}1 "
+ "which is being passed as a formatting argument to the formatting "
+ "%select{method|CFfunction}2">,
+ InGroup<ObjCCStringFormat>, DefaultIgnore;
def err_objc_var_decl_inclass :
Error<"cannot declare variable inside @interface or @protocol">;
def error_missing_method_context : Error<
@@ -745,7 +764,8 @@ def warn_objc_property_default_assign_on_object : Warning<
"default property attribute 'assign' not appropriate for non-GC object">,
InGroup<ObjCPropertyNoAttribute>;
def warn_property_attr_mismatch : Warning<
- "property attribute in class extension does not match the primary class">;
+ "property attribute in class extension does not match the primary class">,
+ InGroup<PropertyAttr>;
def warn_property_implicitly_mismatched : Warning <
"primary property declaration is implicitly strong while redeclaration "
"in class extension is weak">,
@@ -785,6 +805,11 @@ def warn_no_autosynthesis_property : Warning<
"%0 because it is 'readwrite' but it will be synthesized 'readonly' "
"via another property">,
InGroup<ObjCNoPropertyAutoSynthesis>;
+def warn_autosynthesis_property_in_superclass : Warning<
+ "auto property synthesis will not synthesize property "
+ "%0; it will be implemented by its superclass, use @dynamic to "
+ "acknowledge intention">,
+ InGroup<ObjCNoPropertyAutoSynthesis>;
def warn_autosynthesis_property_ivar_match :Warning<
"autosynthesized property %0 will use %select{|synthesized}1 instance variable "
"%2, not existing instance variable %3">,
@@ -934,7 +959,7 @@ def err_static_assert_expression_is_not_constant : Error<
def err_static_assert_failed : Error<"static_assert failed%select{ %1|}0">;
def ext_static_assert_no_message : ExtWarn<
"static_assert with no message is a C++1z extension">, InGroup<CXX1z>;
-def warn_cxx1y_compat_static_assert_no_message : Warning<
+def warn_cxx14_compat_static_assert_no_message : Warning<
"static_assert with no message is incompatible with C++ standards before C++1z">,
DefaultIgnore, InGroup<CXXPre1zCompat>;
@@ -997,7 +1022,11 @@ def warn_template_qualified_friend_ignored : Warning<
"dependent nested name specifier '%0' for friend template declaration is "
"not supported; ignoring this friend declaration">,
InGroup<UnsupportedFriend>;
-
+def ext_friend_tag_redecl_outside_namespace : ExtWarn<
+ "unqualified friend declaration referring to type outside of the nearest "
+ "enclosing namespace is a Microsoft extension; add a nested name specifier">,
+ InGroup<Microsoft>;
+
def err_invalid_member_in_interface : Error<
"%select{data member |non-public member function |static member function |"
"user-declared constructor|user-declared destructor|operator |"
@@ -1071,12 +1100,13 @@ def err_rref_in_exception_spec : Error<
"rvalue reference type %0 is not allowed in exception specification">;
def err_mismatched_exception_spec : Error<
"exception specification in declaration does not match previous declaration">;
-def warn_mismatched_exception_spec : ExtWarn<
- "exception specification in declaration does not match previous declaration">;
+def ext_mismatched_exception_spec : ExtWarn<
+ "exception specification in declaration does not match previous declaration">,
+ InGroup<Microsoft>;
def err_override_exception_spec : Error<
"exception specification of overriding function is more lax than "
"base version">;
-def warn_override_exception_spec : ExtWarn<
+def ext_override_exception_spec : ExtWarn<
"exception specification of overriding function is more lax than "
"base version">, InGroup<Microsoft>;
def err_incompatible_exception_specs : Error<
@@ -1087,6 +1117,8 @@ def warn_missing_exception_specification : Warning<
"%0 is missing exception specification '%1'">;
def err_noexcept_needs_constant_expression : Error<
"argument to noexcept specifier must be a constant expression">;
+def err_exception_spec_not_parsed : Error<
+ "exception specification is not available until end of class definition">;
// C++ access checking
def err_class_redeclared_with_different_access : Error<
@@ -1100,7 +1132,7 @@ def ext_ms_using_declaration_inaccessible : ExtWarn<
def err_access_ctor : Error<
"calling a %select{private|protected}0 constructor of class %2">,
AccessControl;
-def ext_rvalue_to_reference_access_ctor : ExtWarn<
+def ext_rvalue_to_reference_access_ctor : Extension<
"C++98 requires an accessible copy constructor for class %2 when binding "
"a reference to a temporary; was %select{private|protected}0">,
AccessControl, InGroup<BindToTemporaryCopy>;
@@ -1228,7 +1260,7 @@ def err_member_function_initialization : Error<
"initializer on function does not look like a pure-specifier">;
def err_non_virtual_pure : Error<
"%0 is not virtual and cannot be declared pure">;
-def warn_pure_function_definition : ExtWarn<
+def ext_pure_function_definition : ExtWarn<
"function definition with pure-specifier is a Microsoft extension">,
InGroup<Microsoft>;
def err_implicit_object_parameter_init : Error<
@@ -1507,6 +1539,9 @@ def note_block_var_fixit_add_initialization : Note<
def note_in_omitted_aggregate_initializer : Note<
"in implicit initialization of %select{array element %1|field %1}0 "
"with omitted initializer">;
+def note_in_reference_temporary_list_initializer : Note<
+ "in initialization of temporary of type %0 created to "
+ "list-initialize this reference">;
def note_var_fixit_add_initialization : Note<
"initialize the variable %0 to silence this warning">;
def note_uninit_fixit_remove_cond : Note<
@@ -1524,7 +1559,7 @@ def err_temp_copy_no_viable : Error<
"returning object|throwing object|copying member subobject|copying array "
"element|allocating object|copying temporary|initializing base subobject|"
"initializing vector element|capturing value}0 of type %1">;
-def ext_rvalue_to_reference_temp_copy_no_viable : ExtWarn<
+def ext_rvalue_to_reference_temp_copy_no_viable : Extension<
"no viable constructor %select{copying variable|copying parameter|"
"returning object|throwing object|copying member subobject|copying array "
"element|allocating object|copying temporary|initializing base subobject|"
@@ -1596,9 +1631,9 @@ def err_auto_new_ctor_multiple_expressions : Error<
"new expression for type %0 contains multiple constructor arguments">;
def err_auto_missing_trailing_return : Error<
"'auto' return without trailing return type; deduced return types are a "
- "C++1y extension">;
+ "C++14 extension">;
def err_deduced_return_type : Error<
- "deduced return types are a C++1y extension">;
+ "deduced return types are a C++14 extension">;
def err_trailing_return_without_auto : Error<
"function with trailing return type must specify return type 'auto', not %0">;
def err_trailing_return_in_parens : Error<
@@ -1658,6 +1693,9 @@ def override_keyword_hides_virtual_member_function : Error<
"%select{function|functions}1">;
def err_function_marked_override_not_overriding : Error<
"%0 marked 'override' but does not override any member functions">;
+def warn_function_marked_not_override_overriding : Warning <
+ "%0 overrides a member function but is not marked 'override'">,
+ InGroup<CXX11WarnOverrideMethod>;
def err_class_marked_final_used_as_base : Error<
"base %0 is marked '%select{final|sealed}1'">;
def warn_abstract_final_class : Warning<
@@ -1747,10 +1785,10 @@ def note_for_range_begin_end : Note<
def warn_cxx98_compat_constexpr : Warning<
"'constexpr' specifier is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
-// FIXME: Maybe this should also go in -Wc++1y-compat?
-def warn_cxx1y_compat_constexpr_not_const : Warning<
+// FIXME: Maybe this should also go in -Wc++14-compat?
+def warn_cxx14_compat_constexpr_not_const : Warning<
"'constexpr' non-static member function will not be implicitly 'const' "
- "in C++1y; add 'const' to avoid a change in behavior">,
+ "in C++14; add 'const' to avoid a change in behavior">,
InGroup<DiagGroup<"constexpr-not-const">>;
def err_invalid_constexpr : Error<
"%select{function parameter|typedef|non-static data member}0 "
@@ -1792,28 +1830,28 @@ def err_constexpr_body_invalid_stmt : Error<
"statement not allowed in constexpr %select{function|constructor}0">;
def ext_constexpr_body_invalid_stmt : ExtWarn<
"use of this statement in a constexpr %select{function|constructor}0 "
- "is a C++1y extension">, InGroup<CXX1y>;
+ "is a C++14 extension">, InGroup<CXX14>;
def warn_cxx11_compat_constexpr_body_invalid_stmt : Warning<
"use of this statement in a constexpr %select{function|constructor}0 "
- "is incompatible with C++ standards before C++1y">,
- InGroup<CXXPre1yCompat>, DefaultIgnore;
+ "is incompatible with C++ standards before C++14">,
+ InGroup<CXXPre14Compat>, DefaultIgnore;
def ext_constexpr_type_definition : ExtWarn<
"type definition in a constexpr %select{function|constructor}0 "
- "is a C++1y extension">, InGroup<CXX1y>;
+ "is a C++14 extension">, InGroup<CXX14>;
def warn_cxx11_compat_constexpr_type_definition : Warning<
"type definition in a constexpr %select{function|constructor}0 "
- "is incompatible with C++ standards before C++1y">,
- InGroup<CXXPre1yCompat>, DefaultIgnore;
+ "is incompatible with C++ standards before C++14">,
+ InGroup<CXXPre14Compat>, DefaultIgnore;
def err_constexpr_vla : Error<
"variably-modified type %0 cannot be used in a constexpr "
"%select{function|constructor}1">;
def ext_constexpr_local_var : ExtWarn<
"variable declaration in a constexpr %select{function|constructor}0 "
- "is a C++1y extension">, InGroup<CXX1y>;
+ "is a C++14 extension">, InGroup<CXX14>;
def warn_cxx11_compat_constexpr_local_var : Warning<
"variable declaration in a constexpr %select{function|constructor}0 "
- "is incompatible with C++ standards before C++1y">,
- InGroup<CXXPre1yCompat>, DefaultIgnore;
+ "is incompatible with C++ standards before C++14">,
+ InGroup<CXXPre14Compat>, DefaultIgnore;
def err_constexpr_local_var_static : Error<
"%select{static|thread_local}1 variable not permitted in a constexpr "
"%select{function|constructor}0">;
@@ -1832,14 +1870,14 @@ def err_constexpr_body_no_return : Error<
"no return statement in constexpr function">;
def warn_cxx11_compat_constexpr_body_no_return : Warning<
"constexpr function with no return statements is incompatible with C++ "
- "standards before C++1y">, InGroup<CXXPre1yCompat>, DefaultIgnore;
+ "standards before C++14">, InGroup<CXXPre14Compat>, DefaultIgnore;
def ext_constexpr_body_multiple_return : ExtWarn<
- "multiple return statements in constexpr function is a C++1y extension">,
- InGroup<CXX1y>;
+ "multiple return statements in constexpr function is a C++14 extension">,
+ InGroup<CXX14>;
def warn_cxx11_compat_constexpr_body_multiple_return : Warning<
"multiple return statements in constexpr function "
- "is incompatible with C++ standards before C++1y">,
- InGroup<CXXPre1yCompat>, DefaultIgnore;
+ "is incompatible with C++ standards before C++14">,
+ InGroup<CXXPre14Compat>, DefaultIgnore;
def note_constexpr_body_previous_return : Note<
"previous return statement is here">;
def err_constexpr_function_try_block : Error<
@@ -1899,8 +1937,12 @@ def err_attribute_bad_neon_vector_size : Error<
"Neon vector size must be 64 or 128 bits">;
def err_attribute_unsupported : Error<
"%0 attribute is not supported for this target">;
+// The err_*_attribute_argument_not_int are seperate because they're used by
+// VerifyIntegerConstantExpression.
def err_aligned_attribute_argument_not_int : Error<
"'aligned' attribute requires integer constant">;
+def err_align_value_attribute_argument_not_int : Error<
+ "'align_value' attribute requires integer constant">;
def err_alignas_attribute_wrong_decl_type : Error<
"%0 attribute cannot be applied to a %select{function parameter|"
"variable with 'register' storage class|'catch' variable|bit-field}1">;
@@ -1936,12 +1978,22 @@ def err_attribute_pointers_only : Error<warn_attribute_pointers_only.Text>;
def warn_attribute_return_pointers_only : Warning<
"%0 attribute only applies to return values that are pointers">,
InGroup<IgnoredAttributes>;
+def warn_attribute_return_pointers_refs_only : Warning<
+ "%0 attribute only applies to return values that are pointers or references">,
+ InGroup<IgnoredAttributes>;
+def warn_attribute_pointer_or_reference_only : Warning<
+ "%0 attribute only applies to a pointer or reference (%1 is invalid)">,
+ InGroup<IgnoredAttributes>;
def err_attribute_no_member_pointers : Error<
"%0 attribute cannot be used with pointers to members">;
def err_attribute_invalid_implicit_this_argument : Error<
"%0 attribute is invalid for the implicit this argument">;
def err_ownership_type : Error<
"%0 attribute only applies to %select{pointer|integer}1 arguments">;
+def err_ownership_returns_index_mismatch : Error<
+ "'ownership_returns' attribute index does not match; here it is %0">;
+def note_ownership_returns_index_mismatch : Note<
+ "declared with index %0 here">;
def err_format_strftime_third_parameter : Error<
"strftime format attribute requires 3rd parameter to be 0">;
def err_format_attribute_requires_variadic : Error<
@@ -2056,14 +2108,22 @@ def err_no_accessor_for_property : Error<
def error_cannot_find_suitable_accessor : Error<
"cannot find suitable %select{getter|setter}0 for property %1">;
-def err_attribute_aligned_not_power_of_two : Error<
+def err_alignment_not_power_of_two : Error<
"requested alignment is not a power of 2">;
+
def err_attribute_aligned_too_great : Error<
"requested alignment must be %0 bytes or smaller">;
def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
- "%q0 redeclared without %1 attribute: previous %1 ignored">;
+ "%q0 redeclared without %1 attribute: previous %1 ignored">,
+ InGroup<DiagGroup<"inconsistent-dllimport">>;
+def warn_dllimport_dropped_from_inline_function : Warning<
+ "%q0 redeclared inline; %1 attribute ignored">,
+ InGroup<IgnoredAttributes>;
def warn_attribute_ignored : Warning<"%0 attribute ignored">,
InGroup<IgnoredAttributes>;
+def warn_attribute_ignored_on_inline :
+ Warning<"%0 attribute ignored on inline function">,
+ InGroup<IgnoredAttributes>;
def warn_attribute_after_definition_ignored : Warning<
"attribute %0 after definition is ignored">,
InGroup<IgnoredAttributes>;
@@ -2112,11 +2172,16 @@ def err_declspec_thread_on_thread_variable : Error<
"thread-local storage specifier">;
def err_attribute_dll_not_extern : Error<
"%q0 must have external linkage when declared %q1">;
+def err_attribute_dll_thread_local : Error<
+ "%q0 cannot be thread local when declared %q1">;
def warn_attribute_invalid_on_definition : Warning<
"'%0' attribute cannot be specified on a definition">,
InGroup<IgnoredAttributes>;
def err_attribute_dll_redeclaration : Error<
"redeclaration of %q0 cannot add %q1 attribute">;
+def warn_attribute_dll_redeclaration : Warning<
+ "redeclaration of %q0 should not add %q1 attribute">,
+ InGroup<DiagGroup<"dll-attribute-on-redeclaration">>;
def err_attribute_dllimport_function_definition : Error<
"dllimport cannot be applied to non-inline function definition">;
def err_attribute_dll_deleted : Error<
@@ -2137,8 +2202,8 @@ def err_attribute_dll_member_of_dll_class : Error<
def warn_attribute_dll_instantiated_base_class : Warning<
"propagating dll attribute to %select{already instantiated|explicitly specialized}0 "
"base class template "
- "%select{without dll attribute|with different dll attribute}1 is unsupported">,
- InGroup<DiagGroup<"unsupported-dll-base-class-template">>;
+ "%select{without dll attribute|with different dll attribute}1 is not supported">,
+ InGroup<DiagGroup<"unsupported-dll-base-class-template">>, DefaultIgnore;
def err_attribute_weakref_not_static : Error<
"weakref declaration must have internal linkage">;
def err_attribute_weakref_not_global_context : Error<
@@ -2165,19 +2230,23 @@ def warn_attribute_wrong_decl_type : Warning<
"functions, methods and blocks|functions, methods, and classes|"
"functions, methods, and parameters|classes|variables|methods|"
"variables, functions and labels|fields and global variables|structs|"
- "variables, functions and tag types|thread-local variables|"
+ "variables and typedefs|thread-local variables|"
"variables and fields|variables, data members and tag types|"
"types and namespaces|Objective-C interfaces|methods and properties|"
"struct or union|struct, union or class|types|"
"Objective-C instance methods|init methods of interface or class extension declarations|"
"variables, functions and classes|Objective-C protocols|"
- "functions and global variables|structs or typedefs}1">,
+ "functions and global variables|structs or typedefs|"
+ "interface or protocol declarations}1">,
InGroup<IgnoredAttributes>;
def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
def warn_type_attribute_wrong_type : Warning<
"'%0' only applies to %select{function|pointer|"
"Objective-C object or block pointer}1 types; type here is %2">,
InGroup<IgnoredAttributes>;
+def warn_incomplete_encoded_type : Warning<
+ "encoding of %0 type is incomplete because %1 component has unknown encoding">,
+ InGroup<DiagGroup<"encode-type">>;
def warn_attribute_requires_functions_or_static_globals : Warning<
"%0 only applies to variables with static storage duration and functions">,
InGroup<IgnoredAttributes>;
@@ -2195,7 +2264,10 @@ def err_cconv_change : Error<
def warn_cconv_ignored : Warning<
"calling convention %0 ignored for this target">, InGroup<IgnoredAttributes>;
def err_cconv_knr : Error<
- "function with no prototype cannot use %0 calling convention">;
+ "function with no prototype cannot use the %0 calling convention">;
+def warn_cconv_knr : Warning<
+ err_cconv_knr.Text>,
+ InGroup<DiagGroup<"missing-prototype-for-cc">>;
def err_cconv_varargs : Error<
"variadic function cannot use %0 calling convention">;
def warn_cconv_varargs : Warning<
@@ -2305,6 +2377,21 @@ def warn_cannot_resolve_lock : Warning<
"cannot resolve lock expression">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
+// Thread safety warnings negative capabilities
+def warn_acquire_requires_negative_cap : Warning<
+ "acquiring %0 '%1' requires negative capability '%2'">,
+ InGroup<ThreadSafetyNegative>, DefaultIgnore;
+
+// Thread safety warnings on pass by reference
+def warn_guarded_pass_by_reference : Warning<
+ "passing variable '%1' by reference requires holding %0 "
+ "%select{'%2'|'%2' exclusively}3">,
+ InGroup<ThreadSafetyReference>, DefaultIgnore;
+def warn_pt_guarded_pass_by_reference : Warning<
+ "passing the value that '%1' points to by reference requires holding %0 "
+ "%select{'%2'|'%2' exclusively}3">,
+ InGroup<ThreadSafetyReference>, DefaultIgnore;
+
// Imprecise thread safety warnings
def warn_variable_requires_lock : Warning<
"%select{reading|writing}3 variable '%1' requires holding %0 "
@@ -2330,9 +2417,15 @@ def warn_fun_requires_lock_precise :
InGroup<ThreadSafetyPrecise>, DefaultIgnore;
def note_found_mutex_near_match : Note<"found near match '%0'">;
+// Verbose thread safety warnings
+def warn_thread_safety_verbose : Warning<"Thread safety verbose warning.">,
+ InGroup<ThreadSafetyVerbose>, DefaultIgnore;
+def note_thread_warning_in_fun : Note<"Thread warning in function '%0'">;
+def note_guarded_by_declared_here : Note<"Guarded_by declared here.">;
+
// Dummy warning that will trigger "beta" warnings from the analysis if enabled.
-def warn_thread_safety_beta : Warning<
- "Thread safety beta warning.">, InGroup<ThreadSafetyBeta>, DefaultIgnore;
+def warn_thread_safety_beta : Warning<"Thread safety beta warning.">,
+ InGroup<ThreadSafetyBeta>, DefaultIgnore;
// Consumed warnings
def warn_use_in_invalid_state : Warning<
@@ -2406,7 +2499,7 @@ def warn_non_literal_null_pointer : Warning<
"expression which evaluates to zero treated as a null pointer constant of "
"type %0">, InGroup<NonLiteralNullConversion>;
def warn_impcast_null_pointer_to_integer : Warning<
- "implicit conversion of NULL constant to %0">,
+ "implicit conversion of %select{NULL|nullptr}0 constant to %1">,
InGroup<NullConversion>;
def warn_impcast_floating_point_to_bool : Warning<
"implicit conversion turns floating-point number into bool: %0 to %1">,
@@ -2416,6 +2509,10 @@ def warn_impcast_pointer_to_bool : Warning<
"address of%select{| function| array}0 '%1' will always evaluate to "
"'true'">,
InGroup<PointerBoolConversion>;
+def warn_cast_nonnull_to_bool : Warning<
+ "nonnull parameter '%0' will evaluate to "
+ "'true' on first encounter">,
+ InGroup<PointerBoolConversion>;
def warn_this_bool_conversion : Warning<
"'this' pointer cannot be null in well-defined C++ code; pointer may be "
"assumed to always convert to true">, InGroup<UndefinedBoolConversion>;
@@ -2428,6 +2525,10 @@ def warn_null_pointer_compare : Warning<
"comparison of %select{address of|function|array}0 '%1' %select{not |}2"
"equal to a null pointer is always %select{true|false}2">,
InGroup<TautologicalPointerCompare>;
+def warn_nonnull_parameter_compare : Warning<
+ "comparison of nonnull parameter '%0' %select{not |}1"
+ "equal to a null pointer is %select{true|false}1 on first encounter">,
+ InGroup<TautologicalPointerCompare>;
def warn_this_null_compare : Warning<
"'this' pointer cannot be null in well-defined C++ code; comparison may be "
"assumed to always evaluate to %select{true|false}0">,
@@ -2649,8 +2750,8 @@ def err_param_default_argument : Error<
"C does not support default arguments">;
def err_param_default_argument_redefinition : Error<
"redefinition of default argument">;
-def warn_param_default_argument_redefinition : ExtWarn<
- "redefinition of default argument">;
+def ext_param_default_argument_redefinition : ExtWarn<
+ "redefinition of default argument">, InGroup<Microsoft>;
def err_param_default_argument_missing : Error<
"missing default argument on parameter">;
def err_param_default_argument_missing_name : Error<
@@ -2754,7 +2855,7 @@ def note_ovl_candidate_instantiation_depth : Note<
"candidate template ignored: substitution exceeded maximum template "
"instantiation depth">;
def note_ovl_candidate_underqualified : Note<
- "candidate template ignored: can't deduce a type for %0 which would "
+ "candidate template ignored: can't deduce a type for %0 that would "
"make %2 equal %1">;
def note_ovl_candidate_substitution_failure : Note<
"candidate template ignored: substitution failure%0%1">;
@@ -2960,8 +3061,18 @@ def note_ovl_candidate_bad_target : Note<
"function (the implicit copy assignment operator)|"
"function (the implicit move assignment operator)|"
"constructor (inherited)}0 not viable: call to "
- "%select{__device__|__global__|__host__|__host__ __device__}1 function from"
- " %select{__device__|__global__|__host__|__host__ __device__}2 function">;
+ "%select{__device__|__global__|__host__|__host__ __device__|invalid}1 function from"
+ " %select{__device__|__global__|__host__|__host__ __device__|invalid}2 function">;
+def note_implicit_member_target_infer_collision : Note<
+ "implicit %select{"
+ "default constructor|"
+ "copy constructor|"
+ "move constructor|"
+ "copy assignment operator|"
+ "move assignment operator|"
+ "destructor}0 inferred target collision: call to both "
+ "%select{__device__|__global__|__host__|__host__ __device__}1 and "
+ "%select{__device__|__global__|__host__|__host__ __device__}2 members">;
def note_ambiguous_type_conversion: Note<
"because of ambiguity in conversion %diff{of $ to $|between types}0,1">;
@@ -3101,11 +3212,11 @@ def err_template_parameter_default_friend_template : Error<
def err_template_template_parm_no_parms : Error<
"template template parameter must have its own template parameters">;
-def ext_variable_template : ExtWarn<"variable templates are a C++1y extension">,
- InGroup<CXX1y>;
+def ext_variable_template : ExtWarn<"variable templates are a C++14 extension">,
+ InGroup<CXX14>;
def warn_cxx11_compat_variable_template : Warning<
- "variable templates are incompatible with C++ standards before C++1y">,
- InGroup<CXXPre1yCompat>, DefaultIgnore;
+ "variable templates are incompatible with C++ standards before C++14">,
+ InGroup<CXXPre14Compat>, DefaultIgnore;
def err_template_variable_noparams : Error<
"extraneous 'template<>' in declaration of variable %0">;
def err_template_member : Error<"member %0 declared as a template">;
@@ -3433,6 +3544,8 @@ def note_template_variable_def_here : Note<
"in instantiation of variable template specialization %q0 requested here">;
def note_template_enum_def_here : Note<
"in instantiation of enumeration %q0 requested here">;
+def note_template_nsdmi_here : Note<
+ "in instantiation of default member initializer %q0 requested here">;
def note_template_type_alias_instantiation_here : Note<
"in instantiation of template type alias %0 requested here">;
def note_template_exception_spec_instantiation_here : Note<
@@ -3471,7 +3584,7 @@ def err_nested_name_spec_non_tag : Error<
// C++ Explicit Instantiation
def err_explicit_instantiation_duplicate : Error<
"duplicate explicit instantiation of %0">;
-def warn_explicit_instantiation_duplicate : ExtWarn<
+def ext_explicit_instantiation_duplicate : ExtWarn<
"duplicate explicit instantiation of %0 ignored as a Microsoft extension">,
InGroup<Microsoft>;
def note_previous_explicit_instantiation : Note<
@@ -3557,6 +3670,11 @@ def err_invalid_var_template_spec_type : Error<"type %2 "
"of %select{explicit instantiation|explicit specialization|"
"partial specialization|redeclaration}0 of %1 does not match"
" expected type %3">;
+def err_mismatched_exception_spec_explicit_instantiation : Error<
+ "exception specification in explicit instantiation does not match instantiated one">;
+def ext_mismatched_exception_spec_explicit_instantiation : ExtWarn<
+ "exception specification in explicit instantiation does not match instantiated one">,
+ InGroup<Microsoft>;
// C++ typename-specifiers
def err_typename_nested_not_found : Error<"no type named %0 in %1">;
@@ -3678,6 +3796,14 @@ def err_ellipsis_in_declarator_not_parameter : Error<
def err_sizeof_pack_no_pack_name : Error<
"%0 does not refer to the name of a parameter pack">;
+def err_fold_expression_packs_both_sides : Error<
+ "binary fold expression has unexpanded parameter packs in both operands">;
+def err_fold_expression_empty : Error<
+ "unary fold expression has empty expansion for operator '%0' "
+ "with no fallback value">;
+def err_fold_expression_bad_operand : Error<
+ "expression not permitted as operand of fold expression">;
+
def err_unexpected_typedef : Error<
"unexpected type name %0: expected expression">;
def err_unexpected_namespace : Error<
@@ -3704,6 +3830,9 @@ def warn_property_method_deprecated :
InGroup<DeprecatedDeclarations>;
def warn_deprecated_message : Warning<"%0 is deprecated: %1">,
InGroup<DeprecatedDeclarations>;
+def warn_deprecated_anonymous_namespace : Warning<
+ "'deprecated' attribute on anonymous namespace ignored">,
+ InGroup<IgnoredAttributes>;
def warn_deprecated_fwdclass_message : Warning<
"%0 may be deprecated because the receiver type is unknown">,
InGroup<DeprecatedDeclarations>;
@@ -3797,10 +3926,10 @@ def warn_undefined_inline : Warning<"inline function %q0 is not defined">,
InGroup<DiagGroup<"undefined-inline">>;
def note_used_here : Note<"used here">;
-def warn_internal_in_extern_inline : ExtWarn<
+def ext_internal_in_extern_inline : ExtWarn<
"static %select{function|variable}0 %1 is used in an inline function with "
"external linkage">, InGroup<StaticInInline>;
-def ext_internal_in_extern_inline : Extension<
+def ext_internal_in_extern_inline_quiet : Extension<
"static %select{function|variable}0 %1 is used in an inline function with "
"external linkage">, InGroup<StaticInInline>;
def warn_static_local_in_extern_inline : Warning<
@@ -3809,7 +3938,7 @@ def warn_static_local_in_extern_inline : Warning<
def note_convert_inline_to_static : Note<
"use 'static' to give inline function %0 internal linkage">;
-def warn_redefinition_of_typedef : ExtWarn<
+def ext_redefinition_of_typedef : ExtWarn<
"redefinition of typedef %0 is a C11 feature">,
InGroup<DiagGroup<"typedef-redefinition"> >;
def err_redefinition_variably_modified_typedef : Error<
@@ -3852,6 +3981,10 @@ def err_redefinition_different_type : Error<
"redefinition of %0 with a different type%diff{: $ vs $|}1,2">;
def err_redefinition_different_kind : Error<
"redefinition of %0 as different kind of symbol">;
+def err_redefinition_different_namespace_alias : Error<
+ "redefinition of %0 as an alias for a different namespace">;
+def note_previous_namespace_alias : Note<
+ "previously defined as an alias for %0">;
def warn_forward_class_redefinition : Warning<
"redefinition of forward class %0 of a typedef name of an object type is ignored">,
InGroup<DiagGroup<"objc-forward-class-redefinition">>;
@@ -3977,15 +4110,15 @@ def err_variable_object_no_init : Error<
"variable-sized object may not be initialized">;
def err_excess_initializers : Error<
"excess elements in %select{array|vector|scalar|union|struct}0 initializer">;
-def warn_excess_initializers : ExtWarn<
+def ext_excess_initializers : ExtWarn<
"excess elements in %select{array|vector|scalar|union|struct}0 initializer">;
def err_excess_initializers_in_char_array_initializer : Error<
"excess elements in char array initializer">;
-def warn_excess_initializers_in_char_array_initializer : ExtWarn<
+def ext_excess_initializers_in_char_array_initializer : ExtWarn<
"excess elements in char array initializer">;
def err_initializer_string_for_char_array_too_long : Error<
"initializer-string for char array is too long">;
-def warn_initializer_string_for_char_array_too_long : ExtWarn<
+def ext_initializer_string_for_char_array_too_long : ExtWarn<
"initializer-string for char array is too long">;
def warn_missing_field_initializers : Warning<
"missing field %0 initializer">,
@@ -4065,28 +4198,35 @@ def warn_missing_braces : Warning<
def err_redefinition_of_label : Error<"redefinition of label %0">;
def err_undeclared_label_use : Error<"use of undeclared label %0">;
+def err_goto_ms_asm_label : Error<
+ "cannot jump from this goto statement to label %0 inside an inline assembly block">;
+def note_goto_ms_asm_label : Note<
+ "inline assembly label %0 declared here">;
def warn_unused_label : Warning<"unused label %0">,
InGroup<UnusedLabel>, DefaultIgnore;
-def err_goto_into_protected_scope : Error<"goto into protected scope">;
-def warn_goto_into_protected_scope : ExtWarn<"goto into protected scope">,
+def err_goto_into_protected_scope : Error<
+ "cannot jump from this goto statement to its label">;
+def ext_goto_into_protected_scope : ExtWarn<
+ "jump from this goto statement to its label is a Microsoft extension">,
InGroup<Microsoft>;
def warn_cxx98_compat_goto_into_protected_scope : Warning<
- "goto would jump into protected scope in C++98">,
+ "jump from this goto statement to its label is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_switch_into_protected_scope : Error<
- "switch case is in protected scope">;
+ "cannot jump from switch statement to this case label">;
def warn_cxx98_compat_switch_into_protected_scope : Warning<
- "switch case would be in a protected scope in C++98">,
+ "jump from switch statement to this case label is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_indirect_goto_without_addrlabel : Error<
"indirect goto in function with no address-of-label expressions">;
def err_indirect_goto_in_protected_scope : Error<
- "indirect goto might cross protected scopes">;
+ "cannot jump from this indirect goto statement to one of its possible targets">;
def warn_cxx98_compat_indirect_goto_in_protected_scope : Warning<
- "indirect goto might cross protected scopes in C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def note_indirect_goto_target : Note<"possible target of indirect goto">;
+ "jump from this indirect goto statement to one of its possible targets "
+ "is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
+def note_indirect_goto_target : Note<
+ "possible target of indirect goto statement">;
def note_protected_by_variable_init : Note<
"jump bypasses variable initialization">;
def note_protected_by_variable_nontriv_destructor : Note<
@@ -4466,9 +4606,9 @@ def err_offsetof_array_type : Error<"offsetof requires array type, %0 invalid">;
def ext_offsetof_extended_field_designator : Extension<
"using extended field designator is an extension">,
InGroup<DiagGroup<"extended-offsetof">>;
-def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
+def ext_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
InGroup<InvalidOffsetof>;
-def warn_offsetof_non_standardlayout_type : ExtWarn<
+def ext_offsetof_non_standardlayout_type : ExtWarn<
"offset of on non-standard-layout type %0">, InGroup<InvalidOffsetof>;
def err_offsetof_bitfield : Error<"cannot compute offset of bit-field %0">;
def err_offsetof_field_of_virtual_base : Error<
@@ -4526,7 +4666,7 @@ def warn_logical_and_in_logical_or : Warning<
"'&&' within '||'">, InGroup<LogicalOpParentheses>;
def warn_overloaded_shift_in_comparison :Warning<
- "overloaded operator %select{>>|<<}0 has lower precedence than "
+ "overloaded operator %select{>>|<<}0 has higher precedence than "
"comparison operator">,
InGroup<OverloadedShiftOpParentheses>;
def note_evaluate_comparison_first :Note<
@@ -5204,15 +5344,18 @@ def err_address_space_qualified_delete : Error<
def err_default_init_const : Error<
"default initialization of an object of const type %0"
- "%select{| requires a user-provided default constructor}1">;
+ "%select{| without a user-provided default constructor}1">;
+def note_add_initializer : Note<
+ "add an explicit initializer to initialize %0">;
def err_delete_operand : Error<"cannot delete expression of type %0">;
def ext_delete_void_ptr_operand : ExtWarn<
- "cannot delete expression with pointer-to-'void' type %0">;
+ "cannot delete expression with pointer-to-'void' type %0">,
+ InGroup<DeleteIncomplete>;
def err_ambiguous_delete_operand : Error<
"ambiguous conversion of delete expression of type %0 to a pointer">;
def warn_delete_incomplete : Warning<
"deleting pointer to incomplete type %0 may cause undefined behavior">,
- InGroup<DiagGroup<"delete-incomplete">>;
+ InGroup<DeleteIncomplete>;
def err_delete_incomplete_class_type : Error<
"deleting incomplete class type %0; no conversions to pointer type">;
def err_delete_explicit_conversion : Error<
@@ -5321,9 +5464,6 @@ let CategoryName = "Lambda Issue" in {
"'this' cannot be %select{implicitly |}0captured in this context">;
def err_lambda_capture_anonymous_var : Error<
"unnamed variable cannot be implicitly captured in a lambda expression">;
- def err_lambda_capture_vm_type : Error<
- "variable %0 with variably modified type cannot be captured in "
- "a lambda expression">;
def err_lambda_capture_flexarray_type : Error<
"variable %0 with flexible array member cannot be captured in "
"a lambda expression">;
@@ -5359,12 +5499,12 @@ let CategoryName = "Lambda Issue" in {
"implicit capture of lambda object due to conversion to block pointer "
"here">;
- // C++1y lambda init-captures.
+ // C++14 lambda init-captures.
def warn_cxx11_compat_init_capture : Warning<
"initialized lambda captures are incompatible with C++ standards "
- "before C++1y">, InGroup<CXXPre1yCompat>, DefaultIgnore;
+ "before C++14">, InGroup<CXXPre14Compat>, DefaultIgnore;
def ext_init_capture : ExtWarn<
- "initialized lambda captures are a C++1y extension">, InGroup<CXX1y>;
+ "initialized lambda captures are a C++14 extension">, InGroup<CXX14>;
def err_init_capture_no_expression : Error<
"initializer missing for lambda capture %0">;
def err_init_capture_multiple_expressions : Error<
@@ -5918,10 +6058,10 @@ def ext_typecheck_cond_incompatible_operands_nonstandard : ExtWarn<
"pointer type %2">;
def err_cast_selector_expr : Error<
"cannot type cast @selector expression">;
-def warn_typecheck_cond_incompatible_pointers : ExtWarn<
+def ext_typecheck_cond_incompatible_pointers : ExtWarn<
"pointer type mismatch%diff{ ($ and $)|}0,1">,
InGroup<DiagGroup<"pointer-type-mismatch">>;
-def warn_typecheck_cond_pointer_integer_mismatch : ExtWarn<
+def ext_typecheck_cond_pointer_integer_mismatch : ExtWarn<
"pointer/integer type mismatch in conditional expression"
"%diff{ ($ and $)|}0,1">,
InGroup<DiagGroup<"conditional-type-mismatch">>;
@@ -5994,6 +6134,8 @@ let CategoryName = "Inline Assembly Issue" in {
def err_asm_bad_register_type : Error<"bad type for named register variable">;
def err_asm_invalid_input_size : Error<
"invalid input size for constraint '%0'">;
+ def err_asm_invalid_output_size : Error<
+ "invalid output size for constraint '%0'">;
def err_invalid_asm_cast_lvalue : Error<
"invalid use of a cast in a inline asm context requiring an l-value: "
"remove the cast or build with -fheinous-gnu-extensions">;
@@ -6008,6 +6150,9 @@ let CategoryName = "Inline Assembly Issue" in {
"value size does not match register size specified by the constraint "
"and modifier">,
InGroup<ASMOperandWidths>;
+
+ def note_asm_missing_constraint_modifier : Note<
+ "use constraint modifier \"%0\"">;
}
let CategoryName = "Semantic Issue" in {
@@ -6078,9 +6223,12 @@ def err_in_class_initializer_literal_type : Error<
"'constexpr' specifier">;
def err_in_class_initializer_non_constant : Error<
"in-class initializer for static data member is not a constant expression">;
-def err_in_class_initializer_references_def_ctor : Error<
- "defaulted default constructor of %0 cannot be used by non-static data "
- "member initializer which appears before end of class definition">;
+def err_in_class_initializer_not_yet_parsed
+ : Error<"cannot use defaulted default constructor of %0 within the class "
+ "outside of member functions because %1 has an initializer">;
+def err_in_class_initializer_not_yet_parsed_outer_class
+ : Error<"cannot use defaulted default constructor of %0 within "
+ "%1 outside of member functions because %2 has an initializer">;
def ext_in_class_initializer_non_constant : Extension<
"in-class initializer for static data member is not a constant expression; "
@@ -6128,8 +6276,9 @@ def err_anonymous_record_bad_member : Error<
def err_anonymous_record_nonpublic_member : Error<
"anonymous %select{struct|union}0 cannot contain a "
"%select{private|protected}1 data member">;
-def ext_ms_anonymous_struct : ExtWarn<
- "anonymous structs are a Microsoft extension">, InGroup<Microsoft>;
+def ext_ms_anonymous_record : ExtWarn<
+ "anonymous %select{structs|unions}0 are a Microsoft extension">,
+ InGroup<Microsoft>;
// C++ local classes
def err_reference_to_local_var_in_enclosing_function : Error<
@@ -6414,12 +6563,12 @@ def warn_printf_nonsensical_flag: Warning<
def warn_format_nonsensical_length: Warning<
"length modifier '%0' results in undefined behavior or no effect with '%1' conversion specifier">,
InGroup<Format>;
-def warn_format_non_standard_positional_arg: ExtWarn<
+def warn_format_non_standard_positional_arg: Warning<
"positional arguments are not supported by ISO C">, InGroup<FormatNonStandard>, DefaultIgnore;
-def warn_format_non_standard: ExtWarn<
+def warn_format_non_standard: Warning<
"'%0' %select{length modifier|conversion specifier}1 is not supported by ISO C">,
InGroup<FormatNonStandard>, DefaultIgnore;
-def warn_format_non_standard_conversion_spec: ExtWarn<
+def warn_format_non_standard_conversion_spec: Warning<
"using length modifier '%0' with conversion specifier '%1' is not supported by ISO C">,
InGroup<FormatNonStandard>, DefaultIgnore;
def warn_printf_ignored_flag: Warning<
@@ -6433,7 +6582,7 @@ def note_format_fix_specifier : Note<"did you mean to use '%0'?">;
def note_printf_c_str: Note<"did you mean to call the %0 method?">;
def warn_null_arg : Warning<
- "null passed to a callee which requires a non-null argument">,
+ "null passed to a callee that requires a non-null argument">,
InGroup<NonNull>;
def warn_null_ret : Warning<
"null returned from %select{function|method}0 that requires a non-null return value">,
@@ -6799,6 +6948,11 @@ def warn_duplicate_attribute : Warning<
"attribute %0 is already applied with different parameters">,
InGroup<IgnoredAttributes>;
+def warn_sync_fetch_and_nand_semantics_change : Warning<
+ "the semantics of this intrinsic changed with GCC "
+ "version 4.4 - the newer semantics are provided here">,
+ InGroup<DiagGroup<"sync-fetch-and-nand-semantics-changed">>;
+
// Type
def ext_invalid_sign_spec : Extension<"'%0' cannot be signed or unsigned">;
def warn_receiver_forward_class : Warning<
@@ -6840,6 +6994,13 @@ def err_invalid_protocol_qualifiers : Error<
def warn_ivar_use_hidden : Warning<
"local declaration of %0 hides instance variable">,
InGroup<DiagGroup<"shadow-ivar">>;
+def warn_direct_initialize_call : Warning<
+ "explicit call to +initialize results in duplicate call to +initialize">,
+ InGroup<ExplicitInitializeCall>;
+def warn_direct_super_initialize_call : Warning<
+ "explicit call to [super initialize] should only be in implementation "
+ "of +initialize">,
+ InGroup<ExplicitInitializeCall>;
def error_ivar_use_in_class_method : Error<
"instance variable %0 accessed in class method">;
def error_implicit_ivar_access : Error<
@@ -6889,6 +7050,9 @@ def err_property_not_found_suggest : Error<
"property %0 not found on object of type %1; did you mean %2?">;
def err_ivar_access_using_property_syntax_suggest : Error<
"property %0 not found on object of type %1; did you mean to access instance variable %2?">;
+def warn_property_access_suggest : Warning<
+"property %0 not found on object of type %1; did you mean to access property %2?">,
+InGroup<PropertyAccessDotSyntax>;
def err_property_found_suggest : Error<
"property %0 found on object of type %1; did you mean to access "
"it with the \".\" operator?">;
@@ -6920,7 +7084,7 @@ def err_uncasted_send_to_unknown_any_method : Error<
"no known method %select{%objcinstance1|%objcclass1}0; cast the "
"message send to the method's return type">;
def err_unsupported_unknown_any_decl : Error<
- "%0 has unknown type, which is unsupported for this kind of declaration">;
+ "%0 has unknown type, which is not supported for this kind of declaration">;
def err_unsupported_unknown_any_expr : Error<
"unsupported expression with unknown type">;
def err_unsupported_unknown_any_call : Error<
@@ -6936,6 +7100,11 @@ def err_unknown_any_function : Error<
def err_filter_expression_integral : Error<
"filter expression type should be an integral value not %0">;
+def err_non_asm_stmt_in_naked_function : Error<
+ "non-ASM statement in naked function is not supported">;
+def err_asm_naked_parm_ref : Error<
+ "parameter references not allowed in naked functions">;
+
// OpenCL warnings and errors.
def err_invalid_astype_of_different_size : Error<
"invalid reinterpretation: sizes of %0 and %1 must match">;
@@ -7013,8 +7182,12 @@ def err_omp_expected_var_name : Error<
"expected variable name">;
def err_omp_required_method : Error<
"%0 variable must have an accessible, unambiguous %select{default constructor|copy constructor|copy assignment operator|'%2'|destructor}1">;
+def note_omp_task_predetermined_firstprivate_here : Note<
+ "predetermined as a firstprivate in a task construct here">;
def err_omp_clause_ref_type_arg : Error<
"arguments of OpenMP clause '%0' cannot be of reference type %1">;
+def err_omp_task_predetermined_firstprivate_ref_type_arg : Error<
+ "predetermined as a firstprivate in a task construct variable cannot be of reference type %0">;
def err_omp_threadprivate_incomplete_type : Error<
"threadprivate variable with incomplete type %0">;
def err_omp_no_dsa_for_variable : Error<
@@ -7031,12 +7204,15 @@ def note_omp_predetermined_dsa : Note<
"loop iteration variable is predetermined as lastprivate|"
"constant variable is predetermined as shared|"
"global variable is predetermined as shared|"
+ "non-shared variable in a task construct is predetermined as firstprivate|"
"variable with automatic storage duration is predetermined as private}0"
"%select{|; perhaps you forget to enclose 'omp %2' directive into a parallel or another task region?}1">;
def note_omp_implicit_dsa : Note<
"implicitly determined as %0">;
def err_omp_loop_var_dsa : Error<
"loop iteration variable in the associated loop of 'omp %1' directive may not be %0, predetermined as %2">;
+def err_omp_global_loop_var_dsa : Error<
+ "loop iteration variable in the associated loop of 'omp %1' directive may not be a variable with global storage without being explicitly marked as %0">;
def err_omp_not_for : Error<
"%select{statement after '#pragma omp %1' must be a for loop|"
"expected %2 for loops after '#pragma omp %1'%select{|, but found only %4}3}0">;
@@ -7068,6 +7244,9 @@ def err_omp_linear_expected_int_or_ptr : Error<
def warn_omp_linear_step_zero : Warning<
"zero linear step (%0 %select{|and other variables in clause }1should probably be const)">,
InGroup<OpenMPClauses>;
+def warn_omp_alignment_not_power_of_two : Warning<
+ "aligned clause will be ignored because the requested alignment is not a power of 2">,
+ InGroup<OpenMPClauses>;
def err_omp_aligned_expected_array_or_ptr : Error<
"argument of aligned clause should be array"
"%select{ or pointer|, pointer, reference to array or reference to pointer}1"
@@ -7095,10 +7274,16 @@ def err_omp_loop_incr_not_compatible : Error<
"on each iteration of OpenMP for loop">;
def note_omp_loop_cond_requres_compatible_incr : Note<
"loop step is expected to be %select{negative|positive}0 due to this condition">;
+def err_omp_loop_diff_cxx : Error<
+ "could not calculate number of iterations calling 'operator-' with "
+ "upper and lower loop bounds">;
def err_omp_loop_cannot_use_stmt : Error<
"'%0' statement cannot be used in OpenMP for loop">;
def err_omp_simd_region_cannot_use_stmt : Error<
"'%0' statement cannot be used in OpenMP simd region">;
+def warn_omp_loop_64_bit_var : Warning<
+ "OpenMP loop iteration variable cannot have more than 64 bits size and will be narrowed">,
+ InGroup<OpenMPLoopForm>;
def err_omp_unknown_reduction_identifier : Error<
"incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'">;
def err_omp_reduction_type_array : Error<
@@ -7119,9 +7304,17 @@ def err_omp_reduction_id_not_compatible : Error<
"variable of type %0 is not valid for specified reduction operation">;
def err_omp_prohibited_region : Error<
"region cannot be%select{| closely}0 nested inside '%1' region"
- "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?}2">;
+ "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?|"
+ "; perhaps you forget to enclose 'omp %3' directive into a for or a parallel for region with 'ordered' clause?|"
+ "; perhaps you forget to enclose 'omp %3' directive into a target region?}2">;
def err_omp_prohibited_region_simd : Error<
"OpenMP constructs may not be nested inside a simd region">;
+def err_omp_prohibited_region_atomic : Error<
+ "OpenMP constructs may not be nested inside an atomic region">;
+def err_omp_prohibited_region_critical_same_name : Error<
+ "cannot nest 'critical' regions having the same name %0">;
+def note_omp_previous_critical_region : Note<
+ "previous 'critical' region starts here">;
def err_omp_sections_not_compound_stmt : Error<
"the statement for '#pragma omp sections' must be a compound statement">;
def err_omp_parallel_sections_not_compound_stmt : Error<
@@ -7133,6 +7326,37 @@ def err_omp_sections_substmt_not_section : Error<
"statement in 'omp sections' directive must be enclosed into a section region">;
def err_omp_parallel_sections_substmt_not_section : Error<
"statement in 'omp parallel sections' directive must be enclosed into a section region">;
+def err_omp_parallel_reduction_in_task_firstprivate : Error<
+ "argument of a reduction clause of a %0 construct must not appear in a firstprivate clause on a task construct">;
+def err_omp_atomic_read_not_expression_statement : Error<
+ "the statement for 'atomic read' must be an expression statement of form 'v = x;',"
+ " where v and x are both lvalue expressions with scalar type">;
+def note_omp_atomic_read: Note<
+ "%select{expected an expression statement|expected built-in assignment operator|expected expression of scalar type|expected lvalue expression}0">;
+def err_omp_atomic_write_not_expression_statement : Error<
+ "the statement for 'atomic write' must be an expression statement of form 'x = expr;',"
+ " where x is an l-value expression with scalar type">;
+def err_omp_atomic_update_not_expression_statement : Error<
+ "the statement for 'atomic%select{| update}0' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x',"
+ " where x is an l-value expression with scalar type">;
+def err_omp_atomic_capture_not_expression_statement : Error<
+ "the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x',"
+ " where x and v are both l-value expressions with scalar type">;
+def err_omp_atomic_capture_not_compound_statement : Error<
+ "the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}',"
+ " '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}',"
+ " '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}'"
+ " where x is an l-value expression with scalar type">;
+def err_omp_atomic_several_clauses : Error<
+ "directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause">;
+def note_omp_atomic_previous_clause : Note<
+ "'%0' clause used here">;
+def err_omp_target_contains_not_only_teams : Error<
+ "target construct with nested teams region contains statements outside of the teams construct">;
+def note_omp_nested_teams_construct_here : Note<
+ "nested teams construct here">;
+def note_omp_nested_statement_here : Note<
+ "%select{statement|directive}0 outside teams construct here">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
@@ -7184,6 +7408,8 @@ def err_module_import_not_at_top_level : Error<
def note_module_import_not_at_top_level : Note<"%0 begins here">;
def err_module_self_import : Error<
"import of module '%0' appears within same top-level module '%1'">;
+def err_module_import_in_implementation : Error<
+ "@import of module '%0' in implementation of '%1'; use #import">;
}
let CategoryName = "Documentation Issue" in {
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index be9d2bdbd2..5de2c6acba 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -52,10 +52,15 @@ def err_pch_with_compiler_errors : Error<
"PCH file contains compiler errors">;
def err_imported_module_not_found : Error<
- "module '%0' imported by AST file '%1' not found">, DefaultFatal;
+ "module '%0' in AST file '%1' (imported by AST file '%2') "
+ "is not defined in any loaded module map file; "
+ "maybe you need to load '%3'?">, DefaultFatal;
def err_imported_module_modmap_changed : Error<
"module '%0' imported by AST file '%1' found in a different module map file"
" (%2) than when the importing AST file was built (%3)">, DefaultFatal;
+def err_module_different_modmap : Error<
+ "module '%0' %select{uses|does not use}1 additional module map '%2'"
+ "%select{| not}1 used when the module was built">;
def warn_module_conflict : Warning<
"module '%0' conflicts with already-imported module '%1': %2">,
InGroup<ModuleConflict>;
diff --git a/include/clang/Basic/ExceptionSpecificationType.h b/include/clang/Basic/ExceptionSpecificationType.h
index edd89ec709..132b5ba1e5 100644
--- a/include/clang/Basic/ExceptionSpecificationType.h
+++ b/include/clang/Basic/ExceptionSpecificationType.h
@@ -26,7 +26,8 @@ enum ExceptionSpecificationType {
EST_BasicNoexcept, ///< noexcept
EST_ComputedNoexcept, ///< noexcept(expression)
EST_Unevaluated, ///< not evaluated yet, for special member function
- EST_Uninstantiated ///< not instantiated yet
+ EST_Uninstantiated, ///< not instantiated yet
+ EST_Unparsed ///< not parsed yet
};
inline bool isDynamicExceptionSpec(ExceptionSpecificationType ESpecType) {
diff --git a/include/clang/Basic/ExpressionTraits.h b/include/clang/Basic/ExpressionTraits.h
index e877715721..0363a1d2c7 100644
--- a/include/clang/Basic/ExpressionTraits.h
+++ b/include/clang/Basic/ExpressionTraits.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_EXPRESSIONTRAITS_H
-#define LLVM_CLANG_EXPRESSIONTRAITS_H
+#ifndef LLVM_CLANG_BASIC_EXPRESSIONTRAITS_H
+#define LLVM_CLANG_BASIC_EXPRESSIONTRAITS_H
namespace clang {
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index dd1ad0da1d..132bf37019 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FILEMANAGER_H
-#define LLVM_CLANG_FILEMANAGER_H
+#ifndef LLVM_CLANG_BASIC_FILEMANAGER_H
+#define LLVM_CLANG_BASIC_FILEMANAGER_H
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/LLVM.h"
@@ -59,7 +59,7 @@ public:
/// If the 'File' member is valid, then this FileEntry has an open file
/// descriptor for the file.
class FileEntry {
- std::string Name; // Name of the file.
+ const char *Name; // Name of the file.
off_t Size; // File size in bytes.
time_t ModTime; // Modification time of file.
const DirectoryEntry *Dir; // Directory file lives in.
@@ -74,7 +74,7 @@ class FileEntry {
friend class FileManager;
void closeFile() const {
- File.reset(nullptr); // rely on destructor to close File
+ File.reset(); // rely on destructor to close File
}
void operator=(const FileEntry &) LLVM_DELETED_FUNCTION;
@@ -93,7 +93,7 @@ public:
assert(!isValid() && "Cannot copy an initialized FileEntry");
}
- const char *getName() const { return Name.c_str(); }
+ const char *getName() const { return Name; }
bool isValid() const { return IsValid; }
off_t getSize() const { return Size; }
unsigned getUID() const { return UID; }
@@ -194,7 +194,8 @@ public:
/// \param AtBeginning whether this new stat cache must be installed at the
/// beginning of the chain of stat caches. Otherwise, it will be added to
/// the end of the chain.
- void addStatCache(FileSystemStatCache *statCache, bool AtBeginning = false);
+ void addStatCache(std::unique_ptr<FileSystemStatCache> statCache,
+ bool AtBeginning = false);
/// \brief Removes the specified FileSystemStatCache object from the manager.
void removeStatCache(FileSystemStatCache *statCache);
@@ -240,12 +241,11 @@ public:
/// \brief Open the specified file as a MemoryBuffer, returning a new
/// MemoryBuffer if successful, otherwise returning null.
- llvm::MemoryBuffer *getBufferForFile(const FileEntry *Entry,
- std::string *ErrorStr = nullptr,
- bool isVolatile = false,
- bool ShouldCloseOpenFile = true);
- llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
- std::string *ErrorStr = nullptr);
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+ getBufferForFile(const FileEntry *Entry, bool isVolatile = false,
+ bool ShouldCloseOpenFile = true);
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+ getBufferForFile(StringRef Filename);
/// \brief Get the 'stat' information for the given \p Path.
///
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
index 9be8b1074b..cad9189348 100644
--- a/include/clang/Basic/FileSystemStatCache.h
+++ b/include/clang/Basic/FileSystemStatCache.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FILESYSTEMSTATCACHE_H
-#define LLVM_CLANG_FILESYSTEMSTATCACHE_H
+#ifndef LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H
+#define LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringMap.h"
@@ -74,8 +74,8 @@ public:
/// \brief Sets the next stat call cache in the chain of stat caches.
/// Takes ownership of the given stat cache.
- void setNextStatCache(FileSystemStatCache *Cache) {
- NextStatCache.reset(Cache);
+ void setNextStatCache(std::unique_ptr<FileSystemStatCache> Cache) {
+ NextStatCache = std::move(Cache);
}
/// \brief Retrieve the next stat call cache in the chain.
@@ -84,7 +84,9 @@ public:
/// \brief Retrieve the next stat call cache in the chain, transferring
/// ownership of this cache (and, transitively, all of the remaining caches)
/// to the caller.
- FileSystemStatCache *takeNextStatCache() { return NextStatCache.release(); }
+ std::unique_ptr<FileSystemStatCache> takeNextStatCache() {
+ return std::move(NextStatCache);
+ }
protected:
// FIXME: The pointer here is a non-owning/optional reference to the
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 0c278a17a3..ed923393c8 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -444,26 +444,21 @@ public:
/// \brief Return the identifier token info for the specified named
/// identifier.
IdentifierInfo &get(StringRef Name) {
- llvm::StringMapEntry<IdentifierInfo*> &Entry =
- HashTable.GetOrCreateValue(Name);
+ auto &Entry = *HashTable.insert(std::make_pair(Name, nullptr)).first;
- IdentifierInfo *II = Entry.getValue();
+ IdentifierInfo *&II = Entry.second;
if (II) return *II;
// No entry; if we have an external lookup, look there first.
if (ExternalLookup) {
II = ExternalLookup->get(Name);
- if (II) {
- // Cache in the StringMap for subsequent lookups.
- Entry.setValue(II);
+ if (II)
return *II;
- }
}
// Lookups failed, make a new IdentifierInfo.
void *Mem = getAllocator().Allocate<IdentifierInfo>();
II = new (Mem) IdentifierInfo();
- Entry.setValue(II);
// Make sure getName() knows how to find the IdentifierInfo
// contents.
@@ -486,25 +481,23 @@ public:
/// introduce or modify an identifier. If they called get(), they would
/// likely end up in a recursion.
IdentifierInfo &getOwn(StringRef Name) {
- llvm::StringMapEntry<IdentifierInfo*> &Entry =
- HashTable.GetOrCreateValue(Name);
-
- IdentifierInfo *II = Entry.getValue();
- if (!II) {
-
- // Lookups failed, make a new IdentifierInfo.
- void *Mem = getAllocator().Allocate<IdentifierInfo>();
- II = new (Mem) IdentifierInfo();
- Entry.setValue(II);
-
- // Make sure getName() knows how to find the IdentifierInfo
- // contents.
- II->Entry = &Entry;
-
- // If this is the 'import' contextual keyword, mark it as such.
- if (Name.equals("import"))
- II->setModulesImport(true);
- }
+ auto &Entry = *HashTable.insert(std::make_pair(Name, nullptr)).first;
+
+ IdentifierInfo *&II = Entry.second;
+ if (II)
+ return *II;
+
+ // Lookups failed, make a new IdentifierInfo.
+ void *Mem = getAllocator().Allocate<IdentifierInfo>();
+ II = new (Mem) IdentifierInfo();
+
+ // Make sure getName() knows how to find the IdentifierInfo
+ // contents.
+ II->Entry = &Entry;
+
+ // If this is the 'import' contextual keyword, mark it as such.
+ if (Name.equals("import"))
+ II->setModulesImport(true);
return *II;
}
@@ -563,6 +556,7 @@ enum ObjCMethodFamily {
OMF_retain,
OMF_retainCount,
OMF_self,
+ OMF_initialize,
// performSelector families
OMF_performSelector
@@ -588,6 +582,12 @@ enum ObjCInstanceTypeFamily {
OIT_ReturnsSelf
};
+enum ObjCStringFormatFamily {
+ SFF_None,
+ SFF_NSString,
+ SFF_CFString
+};
+
/// \brief Smart pointer class that efficiently represents Objective-C method
/// names.
///
@@ -633,6 +633,8 @@ class Selector {
}
static ObjCMethodFamily getMethodFamilyImpl(Selector sel);
+
+ static ObjCStringFormatFamily getStringFormatFamilyImpl(Selector sel);
public:
friend class SelectorTable; // only the SelectorTable can create these
@@ -703,7 +705,11 @@ public:
ObjCMethodFamily getMethodFamily() const {
return getMethodFamilyImpl(*this);
}
-
+
+ ObjCStringFormatFamily getStringFormatFamily() const {
+ return getStringFormatFamilyImpl(*this);
+ }
+
static Selector getEmptyMarker() {
return Selector(uintptr_t(-1));
}
diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h
index 5a71fa85b3..3e01d25add 100644
--- a/include/clang/Basic/LLVM.h
+++ b/include/clang/Basic/LLVM.h
@@ -13,8 +13,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef CLANG_BASIC_LLVM_H
-#define CLANG_BASIC_LLVM_H
+#ifndef LLVM_CLANG_BASIC_LLVM_H
+#define LLVM_CLANG_BASIC_LLVM_H
// Do not proliferate #includes here, require clients to #include their
// dependencies.
diff --git a/include/clang/Basic/Lambda.h b/include/clang/Basic/Lambda.h
index 280ae94fed..e676e726dd 100644
--- a/include/clang/Basic/Lambda.h
+++ b/include/clang/Basic/Lambda.h
@@ -34,7 +34,8 @@ enum LambdaCaptureDefault {
enum LambdaCaptureKind {
LCK_This, ///< Capturing the \c this pointer
LCK_ByCopy, ///< Capturing by copy (a.k.a., by value)
- LCK_ByRef ///< Capturing by reference
+ LCK_ByRef, ///< Capturing by reference
+ LCK_VLAType ///< Capturing variable-length array type
};
} // end namespace clang
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index 0ac35a205e..82dba18acc 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -9,26 +9,40 @@
//
// This file defines the language options. Users of this file must
// define the LANGOPT macro to make use of this information.
-// Optionally, the user may also define BENIGN_LANGOPT
-// (for options that don't affect the construction of the AST in an
-// incompatible way), ENUM_LANGOPT (for options that have enumeration,
-// rather than unsigned, type), BENIGN_ENUM_LANGOPT (for benign
-// options that have enumeration type), and VALUE_LANGOPT is a language option
-// that describes a value rather than a flag.
//
+// Optionally, the user may also define:
+//
+// BENIGN_LANGOPT: for options that don't affect the construction of the AST in
+// any way (that is, the value can be different between an implicit module
+// and the user of that module).
+//
+// COMPATIBLE_LANGOPT: for options that affect the construction of the AST in
+// a way that doesn't prevent interoperability (that is, the value can be
+// different between an explicit module and the user of that module).
+//
+// ENUM_LANGOPT: for options that have enumeration, rather than unsigned, type.
+//
+// VALUE_LANGOPT: for options that describe a value rather than a flag.
+//
+// BENIGN_ENUM_LANGOPT, COMPATIBLE_ENUM_LANGOPT: combinations of the above.
+//
+// FIXME: Clients should be able to more easily select whether they want
+// different levels of compatibility versus how to handle different kinds
+// of option.
//===----------------------------------------------------------------------===//
+
#ifndef LANGOPT
# error Define the LANGOPT macro to handle language options
#endif
-#ifndef VALUE_LANGOPT
-# define VALUE_LANGOPT(Name, Bits, Default, Description) \
+#ifndef COMPATIBLE_LANGOPT
+# define COMPATIBLE_LANGOPT(Name, Bits, Default, Description) \
LANGOPT(Name, Bits, Default, Description)
#endif
#ifndef BENIGN_LANGOPT
# define BENIGN_LANGOPT(Name, Bits, Default, Description) \
- LANGOPT(Name, Bits, Default, Description)
+ COMPATIBLE_LANGOPT(Name, Bits, Default, Description)
#endif
#ifndef ENUM_LANGOPT
@@ -36,11 +50,22 @@
LANGOPT(Name, Bits, Default, Description)
#endif
+#ifndef COMPATIBLE_ENUM_LANGOPT
+# define COMPATIBLE_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+ ENUM_LANGOPT(Name, Type, Bits, Default, Description)
+#endif
+
#ifndef BENIGN_ENUM_LANGOPT
# define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
- ENUM_LANGOPT(Name, Type, Bits, Default, Description)
+ COMPATIBLE_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
#endif
+#ifndef VALUE_LANGOPT
+# define VALUE_LANGOPT(Name, Bits, Default, Description) \
+ LANGOPT(Name, Bits, Default, Description)
+#endif
+
+// FIXME: A lot of the BENIGN_ options should be COMPATIBLE_ instead.
LANGOPT(C99 , 1, 0, "C99")
LANGOPT(C11 , 1, 0, "C11")
LANGOPT(MSVCCompat , 1, 0, "Microsoft Visual C++ full compatibility mode")
@@ -49,7 +74,7 @@ LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks")
LANGOPT(Borland , 1, 0, "Borland extensions")
LANGOPT(CPlusPlus , 1, 0, "C++")
LANGOPT(CPlusPlus11 , 1, 0, "C++11")
-LANGOPT(CPlusPlus1y , 1, 0, "C++1y")
+LANGOPT(CPlusPlus14 , 1, 0, "C++14")
LANGOPT(CPlusPlus1z , 1, 0, "C++1z")
LANGOPT(ObjC1 , 1, 0, "Objective-C 1")
LANGOPT(ObjC2 , 1, 0, "Objective-C 2")
@@ -101,16 +126,18 @@ LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses")
LANGOPT(ModulesSearchAll , 1, 1, "search even non-imported modules to find unresolved references")
LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module uses and all headers to be in modules")
LANGOPT(ModulesErrorRecovery, 1, 1, "automatically import modules as needed when performing error recovery")
-LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro")
-LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
+COMPATIBLE_LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro")
+COMPATIBLE_LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)")
VALUE_LANGOPT(PackStruct , 32, 0,
"default struct packing maximum alignment")
+VALUE_LANGOPT(MaxTypeAlign , 32, 0,
+ "default maximum alignment for types")
VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level")
VALUE_LANGOPT(PIELevel , 2, 0, "__PIE__ level")
LANGOPT(GNUInline , 1, 0, "GNU inline semantics")
-LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro")
-LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro")
+COMPATIBLE_LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro")
+COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro")
LANGOPT(FastMath , 1, 0, "__FAST_MATH__ predefined macro")
LANGOPT(FiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro")
@@ -126,6 +153,7 @@ LANGOPT(ShortEnums , 1, 0, "short enum types")
LANGOPT(OpenCL , 1, 0, "OpenCL")
LANGOPT(OpenCLVersion , 32, 0, "OpenCL version")
LANGOPT(NativeHalfType , 1, 0, "Native half type support")
+LANGOPT(HalfArgsAndReturns, 1, 0, "half args and returns")
LANGOPT(CUDA , 1, 0, "CUDA")
LANGOPT(OpenMP , 1, 0, "OpenMP support")
LANGOPT(Renderscript , 1, 0, "RenderScript")
@@ -181,17 +209,22 @@ BENIGN_LANGOPT(BracketDepth, 32, 256,
"maximum bracket nesting depth")
BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0,
"if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.")
-VALUE_LANGOPT(MSCVersion, 32, 0,
- "version of Microsoft Visual C/C++")
+VALUE_LANGOPT(MSCompatibilityVersion, 32, 0, "Microsoft Visual C/C++ Version")
VALUE_LANGOPT(VtorDispMode, 2, 1, "How many vtordisps to insert")
LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")
LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
+LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
+ "field padding (0: none, 1:least "
+ "aggressive, 2: more aggressive)")
+
#undef LANGOPT
-#undef VALUE_LANGOPT
+#undef COMPATIBLE_LANGOPT
#undef BENIGN_LANGOPT
#undef ENUM_LANGOPT
+#undef COMPATIBLE_ENUM_LANGOPT
#undef BENIGN_ENUM_LANGOPT
+#undef VALUE_LANGOPT
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 9bffc7cb18..5ac96c5198 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -12,25 +12,18 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LANGOPTIONS_H
-#define LLVM_CLANG_LANGOPTIONS_H
+#ifndef LLVM_CLANG_BASIC_LANGOPTIONS_H
+#define LLVM_CLANG_BASIC_LANGOPTIONS_H
#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/Visibility.h"
#include <string>
namespace clang {
-struct SanitizerOptions {
-#define SANITIZER(NAME, ID) unsigned ID : 1;
-#include "clang/Basic/Sanitizers.def"
-
- /// \brief Cached set of sanitizer options with all sanitizers disabled.
- static const SanitizerOptions Disabled;
-};
-
/// Bitfields of LangOptions, split out from LangOptions in order to ensure that
/// this large collection of bitfields is a trivial class type.
class LangOptionsBase {
@@ -40,7 +33,6 @@ public:
#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
#include "clang/Basic/LangOptions.def"
- SanitizerOptions Sanitize;
protected:
// Define language options of enumeration type. These are private, and will
// have accessors (below).
@@ -75,6 +67,13 @@ public:
enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
public:
+ /// \brief Set of enabled sanitizers.
+ SanitizerSet Sanitize;
+
+ /// \brief Path to blacklist file specifying which objects
+ /// (files, functions, variables) should not be instrumented.
+ std::string SanitizerBlacklistFile;
+
clang::ObjCRuntime ObjCRuntime;
std::string ObjCConstantStringClass;
@@ -88,6 +87,11 @@ public:
/// \brief The name of the current module.
std::string CurrentModule;
+ /// \brief The name of the module that the translation unit is an
+ /// implementation of. Prevents semantic imports, but does not otherwise
+ /// treat this as the CurrentModule.
+ std::string ImplementationOfModule;
+
/// \brief Options for parsing comments.
CommentOptions CommentOpts;
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 9b66840ba4..e46be9edca 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -55,17 +55,6 @@ public:
/// \brief The parent of this module. This will be NULL for the top-level
/// module.
Module *Parent;
-
- /// \brief The module map file that (along with the module name) uniquely
- /// identifies this module.
- ///
- /// The particular module that \c Name refers to may depend on how the module
- /// was found in header search. However, the combination of \c Name and
- /// \c ModuleMap will be globally unique for top-level modules. In the case of
- /// inferred modules, \c ModuleMap will contain the module map that allowed
- /// the inference (e.g. contained 'Module *') rather than the virtual
- /// inferred module map file.
- const FileEntry *ModuleMap;
/// \brief The umbrella header or directory.
llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
@@ -95,12 +84,20 @@ public:
/// \brief The headers that are part of this module.
SmallVector<const FileEntry *, 2> NormalHeaders;
- /// \brief The headers that are explicitly excluded from this module.
- SmallVector<const FileEntry *, 2> ExcludedHeaders;
+ /// \brief The headers that are logically part of this module but
+ /// must be textually included.
+ SmallVector<const FileEntry *, 2> TextualHeaders;
/// \brief The headers that are private to this module.
SmallVector<const FileEntry *, 2> PrivateHeaders;
+ /// \brief The headers that are private to this module and are to be
+ /// included textually.
+ SmallVector<const FileEntry *, 2> PrivateTextualHeaders;
+
+ /// \brief The headers that are explicitly excluded from this module.
+ SmallVector<const FileEntry *, 2> ExcludedHeaders;
+
/// \brief Information about a header directive as found in the module map
/// file.
struct HeaderDirective {
@@ -283,10 +280,8 @@ public:
std::vector<Conflict> Conflicts;
/// \brief Construct a new module or submodule.
- ///
- /// For an explanation of \p ModuleMap, see Module::ModuleMap.
Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
- const FileEntry *ModuleMap, bool IsFramework, bool IsExplicit);
+ bool IsFramework, bool IsExplicit);
~Module();
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index fa375f4e18..e33587d8f3 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_OBJCRUNTIME_H
-#define LLVM_CLANG_OBJCRUNTIME_H
+#ifndef LLVM_CLANG_BASIC_OBJCRUNTIME_H
+#define LLVM_CLANG_BASIC_OBJCRUNTIME_H
#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/Triple.h"
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index 691d13a312..0145db0593 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -30,6 +30,9 @@
#ifndef OPENMP_FOR_CLAUSE
# define OPENMP_FOR_CLAUSE(Name)
#endif
+#ifndef OPENMP_FOR_SIMD_CLAUSE
+# define OPENMP_FOR_SIMD_CLAUSE(Name)
+#endif
#ifndef OPENMP_SECTIONS_CLAUSE
# define OPENMP_SECTIONS_CLAUSE(Name)
#endif
@@ -39,9 +42,24 @@
#ifndef OPENMP_PARALLEL_FOR_CLAUSE
# define OPENMP_PARALLEL_FOR_CLAUSE(Name)
#endif
+#ifndef OPENMP_PARALLEL_FOR_SIMD_CLAUSE
+# define OPENMP_PARALLEL_FOR_SIMD_CLAUSE(Name)
+#endif
#ifndef OPENMP_PARALLEL_SECTIONS_CLAUSE
# define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name)
#endif
+#ifndef OPENMP_TASK_CLAUSE
+# define OPENMP_TASK_CLAUSE(Name)
+#endif
+#ifndef OPENMP_ATOMIC_CLAUSE
+# define OPENMP_ATOMIC_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TARGET_CLAUSE
+# define OPENMP_TARGET_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TEAMS_CLAUSE
+# define OPENMP_TEAMS_CLAUSE(Name)
+#endif
#ifndef OPENMP_DEFAULT_KIND
# define OPENMP_DEFAULT_KIND(Name)
#endif
@@ -61,11 +79,24 @@ OPENMP_DIRECTIVE(for)
OPENMP_DIRECTIVE(sections)
OPENMP_DIRECTIVE(section)
OPENMP_DIRECTIVE(single)
+OPENMP_DIRECTIVE(master)
+OPENMP_DIRECTIVE(critical)
+OPENMP_DIRECTIVE(taskyield)
+OPENMP_DIRECTIVE(barrier)
+OPENMP_DIRECTIVE(taskwait)
+OPENMP_DIRECTIVE(flush)
+OPENMP_DIRECTIVE(ordered)
+OPENMP_DIRECTIVE(atomic)
+OPENMP_DIRECTIVE(target)
+OPENMP_DIRECTIVE(teams)
OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
+OPENMP_DIRECTIVE_EXT(parallel_for_simd, "parallel for simd")
OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
+OPENMP_DIRECTIVE_EXT(for_simd, "for simd")
// OpenMP clauses.
OPENMP_CLAUSE(if, OMPIfClause)
+OPENMP_CLAUSE(final, OMPFinalClause)
OPENMP_CLAUSE(num_threads, OMPNumThreadsClause)
OPENMP_CLAUSE(safelen, OMPSafelenClause)
OPENMP_CLAUSE(collapse, OMPCollapseClause)
@@ -83,6 +114,14 @@ OPENMP_CLAUSE(proc_bind, OMPProcBindClause)
OPENMP_CLAUSE(schedule, OMPScheduleClause)
OPENMP_CLAUSE(ordered, OMPOrderedClause)
OPENMP_CLAUSE(nowait, OMPNowaitClause)
+OPENMP_CLAUSE(untied, OMPUntiedClause)
+OPENMP_CLAUSE(mergeable, OMPMergeableClause)
+OPENMP_CLAUSE(flush, OMPFlushClause)
+OPENMP_CLAUSE(read, OMPReadClause)
+OPENMP_CLAUSE(write, OMPWriteClause)
+OPENMP_CLAUSE(update, OMPUpdateClause)
+OPENMP_CLAUSE(capture, OMPCaptureClause)
+OPENMP_CLAUSE(seq_cst, OMPSeqCstClause)
// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
@@ -104,7 +143,7 @@ OPENMP_SIMD_CLAUSE(safelen)
OPENMP_SIMD_CLAUSE(collapse)
OPENMP_SIMD_CLAUSE(reduction)
-// TODO more clauses allowed for directive 'omp for'.
+// Clauses allowed for directive 'omp for'.
OPENMP_FOR_CLAUSE(private)
OPENMP_FOR_CLAUSE(lastprivate)
OPENMP_FOR_CLAUSE(firstprivate)
@@ -114,6 +153,18 @@ OPENMP_FOR_CLAUSE(schedule)
OPENMP_FOR_CLAUSE(ordered)
OPENMP_FOR_CLAUSE(nowait)
+// Clauses allowed for directive 'omp for simd'.
+OPENMP_FOR_SIMD_CLAUSE(private)
+OPENMP_FOR_SIMD_CLAUSE(firstprivate)
+OPENMP_FOR_SIMD_CLAUSE(lastprivate)
+OPENMP_FOR_SIMD_CLAUSE(reduction)
+OPENMP_FOR_SIMD_CLAUSE(schedule)
+OPENMP_FOR_SIMD_CLAUSE(collapse)
+OPENMP_FOR_SIMD_CLAUSE(nowait)
+OPENMP_FOR_SIMD_CLAUSE(safelen)
+OPENMP_FOR_SIMD_CLAUSE(linear)
+OPENMP_FOR_SIMD_CLAUSE(aligned)
+
// Clauses allowed for OpenMP directive 'omp sections'.
OPENMP_SECTIONS_CLAUSE(private)
OPENMP_SECTIONS_CLAUSE(lastprivate)
@@ -121,7 +172,7 @@ OPENMP_SECTIONS_CLAUSE(firstprivate)
OPENMP_SECTIONS_CLAUSE(reduction)
OPENMP_SECTIONS_CLAUSE(nowait)
-// TODO more clauses allowed for directive 'omp single'.
+// Clauses allowed for directive 'omp single'.
OPENMP_SINGLE_CLAUSE(private)
OPENMP_SINGLE_CLAUSE(firstprivate)
OPENMP_SINGLE_CLAUSE(copyprivate)
@@ -158,6 +209,23 @@ OPENMP_PARALLEL_FOR_CLAUSE(collapse)
OPENMP_PARALLEL_FOR_CLAUSE(schedule)
OPENMP_PARALLEL_FOR_CLAUSE(ordered)
+// Clauses allowed for OpenMP directive 'parallel for simd'.
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(if)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(num_threads)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(default)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(proc_bind)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(private)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(firstprivate)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(shared)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(reduction)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(copyin)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(lastprivate)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(collapse)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(schedule)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(safelen)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(linear)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(aligned)
+
// Clauses allowed for OpenMP directive 'parallel sections'.
OPENMP_PARALLEL_SECTIONS_CLAUSE(if)
OPENMP_PARALLEL_SECTIONS_CLAUSE(num_threads)
@@ -170,6 +238,35 @@ OPENMP_PARALLEL_SECTIONS_CLAUSE(reduction)
OPENMP_PARALLEL_SECTIONS_CLAUSE(copyin)
OPENMP_PARALLEL_SECTIONS_CLAUSE(lastprivate)
+// Clauses allowed for OpenMP directive 'task'.
+OPENMP_TASK_CLAUSE(if)
+OPENMP_TASK_CLAUSE(final)
+OPENMP_TASK_CLAUSE(default)
+OPENMP_TASK_CLAUSE(private)
+OPENMP_TASK_CLAUSE(firstprivate)
+OPENMP_TASK_CLAUSE(shared)
+OPENMP_TASK_CLAUSE(untied)
+OPENMP_TASK_CLAUSE(mergeable)
+
+// Clauses allowed for OpenMP directive 'atomic'.
+OPENMP_ATOMIC_CLAUSE(read)
+OPENMP_ATOMIC_CLAUSE(write)
+OPENMP_ATOMIC_CLAUSE(update)
+OPENMP_ATOMIC_CLAUSE(capture)
+OPENMP_ATOMIC_CLAUSE(seq_cst)
+
+// Clauses allowed for OpenMP directive 'target'.
+// TODO More clauses for 'target' directive.
+OPENMP_TARGET_CLAUSE(if)
+
+// Clauses allowed for OpenMP directive 'teams'.
+// TODO More clauses for 'teams' directive.
+OPENMP_TEAMS_CLAUSE(default)
+OPENMP_TEAMS_CLAUSE(private)
+OPENMP_TEAMS_CLAUSE(firstprivate)
+OPENMP_TEAMS_CLAUSE(shared)
+OPENMP_TEAMS_CLAUSE(reduction)
+
#undef OPENMP_SCHEDULE_KIND
#undef OPENMP_PROC_BIND_KIND
#undef OPENMP_DEFAULT_KIND
@@ -180,7 +277,13 @@ OPENMP_PARALLEL_SECTIONS_CLAUSE(lastprivate)
#undef OPENMP_SECTIONS_CLAUSE
#undef OPENMP_PARALLEL_CLAUSE
#undef OPENMP_PARALLEL_FOR_CLAUSE
+#undef OPENMP_PARALLEL_FOR_SIMD_CLAUSE
#undef OPENMP_PARALLEL_SECTIONS_CLAUSE
+#undef OPENMP_TASK_CLAUSE
+#undef OPENMP_ATOMIC_CLAUSE
+#undef OPENMP_TARGET_CLAUSE
+#undef OPENMP_TEAMS_CLAUSE
#undef OPENMP_SIMD_CLAUSE
#undef OPENMP_FOR_CLAUSE
+#undef OPENMP_FOR_SIMD_CLAUSE
diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h
index 526cbb26cf..e2f115113e 100644
--- a/include/clang/Basic/OpenMPKinds.h
+++ b/include/clang/Basic/OpenMPKinds.h
@@ -93,6 +93,12 @@ bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind);
/// parallel', otherwise - false.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
+/// \brief Checks if the specified directive is a teams-kind directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a teams-like directive like 'omp teams',
+/// otherwise - false.
+bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind);
+
/// \brief Checks if the specified directive is a simd directive.
/// \param DKind Specified directive.
/// \return true - the directive is a simd directive like 'omp simd',
diff --git a/include/clang/Basic/OperatorKinds.h b/include/clang/Basic/OperatorKinds.h
index d3b70c2f4d..7120baeef6 100644
--- a/include/clang/Basic/OperatorKinds.h
+++ b/include/clang/Basic/OperatorKinds.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_BASIC_OPERATOR_KINDS_H
-#define LLVM_CLANG_BASIC_OPERATOR_KINDS_H
+#ifndef LLVM_CLANG_BASIC_OPERATORKINDS_H
+#define LLVM_CLANG_BASIC_OPERATORKINDS_H
namespace clang {
diff --git a/include/clang/Basic/OperatorPrecedence.h b/include/clang/Basic/OperatorPrecedence.h
index b68d577c80..640749fdd1 100644
--- a/include/clang/Basic/OperatorPrecedence.h
+++ b/include/clang/Basic/OperatorPrecedence.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_OPERATOR_PRECEDENCE_H
-#define LLVM_CLANG_OPERATOR_PRECEDENCE_H
+#ifndef LLVM_CLANG_BASIC_OPERATORPRECEDENCE_H
+#define LLVM_CLANG_BASIC_OPERATORPRECEDENCE_H
#include "clang/Basic/TokenKinds.h"
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index 8ae3b22b0c..84c8dd1596 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -13,8 +13,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_PARTIALDIAGNOSTIC_H
-#define LLVM_CLANG_PARTIALDIAGNOSTIC_H
+#ifndef LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H
+#define LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h
index b7a938209a..081f22d48d 100644
--- a/include/clang/Basic/PlistSupport.h
+++ b/include/clang/Basic/PlistSupport.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_PLISTSUPPORT_H
-#define LLVM_CLANG_PLISTSUPPORT_H
+#ifndef LLVM_CLANG_BASIC_PLISTSUPPORT_H
+#define LLVM_CLANG_BASIC_PLISTSUPPORT_H
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
diff --git a/include/clang/Basic/PrettyStackTrace.h b/include/clang/Basic/PrettyStackTrace.h
index 0e49295540..6badae5c03 100644
--- a/include/clang/Basic/PrettyStackTrace.h
+++ b/include/clang/Basic/PrettyStackTrace.h
@@ -14,8 +14,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef CLANG_BASIC_PRETTYSTACKTRACE_H
-#define CLANG_BASIC_PRETTYSTACKTRACE_H
+#ifndef LLVM_CLANG_BASIC_PRETTYSTACKTRACE_H
+#define LLVM_CLANG_BASIC_PRETTYSTACKTRACE_H
#include "clang/Basic/SourceLocation.h"
#include "llvm/Support/PrettyStackTrace.h"
diff --git a/include/clang/Basic/SanitizerBlacklist.h b/include/clang/Basic/SanitizerBlacklist.h
new file mode 100644
index 0000000000..2ce268aa0a
--- /dev/null
+++ b/include/clang/Basic/SanitizerBlacklist.h
@@ -0,0 +1,45 @@
+//===--- SanitizerBlacklist.h - Blacklist for sanitizers --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// User-provided blacklist used to disable/alter instrumentation done in
+// sanitizers.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_SANITIZERBLACKLIST_H
+#define LLVM_CLANG_BASIC_SANITIZERBLACKLIST_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SpecialCaseList.h"
+#include <memory>
+
+namespace clang {
+
+class SanitizerBlacklist {
+ std::unique_ptr<llvm::SpecialCaseList> SCL;
+ SourceManager &SM;
+
+public:
+ SanitizerBlacklist(StringRef BlacklistPath, SourceManager &SM);
+ bool isBlacklistedGlobal(StringRef GlobalName,
+ StringRef Category = StringRef()) const;
+ bool isBlacklistedType(StringRef MangledTypeName,
+ StringRef Category = StringRef()) const;
+ bool isBlacklistedFunction(StringRef FunctionName) const;
+ bool isBlacklistedFile(StringRef FileName,
+ StringRef Category = StringRef()) const;
+ bool isBlacklistedLocation(SourceLocation Loc,
+ StringRef Category = StringRef()) const;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
index 0ef39bc710..adb9b04072 100644
--- a/include/clang/Basic/Sanitizers.def
+++ b/include/clang/Basic/Sanitizers.def
@@ -59,9 +59,11 @@ SANITIZER("float-cast-overflow", FloatCastOverflow)
SANITIZER("float-divide-by-zero", FloatDivideByZero)
SANITIZER("function", Function)
SANITIZER("integer-divide-by-zero", IntegerDivideByZero)
+SANITIZER("nonnull-attribute", NonnullAttribute)
SANITIZER("null", Null)
SANITIZER("object-size", ObjectSize)
SANITIZER("return", Return)
+SANITIZER("returns-nonnull-attribute", ReturnsNonnullAttribute)
SANITIZER("shift", Shift)
SANITIZER("signed-integer-overflow", SignedIntegerOverflow)
SANITIZER("unreachable", Unreachable)
@@ -78,9 +80,10 @@ SANITIZER("dataflow", DataFlow)
// ABI or address space layout implications, and only catch undefined behavior.
SANITIZER_GROUP("undefined", Undefined,
Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow |
- FloatDivideByZero | Function | IntegerDivideByZero | Null |
- ObjectSize | Return | Shift | SignedIntegerOverflow |
- Unreachable | VLABound | Vptr)
+ FloatDivideByZero | Function | IntegerDivideByZero |
+ NonnullAttribute | Null | ObjectSize | Return |
+ ReturnsNonnullAttribute | Shift | SignedIntegerOverflow |
+ Unreachable | VLABound | Vptr)
// -fsanitize=undefined-trap includes
// all sanitizers included by -fsanitize=undefined, except those that require
@@ -88,9 +91,9 @@ SANITIZER_GROUP("undefined", Undefined,
// -fsanitize-undefined-trap-on-error flag.
SANITIZER_GROUP("undefined-trap", UndefinedTrap,
Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow |
- FloatDivideByZero | IntegerDivideByZero | Null | ObjectSize |
- Return | Shift | SignedIntegerOverflow | Unreachable |
- VLABound)
+ FloatDivideByZero | IntegerDivideByZero | NonnullAttribute |
+ Null | ObjectSize | Return | ReturnsNonnullAttribute |
+ Shift | SignedIntegerOverflow | Unreachable | VLABound)
SANITIZER_GROUP("integer", Integer,
SignedIntegerOverflow | UnsignedIntegerOverflow | Shift |
diff --git a/include/clang/Basic/Sanitizers.h b/include/clang/Basic/Sanitizers.h
new file mode 100644
index 0000000000..868b331f2f
--- /dev/null
+++ b/include/clang/Basic/Sanitizers.h
@@ -0,0 +1,47 @@
+//===--- Sanitizers.h - C Language Family Language Options ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::SanitizerKind enum.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_SANITIZERS_H
+#define LLVM_CLANG_BASIC_SANITIZERS_H
+
+namespace clang {
+
+enum class SanitizerKind {
+#define SANITIZER(NAME, ID) ID,
+#include "clang/Basic/Sanitizers.def"
+ Unknown
+};
+
+class SanitizerSet {
+ /// \brief Bitmask of enabled sanitizers.
+ unsigned Kinds;
+public:
+ SanitizerSet();
+
+ /// \brief Check if a certain sanitizer is enabled.
+ bool has(SanitizerKind K) const;
+
+ /// \brief Enable or disable a certain sanitizer.
+ void set(SanitizerKind K, bool Value);
+
+ /// \brief Disable all sanitizers.
+ void clear();
+
+ /// \brief Returns true if at least one sanitizer is enabled.
+ bool empty() const;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 7b637d7e1f..7aaee1df22 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SOURCELOCATION_H
-#define LLVM_CLANG_SOURCELOCATION_H
+#ifndef LLVM_CLANG_BASIC_SOURCELOCATION_H
+#define LLVM_CLANG_BASIC_SOURCELOCATION_H
#include "clang/Basic/LLVM.h"
#include "llvm/Support/Compiler.h"
@@ -292,7 +292,6 @@ public:
const char *getCharacterData(bool *Invalid = nullptr) const;
- const llvm::MemoryBuffer* getBuffer(bool *Invalid = nullptr) const;
/// \brief Return a StringRef to the source buffer data for the
/// specified FileID.
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index bece66d427..717258ddcf 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -32,8 +32,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SOURCEMANAGER_H
-#define LLVM_CLANG_SOURCEMANAGER_H
+#ifndef LLVM_CLANG_BASIC_SOURCEMANAGER_H
+#define LLVM_CLANG_BASIC_SOURCEMANAGER_H
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h"
@@ -205,10 +205,10 @@ namespace SrcMgr {
/// this content cache. This is used for performance analysis.
llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const;
- void setBuffer(llvm::MemoryBuffer *B) {
+ void setBuffer(std::unique_ptr<llvm::MemoryBuffer> B) {
assert(!Buffer.getPointer() && "MemoryBuffer already set.");
- Buffer.setPointer(B);
- Buffer.setInt(false);
+ Buffer.setPointer(B.release());
+ Buffer.setInt(0);
}
/// \brief Get the underlying buffer, returning NULL if the buffer is not
@@ -566,7 +566,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// non-null, FileEntry pointers.
llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
- /// \brief True if the ContentCache for files that are overriden by other
+ /// \brief True if the ContentCache for files that are overridden by other
/// files, should report the original file name. Defaults to true.
bool OverridenFilesKeepOriginalName;
@@ -575,7 +575,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
bool UserFilesAreVolatile;
struct OverriddenFilesInfoTy {
- /// \brief Files that have been overriden with the contents from another
+ /// \brief Files that have been overridden with the contents from another
/// file.
llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
/// \brief Files that were overridden with a memory buffer.
@@ -685,9 +685,9 @@ class SourceManager : public RefCountedBase<SourceManager> {
InBeforeInTUCacheEntry &getInBeforeInTUCache(FileID LFID, FileID RFID) const;
// Cache for the "fake" buffer used for error-recovery purposes.
- mutable llvm::MemoryBuffer *FakeBufferForRecovery;
+ mutable std::unique_ptr<llvm::MemoryBuffer> FakeBufferForRecovery;
- mutable SrcMgr::ContentCache *FakeContentCacheForRecovery;
+ mutable std::unique_ptr<SrcMgr::ContentCache> FakeContentCacheForRecovery;
/// \brief Lazily computed map of macro argument chunks to their expanded
/// source location.
@@ -719,7 +719,8 @@ public:
FileManager &getFileManager() const { return FileMgr; }
/// \brief Set true if the SourceManager should report the original file name
- /// for contents of files that were overriden by other files.Defaults to true.
+ /// for contents of files that were overridden by other files. Defaults to
+ /// true.
void setOverridenFilesKeepOriginalName(bool value) {
OverridenFilesKeepOriginalName = value;
}
@@ -753,7 +754,6 @@ public:
/// \brief Set the file ID for the main source file.
void setMainFileID(FileID FID) {
- assert(MainFileID.isInvalid() && "MainFileID already set!");
MainFileID = FID;
}
@@ -788,12 +788,12 @@ public:
///
/// This does no caching of the buffer and takes ownership of the
/// MemoryBuffer, so only pass a MemoryBuffer to this once.
- FileID createFileID(llvm::MemoryBuffer *Buffer,
+ FileID createFileID(std::unique_ptr<llvm::MemoryBuffer> Buffer,
SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User,
int LoadedID = 0, unsigned LoadedOffset = 0,
SourceLocation IncludeLoc = SourceLocation()) {
- return createFileID(createMemBufferContentCache(Buffer), IncludeLoc,
- FileCharacter, LoadedID, LoadedOffset);
+ return createFileID(createMemBufferContentCache(std::move(Buffer)),
+ IncludeLoc, FileCharacter, LoadedID, LoadedOffset);
}
/// \brief Return a new SourceLocation that encodes the
@@ -824,7 +824,7 @@ public:
/// \brief Override the contents of the given source file by providing an
/// already-allocated buffer.
///
- /// \param SourceFile the source file whose contents will be overriden.
+ /// \param SourceFile the source file whose contents will be overridden.
///
/// \param Buffer the memory buffer whose contents will be used as the
/// data in the given source file.
@@ -832,11 +832,15 @@ public:
/// \param DoNotFree If true, then the buffer will not be freed when the
/// source manager is destroyed.
void overrideFileContents(const FileEntry *SourceFile,
- llvm::MemoryBuffer *Buffer, bool DoNotFree = false);
+ llvm::MemoryBuffer *Buffer, bool DoNotFree);
+ void overrideFileContents(const FileEntry *SourceFile,
+ std::unique_ptr<llvm::MemoryBuffer> Buffer) {
+ overrideFileContents(SourceFile, Buffer.release(), /*DoNotFree*/ false);
+ }
/// \brief Override the given source file with another one.
///
- /// \param SourceFile the source file which will be overriden.
+ /// \param SourceFile the source file which will be overridden.
///
/// \param NewFile the file whose contents will be used as the
/// data instead of the contents of the given source file.
@@ -1623,7 +1627,7 @@ private:
/// \brief Create a new ContentCache for the specified memory buffer.
const SrcMgr::ContentCache *
- createMemBufferContentCache(llvm::MemoryBuffer *Buf);
+ createMemBufferContentCache(std::unique_ptr<llvm::MemoryBuffer> Buf);
FileID getFileIDSlow(unsigned SLocOffset) const;
FileID getFileIDLocal(unsigned SLocOffset) const;
@@ -1673,7 +1677,7 @@ class BeforeThanCompare<SourceRange> {
public:
explicit BeforeThanCompare(SourceManager &SM) : SM(SM) { }
- bool operator()(SourceRange LHS, SourceRange RHS) {
+ bool operator()(SourceRange LHS, SourceRange RHS) const {
return SM.isBeforeInTranslationUnit(LHS.getBegin(), RHS.getBegin());
}
};
diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h
index af95b78883..f31d604244 100644
--- a/include/clang/Basic/SourceManagerInternals.h
+++ b/include/clang/Basic/SourceManagerInternals.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
-#define LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
+#ifndef LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
+#define LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index f89567356b..a968d00d20 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -203,6 +203,7 @@ namespace clang {
CC_X86StdCall, // __attribute__((stdcall))
CC_X86FastCall, // __attribute__((fastcall))
CC_X86ThisCall, // __attribute__((thiscall))
+ CC_X86VectorCall, // __attribute__((vectorcall))
CC_X86Pascal, // __attribute__((pascal))
CC_X86_64Win64, // __attribute__((ms_abi))
CC_X86_64SysV, // __attribute__((sysv_abi))
@@ -212,16 +213,18 @@ namespace clang {
CC_IntelOclBicc // __attribute__((intel_ocl_bicc))
};
- /// \brief Checks whether the given calling convention is callee-cleanup.
- inline bool isCalleeCleanup(CallingConv CC) {
+ /// \brief Checks whether the given calling convention supports variadic
+ /// calls. Unprototyped calls also use the variadic call rules.
+ inline bool supportsVariadicCall(CallingConv CC) {
switch (CC) {
case CC_X86StdCall:
case CC_X86FastCall:
case CC_X86ThisCall:
case CC_X86Pascal:
- return true;
- default:
+ case CC_X86VectorCall:
return false;
+ default:
+ return true;
}
}
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index 1b0ead9676..750108f39f 100644
--- a/include/clang/Basic/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -135,6 +135,7 @@ def SubstNonTypeTemplateParmPackExpr : DStmt<Expr>;
def FunctionParmPackExpr : DStmt<Expr>;
def MaterializeTemporaryExpr : DStmt<Expr>;
def LambdaExpr : DStmt<Expr>;
+def CXXFoldExpr : DStmt<Expr>;
// Obj-C Expressions.
def ObjCStringLiteral : DStmt<Expr>;
@@ -163,6 +164,7 @@ def ShuffleVectorExpr : DStmt<Expr>;
def ConvertVectorExpr : DStmt<Expr>;
def BlockExpr : DStmt<Expr>;
def OpaqueValueExpr : DStmt<Expr>;
+def TypoExpr : DStmt<Expr>;
// Microsoft Extensions.
def MSPropertyRefExpr : DStmt<Expr>;
@@ -178,11 +180,25 @@ def AsTypeExpr : DStmt<Expr>;
// OpenMP Directives.
def OMPExecutableDirective : Stmt<1>;
+def OMPLoopDirective : DStmt<OMPExecutableDirective, 1>;
def OMPParallelDirective : DStmt<OMPExecutableDirective>;
-def OMPSimdDirective : DStmt<OMPExecutableDirective>;
-def OMPForDirective : DStmt<OMPExecutableDirective>;
+def OMPSimdDirective : DStmt<OMPLoopDirective>;
+def OMPForDirective : DStmt<OMPLoopDirective>;
+def OMPForSimdDirective : DStmt<OMPLoopDirective>;
def OMPSectionsDirective : DStmt<OMPExecutableDirective>;
def OMPSectionDirective : DStmt<OMPExecutableDirective>;
def OMPSingleDirective : DStmt<OMPExecutableDirective>;
-def OMPParallelForDirective : DStmt<OMPExecutableDirective>;
+def OMPMasterDirective : DStmt<OMPExecutableDirective>;
+def OMPCriticalDirective : DStmt<OMPExecutableDirective>;
+def OMPParallelForDirective : DStmt<OMPLoopDirective>;
+def OMPParallelForSimdDirective : DStmt<OMPLoopDirective>;
def OMPParallelSectionsDirective : DStmt<OMPExecutableDirective>;
+def OMPTaskDirective : DStmt<OMPExecutableDirective>;
+def OMPTaskyieldDirective : DStmt<OMPExecutableDirective>;
+def OMPBarrierDirective : DStmt<OMPExecutableDirective>;
+def OMPTaskwaitDirective : DStmt<OMPExecutableDirective>;
+def OMPFlushDirective : DStmt<OMPExecutableDirective>;
+def OMPOrderedDirective : DStmt<OMPExecutableDirective>;
+def OMPAtomicDirective : DStmt<OMPExecutableDirective>;
+def OMPTargetDirective : DStmt<OMPExecutableDirective>;
+def OMPTeamsDirective : DStmt<OMPExecutableDirective>;
diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h
index b1652bed07..e112c654b5 100644
--- a/include/clang/Basic/TargetBuiltins.h
+++ b/include/clang/Basic/TargetBuiltins.h
@@ -13,8 +13,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_BASIC_TARGET_BUILTINS_H
-#define LLVM_CLANG_BASIC_TARGET_BUILTINS_H
+#ifndef LLVM_CLANG_BASIC_TARGETBUILTINS_H
+#define LLVM_CLANG_BASIC_TARGETBUILTINS_H
#include "clang/Basic/Builtins.h"
#undef PPC
@@ -164,6 +164,17 @@ namespace clang {
LastTSBuiltin
};
}
+
+ /// \brief Le64 builtins
+ namespace Le64 {
+ enum {
+ LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+ #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+ #include "clang/Basic/BuiltinsLe64.def"
+ LastTSBuiltin
+ };
+ }
+
} // end namespace clang.
#endif
diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h
index f9e37c360b..5669d2a559 100644
--- a/include/clang/Basic/TargetCXXABI.h
+++ b/include/clang/Basic/TargetCXXABI.h
@@ -13,8 +13,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TARGETCXXABI_H
-#define LLVM_CLANG_TARGETCXXABI_H
+#ifndef LLVM_CLANG_BASIC_TARGETCXXABI_H
+#define LLVM_CLANG_BASIC_TARGETCXXABI_H
#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index f4dcc0e5b5..8c2b89c736 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -170,7 +170,7 @@ public:
};
protected:
- IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
+ IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType,
WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType,
ProcessIDType;
@@ -206,22 +206,44 @@ protected:
public:
IntType getSizeType() const { return SizeType; }
IntType getIntMaxType() const { return IntMaxType; }
- IntType getUIntMaxType() const { return UIntMaxType; }
+ IntType getUIntMaxType() const {
+ return getCorrespondingUnsignedType(IntMaxType);
+ }
IntType getPtrDiffType(unsigned AddrSpace) const {
return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
}
IntType getIntPtrType() const { return IntPtrType; }
IntType getUIntPtrType() const {
- return getIntTypeByWidth(getTypeWidth(IntPtrType), false);
+ return getCorrespondingUnsignedType(IntPtrType);
}
IntType getWCharType() const { return WCharType; }
IntType getWIntType() const { return WIntType; }
IntType getChar16Type() const { return Char16Type; }
IntType getChar32Type() const { return Char32Type; }
IntType getInt64Type() const { return Int64Type; }
+ IntType getUInt64Type() const {
+ return getCorrespondingUnsignedType(Int64Type);
+ }
IntType getSigAtomicType() const { return SigAtomicType; }
IntType getProcessIDType() const { return ProcessIDType; }
+ static IntType getCorrespondingUnsignedType(IntType T) {
+ switch (T) {
+ case SignedChar:
+ return UnsignedChar;
+ case SignedShort:
+ return UnsignedShort;
+ case SignedInt:
+ return UnsignedInt;
+ case SignedLong:
+ return UnsignedLong;
+ case SignedLongLong:
+ return UnsignedLongLong;
+ default:
+ llvm_unreachable("Unexpected signed integer type");
+ }
+ }
+
/// \brief Return the width (in bits) of the specified integer type enum.
///
/// For example, SignedInt -> getIntWidth().
@@ -424,7 +446,13 @@ public:
/// \brief Return the constant suffix for the specified integer type enum.
///
/// For example, SignedLong -> "L".
- static const char *getTypeConstantSuffix(IntType T);
+ const char *getTypeConstantSuffix(IntType T) const;
+
+ /// \brief Return the printf format modifier for the specified
+ /// integer type enum.
+ ///
+ /// For example, SignedLong -> "l".
+ static const char *getTypeFormatModifier(IntType T);
/// \brief Check whether the given real type should use the "fpret" flavor of
/// Objective-C message passing on this target.
@@ -549,13 +577,21 @@ public:
bool validateInputConstraint(ConstraintInfo *OutputConstraints,
unsigned NumOutputs,
ConstraintInfo &info) const;
+
+ virtual bool validateOutputSize(StringRef /*Constraint*/,
+ unsigned /*Size*/) const {
+ return true;
+ }
+
virtual bool validateInputSize(StringRef /*Constraint*/,
unsigned /*Size*/) const {
return true;
}
- virtual bool validateConstraintModifier(StringRef /*Constraint*/,
- const char /*Modifier*/,
- unsigned /*Size*/) const {
+ virtual bool
+ validateConstraintModifier(StringRef /*Constraint*/,
+ char /*Modifier*/,
+ unsigned /*Size*/,
+ std::string &/*SuggestedModifier*/) const {
return true;
}
bool resolveSymbolicName(const char *&Name,
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index 2c86c31c23..9782539420 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
-#define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
+#ifndef LLVM_CLANG_BASIC_TARGETOPTIONS_H
+#define LLVM_CLANG_BASIC_TARGETOPTIONS_H
#include <string>
#include <vector>
diff --git a/include/clang/Basic/TemplateKinds.h b/include/clang/Basic/TemplateKinds.h
index b730143b63..aed287b462 100644
--- a/include/clang/Basic/TemplateKinds.h
+++ b/include/clang/Basic/TemplateKinds.h
@@ -11,8 +11,8 @@
/// \brief Defines the clang::TemplateNameKind enum.
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TEMPLATEKINDS_H
-#define LLVM_CLANG_TEMPLATEKINDS_H
+#ifndef LLVM_CLANG_BASIC_TEMPLATEKINDS_H
+#define LLVM_CLANG_BASIC_TEMPLATEKINDS_H
namespace clang {
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 5d088336df..c63dea0fa5 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -117,6 +117,7 @@ TOK(eod) // End of preprocessing directive (end of line inside a
// directive).
TOK(code_completion) // Code completion marker
TOK(cxx_defaultarg_end) // C++ default argument end marker
+TOK(cxx_exceptspec_end) // C++ exception-specification end marker
// C99 6.4.9: Comments.
TOK(comment) // Comment (only in -E -C[C] mode)
@@ -133,6 +134,9 @@ TOK(numeric_constant) // 0x123
TOK(char_constant) // 'a'
TOK(wide_char_constant) // L'b'
+// C++1z Character Constants
+TOK(utf8_char_constant) // u8'a'
+
// C++11 Character Constants
TOK(utf16_char_constant) // u'a'
TOK(utf32_char_constant) // U'a'
@@ -457,8 +461,10 @@ KEYWORD(__cdecl , KEYALL)
KEYWORD(__stdcall , KEYALL)
KEYWORD(__fastcall , KEYALL)
KEYWORD(__thiscall , KEYALL)
+KEYWORD(__vectorcall , KEYALL)
KEYWORD(__forceinline , KEYMS)
KEYWORD(__unaligned , KEYMS)
+KEYWORD(__super , KEYMS)
// OpenCL address space qualifiers
KEYWORD(__global , KEYOPENCL)
@@ -545,8 +551,12 @@ KEYWORD(__multiple_inheritance , KEYMS)
KEYWORD(__virtual_inheritance , KEYMS)
KEYWORD(__interface , KEYMS)
ALIAS("__int8" , char , KEYMS)
+ALIAS("_int8" , char , KEYMS)
ALIAS("__int16" , short , KEYMS)
+ALIAS("_int16" , short , KEYMS)
ALIAS("__int32" , int , KEYMS)
+ALIAS("_int32" , int , KEYMS)
+ALIAS("_int64" , __int64 , KEYMS)
ALIAS("__wchar_t" , wchar_t , KEYMS)
ALIAS("_asm" , asm , KEYMS)
ALIAS("_alignof" , __alignof , KEYMS)
@@ -555,6 +565,7 @@ ALIAS("_cdecl" , __cdecl , KEYMS | KEYBORLAND)
ALIAS("_fastcall" , __fastcall , KEYMS | KEYBORLAND)
ALIAS("_stdcall" , __stdcall , KEYMS | KEYBORLAND)
ALIAS("_thiscall" , __thiscall , KEYMS)
+ALIAS("_vectorcall" , __vectorcall, KEYMS)
ALIAS("_uuidof" , __uuidof , KEYMS | KEYBORLAND)
ALIAS("_inline" , inline , KEYMS)
ALIAS("_declspec" , __declspec , KEYMS)
diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h
index 794625ca91..f4ecb3eb30 100644
--- a/include/clang/Basic/TokenKinds.h
+++ b/include/clang/Basic/TokenKinds.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOKENKINDS_H
-#define LLVM_CLANG_TOKENKINDS_H
+#ifndef LLVM_CLANG_BASIC_TOKENKINDS_H
+#define LLVM_CLANG_BASIC_TOKENKINDS_H
#include "llvm/Support/Compiler.h"
@@ -86,9 +86,9 @@ inline bool isStringLiteral(TokenKind K) {
/// constant, string, etc.
inline bool isLiteral(TokenKind K) {
return K == tok::numeric_constant || K == tok::char_constant ||
- K == tok::wide_char_constant || K == tok::utf16_char_constant ||
- K == tok::utf32_char_constant || isStringLiteral(K) ||
- K == tok::angle_string_literal;
+ K == tok::wide_char_constant || K == tok::utf8_char_constant ||
+ K == tok::utf16_char_constant || K == tok::utf32_char_constant ||
+ isStringLiteral(K) || K == tok::angle_string_literal;
}
/// \brief Return true if this is any of tok::annot_* kinds.
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
index d7d2b18f31..ef84d2b111 100644
--- a/include/clang/Basic/TypeTraits.h
+++ b/include/clang/Basic/TypeTraits.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TYPETRAITS_H
-#define LLVM_CLANG_TYPETRAITS_H
+#ifndef LLVM_CLANG_BASIC_TYPETRAITS_H
+#define LLVM_CLANG_BASIC_TYPETRAITS_H
namespace clang {
diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h
index 54d06e0739..77fd947f96 100644
--- a/include/clang/Basic/VersionTuple.h
+++ b/include/clang/Basic/VersionTuple.h
@@ -24,30 +24,35 @@ namespace clang {
/// \brief Represents a version number in the form major[.minor[.subminor]].
class VersionTuple {
- unsigned Major;
+ unsigned Major : 31;
unsigned Minor : 31;
unsigned Subminor : 31;
unsigned HasMinor : 1;
unsigned HasSubminor : 1;
+ unsigned UsesUnderscores : 1;
public:
VersionTuple()
- : Major(0), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false) { }
+ : Major(0), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false),
+ UsesUnderscores(false) { }
explicit VersionTuple(unsigned Major)
- : Major(Major), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false)
+ : Major(Major), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false),
+ UsesUnderscores(false)
{ }
- explicit VersionTuple(unsigned Major, unsigned Minor)
+ explicit VersionTuple(unsigned Major, unsigned Minor,
+ bool UsesUnderscores = false)
: Major(Major), Minor(Minor), Subminor(0), HasMinor(true),
- HasSubminor(false)
+ HasSubminor(false), UsesUnderscores(UsesUnderscores)
{ }
- explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor)
+ explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor,
+ bool UsesUnderscores = false)
: Major(Major), Minor(Minor), Subminor(Subminor), HasMinor(true),
- HasSubminor(true)
+ HasSubminor(true), UsesUnderscores(UsesUnderscores)
{ }
-
+
/// \brief Determine whether this version information is empty
/// (e.g., all version components are zero).
bool empty() const { return Major == 0 && Minor == 0 && Subminor == 0; }
@@ -69,6 +74,14 @@ public:
return Subminor;
}
+ bool usesUnderscores() const {
+ return UsesUnderscores;
+ }
+
+ void UseDotAsSeparator() {
+ UsesUnderscores = false;
+ }
+
/// \brief Determine if two version numbers are equivalent. If not
/// provided, minor and subminor version numbers are considered to be zero.
friend bool operator==(const VersionTuple& X, const VersionTuple &Y) {
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
index 36f78fd872..708659634d 100644
--- a/include/clang/Basic/VirtualFileSystem.h
+++ b/include/clang/Basic/VirtualFileSystem.h
@@ -10,8 +10,8 @@
/// \brief Defines the virtual file system interface vfs::FileSystem.
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
-#define LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
+#ifndef LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H
+#define LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -89,11 +89,9 @@ public:
/// \brief Get the status of the file.
virtual llvm::ErrorOr<Status> status() = 0;
/// \brief Get the contents of the file as a \p MemoryBuffer.
- virtual std::error_code getBuffer(const Twine &Name,
- std::unique_ptr<llvm::MemoryBuffer> &Result,
- int64_t FileSize = -1,
- bool RequiresNullTerminator = true,
- bool IsVolatile = false) = 0;
+ virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+ getBuffer(const Twine &Name, int64_t FileSize = -1,
+ bool RequiresNullTerminator = true, bool IsVolatile = false) = 0;
/// \brief Closes the file.
virtual std::error_code close() = 0;
/// \brief Sets the name to use for this file.
@@ -188,16 +186,14 @@ public:
/// \brief Get the status of the entry at \p Path, if one exists.
virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0;
/// \brief Get a \p File object for the file at \p Path, if one exists.
- virtual std::error_code openFileForRead(const Twine &Path,
- std::unique_ptr<File> &Result) = 0;
+ virtual llvm::ErrorOr<std::unique_ptr<File>>
+ openFileForRead(const Twine &Path) = 0;
/// This is a convenience method that opens a file, gets its content and then
/// closes the file.
- std::error_code getBufferForFile(const Twine &Name,
- std::unique_ptr<llvm::MemoryBuffer> &Result,
- int64_t FileSize = -1,
- bool RequiresNullTerminator = true,
- bool IsVolatile = false);
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+ getBufferForFile(const Twine &Name, int64_t FileSize = -1,
+ bool RequiresNullTerminator = true, bool IsVolatile = false);
/// \brief Get a directory_iterator for \p Dir.
/// \note The 'end' iterator is directory_iterator().
@@ -231,8 +227,8 @@ public:
void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS);
llvm::ErrorOr<Status> status(const Twine &Path) override;
- std::error_code openFileForRead(const Twine &Path,
- std::unique_ptr<File> &Result) override;
+ llvm::ErrorOr<std::unique_ptr<File>>
+ openFileForRead(const Twine &Path) override;
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
typedef FileSystemList::reverse_iterator iterator;
@@ -250,10 +246,8 @@ llvm::sys::fs::UniqueID getNextVirtualUniqueID();
/// \brief Gets a \p FileSystem for a virtual file system described in YAML
/// format.
-///
-/// Takes ownership of \p Buffer.
IntrusiveRefCntPtr<FileSystem>
-getVFSFromYAML(llvm::MemoryBuffer *Buffer,
+getVFSFromYAML(std::unique_ptr<llvm::MemoryBuffer> Buffer,
llvm::SourceMgr::DiagHandlerTy DiagHandler,
void *DiagContext = nullptr,
IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem());
@@ -280,4 +274,4 @@ public:
} // end namespace vfs
} // end namespace clang
-#endif // LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
+#endif
diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td
index f68ccea655..933f204bfb 100644
--- a/include/clang/Basic/arm_neon.td
+++ b/include/clang/Basic/arm_neon.td
@@ -87,7 +87,7 @@ def call;
def cast;
// bitcast - Same as "cast", except a reinterpret-cast is produced:
// (bitcast "T", $p0) -> "*(T*)&__p0".
-// The VAL argument is saved to a temprary so it can be used
+// The VAL argument is saved to a temporary so it can be used
// as an l-value.
def bitcast;
// dup - Take a scalar argument and create a vector by duplicating it into
@@ -944,13 +944,6 @@ def VCVT_F64 : SInst<"vcvt_f64", "Fd", "lUlQlQUl">;
def VCVT_HIGH_F64_F32 : SOpInst<"vcvt_high_f64", "wj", "f", OP_VCVT_EX_HI_F64>;
def VCVTX_F32_F64 : SInst<"vcvtx_f32", "fj", "d">;
def VCVTX_HIGH_F32_F64 : SOpInst<"vcvtx_high_f32", "qfj", "d", OP_VCVTX_HI>;
-def FRINTN : SInst<"vrndn", "dd", "fdQfQd">;
-def FRINTA : SInst<"vrnda", "dd", "fdQfQd">;
-def FRINTP : SInst<"vrndp", "dd", "fdQfQd">;
-def FRINTM : SInst<"vrndm", "dd", "fdQfQd">;
-def FRINTX : SInst<"vrndx", "dd", "fdQfQd">;
-def FRINTZ : SInst<"vrnd", "dd", "fdQfQd">;
-def FRINTI : SInst<"vrndi", "dd", "fdQfQd">;
def VCVT_S64 : SInst<"vcvt_s64", "xd", "dQd">;
def VCVT_U64 : SInst<"vcvt_u64", "ud", "dQd">;
def FRECPE : SInst<"vrecpe", "dd", "dQd">;
@@ -983,11 +976,6 @@ def MAX : SInst<"vmax", "ddd", "dQd">;
def MIN : SInst<"vmin", "ddd", "dQd">;
////////////////////////////////////////////////////////////////////////////////
-// MaxNum/MinNum Floating Point
-def FMAXNM : SInst<"vmaxnm", "ddd", "fdQfQd">;
-def FMINNM : SInst<"vminnm", "ddd", "fdQfQd">;
-
-////////////////////////////////////////////////////////////////////////////////
// Pairwise Max/Min
def MAXP : SInst<"vpmax", "ddd", "QcQsQiQUcQUsQUiQfQd">;
def MINP : SInst<"vpmin", "ddd", "QcQsQiQUcQUsQUiQfQd">;
@@ -1089,7 +1077,7 @@ def VDUP_LANE2: WOpInst<"vdup_laneq", "dji",
"csilUcUsUiUlPcPshfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl",
OP_DUP_LN>;
def DUP_N : WOpInst<"vdup_n", "ds", "dQdPlQPl", OP_DUP>;
-def MOV_N : WOpInst<"vmov_n", "ds", "dQd", OP_DUP>;
+def MOV_N : WOpInst<"vmov_n", "ds", "dQdPlQPl", OP_DUP>;
////////////////////////////////////////////////////////////////////////////////
def COMBINE : NoTestOpInst<"vcombine", "kdd", "dPl", OP_CONC>;
@@ -1223,6 +1211,41 @@ def FCVTAU_S64 : SInst<"vcvta_u64", "ud", "dQd">;
}
////////////////////////////////////////////////////////////////////////////////
+// Round to Integral
+
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING)" in {
+def FRINTN_S32 : SInst<"vrndn", "dd", "fQf">;
+def FRINTA_S32 : SInst<"vrnda", "dd", "fQf">;
+def FRINTP_S32 : SInst<"vrndp", "dd", "fQf">;
+def FRINTM_S32 : SInst<"vrndm", "dd", "fQf">;
+def FRINTX_S32 : SInst<"vrndx", "dd", "fQf">;
+def FRINTZ_S32 : SInst<"vrnd", "dd", "fQf">;
+}
+
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__) && defined(__ARM_FEATURE_DIRECTED_ROUNDING)" in {
+def FRINTN_S64 : SInst<"vrndn", "dd", "dQd">;
+def FRINTA_S64 : SInst<"vrnda", "dd", "dQd">;
+def FRINTP_S64 : SInst<"vrndp", "dd", "dQd">;
+def FRINTM_S64 : SInst<"vrndm", "dd", "dQd">;
+def FRINTX_S64 : SInst<"vrndx", "dd", "dQd">;
+def FRINTZ_S64 : SInst<"vrnd", "dd", "dQd">;
+def FRINTI_S64 : SInst<"vrndi", "dd", "fdQfQd">;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// MaxNum/MinNum Floating Point
+
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN)" in {
+def FMAXNM_S32 : SInst<"vmaxnm", "ddd", "fQf">;
+def FMINNM_S32 : SInst<"vminnm", "ddd", "fQf">;
+}
+
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__) && defined(__ARM_FEATURE_NUMERIC_MAXMIN)" in {
+def FMAXNM_S64 : SInst<"vmaxnm", "ddd", "dQd">;
+def FMINNM_S64 : SInst<"vminnm", "ddd", "dQd">;
+}
+
+////////////////////////////////////////////////////////////////////////////////
// Permutation
def VTRN1 : SOpInst<"vtrn1", "ddd",
"csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_TRN1>;
diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h
index f8b90b34ee..07c6183683 100644
--- a/include/clang/CodeGen/BackendUtil.h
+++ b/include/clang/CodeGen/BackendUtil.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CODEGEN_BACKEND_UTIL_H
-#define LLVM_CLANG_CODEGEN_BACKEND_UTIL_H
+#ifndef LLVM_CLANG_CODEGEN_BACKENDUTIL_H
+#define LLVM_CLANG_CODEGEN_BACKENDUTIL_H
#include "clang/Basic/LLVM.h"
diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h
index 449827e028..8aea6c3708 100644
--- a/include/clang/CodeGen/CGFunctionInfo.h
+++ b/include/clang/CodeGen/CGFunctionInfo.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CODEGEN_FUNCTION_INFO_H
-#define LLVM_CLANG_CODEGEN_FUNCTION_INFO_H
+#ifndef LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
+#define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
#include "clang/AST/CanonicalType.h"
#include "clang/AST/Type.h"
@@ -87,6 +87,7 @@ private:
bool IndirectRealign : 1; // isIndirect()
bool SRetAfterThis : 1; // isIndirect()
bool InReg : 1; // isDirect() || isExtend() || isIndirect()
+ bool CanBeFlattened: 1; // isDirect()
ABIArgInfo(Kind K)
: PaddingType(nullptr), TheKind(K), PaddingInReg(false), InReg(false) {}
@@ -97,11 +98,13 @@ public:
TheKind(Direct), PaddingInReg(false), InReg(false) {}
static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
- llvm::Type *Padding = nullptr) {
+ llvm::Type *Padding = nullptr,
+ bool CanBeFlattened = true) {
auto AI = ABIArgInfo(Direct);
AI.setCoerceToType(T);
AI.setDirectOffset(Offset);
AI.setPaddingType(Padding);
+ AI.setCanBeFlattened(CanBeFlattened);
return AI;
}
static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
@@ -265,6 +268,16 @@ public:
InAllocaSRet = SRet;
}
+ bool getCanBeFlattened() const {
+ assert(isDirect() && "Invalid kind!");
+ return CanBeFlattened;
+ }
+
+ void setCanBeFlattened(bool Flatten) {
+ assert(isDirect() && "Invalid kind!");
+ CanBeFlattened = Flatten;
+ }
+
void dump() const;
};
@@ -393,6 +406,9 @@ public:
bool isVariadic() const { return Required.allowsOptionalArgs(); }
RequiredArgs getRequiredArgs() const { return Required; }
+ unsigned getNumRequiredArgs() const {
+ return isVariadic() ? getRequiredArgs().getNumRequiredArgs() : arg_size();
+ }
bool isInstanceMethod() const { return InstanceMethod; }
diff --git a/include/clang/CodeGen/CodeGenABITypes.h b/include/clang/CodeGen/CodeGenABITypes.h
index 2502982b23..97a9dc8294 100644
--- a/include/clang/CodeGen/CodeGenABITypes.h
+++ b/include/clang/CodeGen/CodeGenABITypes.h
@@ -21,8 +21,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CODEGEN_ABITYPES_H
-#define LLVM_CLANG_CODEGEN_ABITYPES_H
+#ifndef LLVM_CLANG_CODEGEN_CODEGENABITYPES_H
+#define LLVM_CLANG_CODEGEN_CODEGENABITYPES_H
#include "clang/AST/CanonicalType.h"
#include "clang/AST/Type.h"
@@ -39,6 +39,7 @@ class CXXRecordDecl;
class CodeGenOptions;
class DiagnosticsEngine;
class ObjCMethodDecl;
+class CoverageSourceInfo;
namespace CodeGen {
class CGFunctionInfo;
@@ -47,7 +48,8 @@ class CodeGenModule;
class CodeGenABITypes
{
public:
- CodeGenABITypes(ASTContext &C, llvm::Module &M, const llvm::DataLayout &TD);
+ CodeGenABITypes(ASTContext &C, llvm::Module &M, const llvm::DataLayout &TD,
+ CoverageSourceInfo *CoverageInfo = nullptr);
~CodeGenABITypes();
/// These methods all forward to methods in the private implementation class
diff --git a/include/clang/CodeGen/CodeGenAction.h b/include/clang/CodeGen/CodeGenAction.h
index 37819c780d..f8fd56152f 100644
--- a/include/clang/CodeGen/CodeGenAction.h
+++ b/include/clang/CodeGen/CodeGenAction.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_CODEGEN_CODE_GEN_ACTION_H
-#define LLVM_CLANG_CODEGEN_CODE_GEN_ACTION_H
+#ifndef LLVM_CLANG_CODEGEN_CODEGENACTION_H
+#define LLVM_CLANG_CODEGEN_CODEGENACTION_H
#include "clang/Frontend/FrontendAction.h"
#include <memory>
@@ -37,8 +37,8 @@ protected:
bool hasIRSupport() const override;
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
void ExecuteAction() override;
@@ -52,9 +52,9 @@ public:
/// the action will load it from the specified file.
void setLinkModule(llvm::Module *Mod) { LinkModule = Mod; }
- /// takeModule - Take the generated LLVM module, for use after the action has
- /// been run. The result may be null on failure.
- llvm::Module *takeModule();
+ /// Take the generated LLVM module, for use after the action has been run.
+ /// The result may be null on failure.
+ std::unique_ptr<llvm::Module> takeModule();
/// Take the LLVM context used by this action.
llvm::LLVMContext *takeLLVMContext();
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index 4b7236bfd0..f4c31074e9 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -24,6 +24,7 @@ namespace llvm {
namespace clang {
class DiagnosticsEngine;
+ class CoverageSourceInfo;
class LangOptions;
class CodeGenOptions;
class TargetOptions;
@@ -44,7 +45,8 @@ namespace clang {
const std::string &ModuleName,
const CodeGenOptions &CGO,
const TargetOptions &TO,
- llvm::LLVMContext& C);
+ llvm::LLVMContext& C,
+ CoverageSourceInfo *CoverageInfo = nullptr);
}
#endif
diff --git a/include/clang/Config/config.h b/include/clang/Config/config.h
index d469a0edeb..e106019b14 100644
--- a/include/clang/Config/config.h
+++ b/include/clang/Config/config.h
@@ -25,7 +25,7 @@
/* Define if we have libxml2 */
/* #undef CLANG_HAVE_LIBXML */
-#define PACKAGE_STRING "LLVM 3.5.0svn"
+#define PACKAGE_STRING "LLVM 3.6.0svn"
/* The LLVM product name and version */
#define BACKEND_PACKAGE_STRING PACKAGE_STRING
diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
index 7629ef9129..38b398cffd 100644
--- a/include/clang/Config/config.h.cmake
+++ b/include/clang/Config/config.h.cmake
@@ -26,4 +26,7 @@
/* The LLVM product name and version */
#define BACKEND_PACKAGE_STRING "${BACKEND_PACKAGE_STRING}"
+/* Linker version detected at compile time. */
+#cmakedefine HOST_LINK_VERSION "${HOST_LINK_VERSION}"
+
#endif
diff --git a/include/clang/Config/config.h.in b/include/clang/Config/config.h.in
index 1530fefaa5..3c2cb075ef 100644
--- a/include/clang/Config/config.h.in
+++ b/include/clang/Config/config.h.in
@@ -14,9 +14,6 @@
/* Directories clang will search for headers */
#undef C_INCLUDE_DIRS
-/* Linker version detected at compile time. */
-#undef HOST_LINK_VERSION
-
/* Default <path> to all compiler invocations for --sysroot=<path>. */
#undef DEFAULT_SYSROOT
@@ -31,4 +28,7 @@
/* The LLVM product name and version */
#define BACKEND_PACKAGE_STRING PACKAGE_STRING
+/* Linker version detected at compile time. */
+#undef HOST_LINK_VERSION
+
#endif
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
index 2cdb581b85..2739d4934d 100644
--- a/include/clang/Driver/Action.h
+++ b/include/clang/Driver/Action.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_DRIVER_ACTION_H_
-#define CLANG_DRIVER_ACTION_H_
+#ifndef LLVM_CLANG_DRIVER_ACTION_H
+#define LLVM_CLANG_DRIVER_ACTION_H
#include "clang/Driver/Types.h"
#include "clang/Driver/Util.h"
@@ -72,8 +72,12 @@ private:
protected:
Action(ActionClass _Kind, types::ID _Type)
: Kind(_Kind), Type(_Type), OwnsInputs(true) {}
- Action(ActionClass _Kind, Action *Input, types::ID _Type)
- : Kind(_Kind), Type(_Type), Inputs(&Input, &Input + 1), OwnsInputs(true) {}
+ Action(ActionClass _Kind, std::unique_ptr<Action> Input, types::ID _Type)
+ : Kind(_Kind), Type(_Type), Inputs(1, Input.release()), OwnsInputs(true) {
+ }
+ Action(ActionClass _Kind, std::unique_ptr<Action> Input)
+ : Kind(_Kind), Type(Input->getType()), Inputs(1, Input.release()),
+ OwnsInputs(true) {}
Action(ActionClass _Kind, const ActionList &_Inputs, types::ID _Type)
: Kind(_Kind), Type(_Type), Inputs(_Inputs), OwnsInputs(true) {}
public:
@@ -119,7 +123,7 @@ class BindArchAction : public Action {
const char *ArchName;
public:
- BindArchAction(Action *Input, const char *_ArchName);
+ BindArchAction(std::unique_ptr<Action> Input, const char *_ArchName);
const char *getArchName() const { return ArchName; }
@@ -131,7 +135,7 @@ public:
class JobAction : public Action {
virtual void anchor();
protected:
- JobAction(ActionClass Kind, Action *Input, types::ID Type);
+ JobAction(ActionClass Kind, std::unique_ptr<Action> Input, types::ID Type);
JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type);
public:
@@ -144,7 +148,7 @@ public:
class PreprocessJobAction : public JobAction {
void anchor() override;
public:
- PreprocessJobAction(Action *Input, types::ID OutputType);
+ PreprocessJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == PreprocessJobClass;
@@ -154,7 +158,7 @@ public:
class PrecompileJobAction : public JobAction {
void anchor() override;
public:
- PrecompileJobAction(Action *Input, types::ID OutputType);
+ PrecompileJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == PrecompileJobClass;
@@ -164,7 +168,7 @@ public:
class AnalyzeJobAction : public JobAction {
void anchor() override;
public:
- AnalyzeJobAction(Action *Input, types::ID OutputType);
+ AnalyzeJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == AnalyzeJobClass;
@@ -174,7 +178,7 @@ public:
class MigrateJobAction : public JobAction {
void anchor() override;
public:
- MigrateJobAction(Action *Input, types::ID OutputType);
+ MigrateJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == MigrateJobClass;
@@ -184,7 +188,7 @@ public:
class CompileJobAction : public JobAction {
void anchor() override;
public:
- CompileJobAction(Action *Input, types::ID OutputType);
+ CompileJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == CompileJobClass;
@@ -194,7 +198,7 @@ public:
class AssembleJobAction : public JobAction {
void anchor() override;
public:
- AssembleJobAction(Action *Input, types::ID OutputType);
+ AssembleJobAction(std::unique_ptr<Action> Input, types::ID OutputType);
static bool classof(const Action *A) {
return A->getKind() == AssembleJobClass;
@@ -234,7 +238,8 @@ public:
class VerifyJobAction : public JobAction {
void anchor() override;
public:
- VerifyJobAction(ActionClass Kind, Action *Input, types::ID Type);
+ VerifyJobAction(ActionClass Kind, std::unique_ptr<Action> Input,
+ types::ID Type);
VerifyJobAction(ActionClass Kind, ActionList &Inputs, types::ID Type);
static bool classof(const Action *A) {
return A->getKind() == VerifyDebugInfoJobClass ||
@@ -245,7 +250,7 @@ public:
class VerifyDebugInfoJobAction : public VerifyJobAction {
void anchor() override;
public:
- VerifyDebugInfoJobAction(Action *Input, types::ID Type);
+ VerifyDebugInfoJobAction(std::unique_ptr<Action> Input, types::ID Type);
static bool classof(const Action *A) {
return A->getKind() == VerifyDebugInfoJobClass;
}
@@ -254,7 +259,7 @@ public:
class VerifyPCHJobAction : public VerifyJobAction {
void anchor() override;
public:
- VerifyPCHJobAction(Action *Input, types::ID Type);
+ VerifyPCHJobAction(std::unique_ptr<Action> Input, types::ID Type);
static bool classof(const Action *A) {
return A->getKind() == VerifyPCHJobClass;
}
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index d25560c9f3..fbab14b51b 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -108,6 +108,9 @@ def analyzer_disable_checker : Separate<["-"], "analyzer-disable-checker">,
def analyzer_disable_checker_EQ : Joined<["-"], "analyzer-disable-checker=">,
Alias<analyzer_disable_checker>;
+def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">,
+ HelpText<"Disable all static analyzer checks">;
+
def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">,
HelpText<"Display the list of analyzer checkers that are available">;
@@ -135,6 +138,8 @@ def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
HelpText<"The string to embed in the Dwarf debug flags record.">;
def mno_exec_stack : Flag<["-"], "mnoexecstack">,
HelpText<"Mark the file as not needing an executable stack">;
+def massembler_fatal_warnings : Flag<["-"], "massembler-fatal-warnings">,
+ HelpText<"Make assembler warnings fatal">;
def compress_debug_sections : Flag<["-"], "compress-debug-sections">,
HelpText<"Compress DWARF debug sections using zlib">;
def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
@@ -164,6 +169,8 @@ def no_implicit_float : Flag<["-"], "no-implicit-float">,
HelpText<"Don't generate implicit floating point instructions">;
def fdump_vtable_layouts : Flag<["-"], "fdump-vtable-layouts">,
HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">;
+def fmerge_functions : Flag<["-"], "fmerge-functions">,
+ HelpText<"Permit merging of identical functions when optimizing.">;
def femit_coverage_notes : Flag<["-"], "femit-coverage-notes">,
HelpText<"Emit a gcov coverage notes file when compiling.">;
def femit_coverage_data: Flag<["-"], "femit-coverage-data">,
@@ -179,6 +186,8 @@ def coverage_version_EQ : Joined<["-"], "coverage-version=">,
HelpText<"Four-byte version string for gcov files.">;
def test_coverage : Flag<["-"], "test-coverage">,
HelpText<"Do not generate coverage files or remove coverage changes from IR">;
+def dump_coverage_mapping : Flag<["-"], "dump-coverage-mapping">,
+ HelpText<"Dump the coverage mapping records, for testing">;
def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfield-access">,
HelpText<"Use register sized accesses to bit-fields, when possible.">;
def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">,
@@ -321,12 +330,13 @@ def ast_dump_filter : Separate<["-"], "ast-dump-filter">,
HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration"
" nodes having a certain substring in a qualified name. Use"
" -ast-list to list all filterable declaration node names.">;
-def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">,
- HelpText<"Include name lookup table dumps in AST dumps">;
def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">,
HelpText<"Do not automatically generate or update the global module index">;
def fno_modules_error_recovery : Flag<["-"], "fno-modules-error-recovery">,
HelpText<"Do not automatically import modules for error recovery">;
+def fmodule_implementation_of : Separate<["-"], "fmodule-implementation-of">,
+ MetaVarName<"<name>">,
+ HelpText<"Specify the name of the module whose implementation file this is">;
let Group = Action_Group in {
@@ -355,6 +365,8 @@ def ast_list : Flag<["-"], "ast-list">,
HelpText<"Build ASTs and print the list of declaration node qualified names">;
def ast_dump : Flag<["-"], "ast-dump">,
HelpText<"Build ASTs and then debug dump them">;
+def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">,
+ HelpText<"Build ASTs and then debug dump their name lookup tables">;
def ast_view : Flag<["-"], "ast-view">,
HelpText<"Build ASTs and view them with GraphViz">;
def print_decl_contexts : Flag<["-"], "print-decl-contexts">,
@@ -497,13 +509,15 @@ def fdeprecated_macro : Flag<["-"], "fdeprecated-macro">,
def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">,
HelpText<"Undefines the __DEPRECATED macro">;
def fsized_deallocation : Flag<["-"], "fsized-deallocation">,
- HelpText<"Enable C++1y sized global deallocation functions">;
+ HelpText<"Enable C++14 sized global deallocation functions">;
def fobjc_subscripting_legacy_runtime : Flag<["-"], "fobjc-subscripting-legacy-runtime">,
HelpText<"Allow Objective-C array and dictionary subscripting in legacy runtime">;
def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">,
HelpText<"Control vtordisp placement on win32 targets">;
def fno_rtti_data : Flag<["-"], "fno-rtti-data">,
HelpText<"Control emission of RTTI data">;
+def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">,
+ HelpText<"Allow function arguments and returns of type half">;
//===----------------------------------------------------------------------===//
// Header Search Options
@@ -569,6 +583,8 @@ def cl_mad_enable : Flag<["-"], "cl-mad-enable">,
HelpText<"OpenCL only. Enable less precise MAD instructions to be generated.">;
def cl_std_EQ : Joined<["-"], "cl-std=">,
HelpText<"OpenCL language standard to compile for">;
+def cl_denorms_are_zero : Flag<["-"], "cl-denorms-are-zero">,
+ HelpText<"OpenCL only. Allow denormals to be flushed to zero">;
//===----------------------------------------------------------------------===//
// CUDA Options
diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td
index 90e3aca406..e05d68700e 100644
--- a/include/clang/Driver/CLCompatOptions.td
+++ b/include/clang/Driver/CLCompatOptions.td
@@ -132,12 +132,21 @@ def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">,
def _SLASH_Z7 : CLFlag<"Z7">, Alias<gline_tables_only>;
def _SLASH_Zi : CLFlag<"Zi">, HelpText<"Enable debug information">,
Alias<gline_tables_only>;
+def _SLASH_Zp : CLJoined<"Zp">,
+ HelpText<"Specify the default maximum struct packing alignment">,
+ Alias<fpack_struct_EQ>;
+def _SLASH_Zp_flag : CLFlag<"Zp">,
+ HelpText<"Set the default maximum struct packing alignment to 1">,
+ Alias<fpack_struct_EQ>, AliasArgs<["1"]>;
def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">,
Alias<fsyntax_only>;
// Non-aliases:
+def _SLASH_arch : CLCompileJoined<"arch:">,
+ HelpText<"Set architecture for code generation">;
+
def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>;
def _SLASH_EH : CLJoined<"EH">, HelpText<"Exception handling model">;
@@ -173,6 +182,9 @@ def _SLASH_MT : Option<["/", "-"], "MT", KIND_FLAG>, Group<_SLASH_M_Group>,
Flags<[CLOption, DriverOption]>, HelpText<"Use static run-time">;
def _SLASH_MTd : Option<["/", "-"], "MTd", KIND_FLAG>, Group<_SLASH_M_Group>,
Flags<[CLOption, DriverOption]>, HelpText<"Use static debug run-time">;
+def _SLASH_o : CLJoinedOrSeparate<"o">,
+ HelpText<"Set output file or directory (ends in / or \\)">,
+ MetaVarName<"<file or directory>">;
def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">;
def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">,
HelpText<"Specify a C source file">, MetaVarName<"<filename>">;
@@ -185,6 +197,7 @@ def _SLASH_TP : CLCompileFlag<"TP">, HelpText<"Treat all source files as C++">;
// Ignored:
def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">;
+def _SLASH_d2Zi_PLUS : CLIgnoredFlag<"d2Zi+">;
def _SLASH_errorReport : CLIgnoredJoined<"errorReport">;
def _SLASH_FS : CLIgnoredFlag<"FS">, HelpText<"Force synchronous PDB writes">;
def _SLASH_GF : CLIgnoredFlag<"GF">;
@@ -202,15 +215,15 @@ def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">;
def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">;
def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
def _SLASH_Zm : CLIgnoredJoined<"Zm">;
+def _SLASH_Zo : CLIgnoredFlag<"Zo">;
+def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">;
// Unsupported:
def _SLASH_AI : CLJoined<"AI">;
-def _SLASH_arch : CLJoined<"arch:">;
def _SLASH_bigobj : CLFlag<"bigobj">;
def _SLASH_clr : CLJoined<"clr">;
-def _SLASH_d2Zi_PLUS : CLFlag<"d2Zi+">;
def _SLASH_doc : CLJoined<"doc">;
def _SLASH_FA_joined : CLJoined<"FA">;
def _SLASH_favor : CLJoined<"favor">;
@@ -248,7 +261,6 @@ def _SLASH_hotpatch : CLFlag<"hotpatch">;
def _SLASH_kernel : CLFlag<"kernel">;
def _SLASH_LN : CLFlag<"LN">;
def _SLASH_MP : CLJoined<"MP">;
-def _SLASH_o : CLJoinedOrSeparate<"o">;
def _SLASH_openmp : CLFlag<"openmp">;
def _SLASH_Qfast_transcendentals : CLFlag<"Qfast_transcendentals">;
def _SLASH_QIfist : CLFlag<"QIfist">;
@@ -272,5 +284,4 @@ def _SLASH_Ze : CLFlag<"Ze">;
def _SLASH_Zg : CLFlag<"Zg">;
def _SLASH_ZI : CLFlag<"ZI">;
def _SLASH_Zl : CLFlag<"Zl">;
-def _SLASH_Zp : CLJoined<"Zp">;
def _SLASH_ZW : CLJoined<"ZW">;
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
index c1c0f4326d..5574e2ca05 100644
--- a/include/clang/Driver/Compilation.h
+++ b/include/clang/Driver/Compilation.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_DRIVER_COMPILATION_H_
-#define CLANG_DRIVER_COMPILATION_H_
+#ifndef LLVM_CLANG_DRIVER_COMPILATION_H
+#define LLVM_CLANG_DRIVER_COMPILATION_H
#include "clang/Driver/Job.h"
#include "clang/Driver/Util.h"
@@ -94,7 +94,7 @@ public:
JobList &getJobs() { return Jobs; }
const JobList &getJobs() const { return Jobs; }
- void addCommand(Command *C) { Jobs.addJob(C); }
+ void addCommand(std::unique_ptr<Command> C) { Jobs.addJob(std::move(C)); }
const llvm::opt::ArgStringList &getTempFiles() const { return TempFiles; }
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index df974ad1d7..020966f8cd 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_DRIVER_DRIVER_H_
-#define CLANG_DRIVER_DRIVER_H_
+#ifndef LLVM_CLANG_DRIVER_DRIVER_H
+#define LLVM_CLANG_DRIVER_DRIVER_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
@@ -42,6 +42,7 @@ namespace driver {
class Command;
class Compilation;
class InputInfo;
+ class Job;
class JobAction;
class SanitizerArgs;
class ToolChain;
@@ -190,6 +191,12 @@ private:
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL,
llvm::opt::Arg **FinalPhaseArg = nullptr) const;
+ // Before executing jobs, sets up response files for commands that need them.
+ void setUpResponseFiles(Compilation &C, Job &J);
+
+ void generatePrefixedToolNames(const char *Tool, const ToolChain &TC,
+ SmallVectorImpl<std::string> &Names) const;
+
public:
Driver(StringRef _ClangExecutable,
StringRef _DefaultTargetTriple,
@@ -291,16 +298,16 @@ public:
/// arguments and return an appropriate exit code.
///
/// This routine handles additional processing that must be done in addition
- /// to just running the subprocesses, for example reporting errors, removing
- /// temporary files, etc.
- int ExecuteCompilation(const Compilation &C,
- SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands) const;
+ /// to just running the subprocesses, for example reporting errors, setting
+ /// up response files, removing temporary files, etc.
+ int ExecuteCompilation(Compilation &C,
+ SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands);
/// generateCompilationDiagnostics - Generate diagnostics information
/// including preprocessed source file(s).
///
void generateCompilationDiagnostics(Compilation &C,
- const Command *FailingCommand);
+ const Command &FailingCommand);
/// @}
/// @name Helper Methods
@@ -343,8 +350,9 @@ public:
/// ConstructAction - Construct the appropriate action to do for
/// \p Phase on the \p Input, taking in to account arguments
/// like -fsyntax-only or --analyze.
- Action *ConstructPhaseAction(const llvm::opt::ArgList &Args, phases::ID Phase,
- Action *Input) const;
+ std::unique_ptr<Action>
+ ConstructPhaseAction(const llvm::opt::ArgList &Args, phases::ID Phase,
+ std::unique_ptr<Action> Input) const;
/// BuildJobsForAction - Construct the jobs to perform for the
/// action \p A.
diff --git a/include/clang/Driver/DriverDiagnostic.h b/include/clang/Driver/DriverDiagnostic.h
index f3c33aeccb..680338a2ea 100644
--- a/include/clang/Driver/DriverDiagnostic.h
+++ b/include/clang/Driver/DriverDiagnostic.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_DRIVERDIAGNOSTIC_H
-#define LLVM_CLANG_DRIVERDIAGNOSTIC_H
+#ifndef LLVM_CLANG_DRIVER_DRIVERDIAGNOSTIC_H
+#define LLVM_CLANG_DRIVER_DRIVERDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index 5b19efedde..685088d24a 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -7,12 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_DRIVER_JOB_H_
-#define CLANG_DRIVER_JOB_H_
+#ifndef LLVM_CLANG_DRIVER_JOB_H
+#define LLVM_CLANG_DRIVER_JOB_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Option/Option.h"
+#include "llvm/ADT/iterator.h"
#include <memory>
namespace llvm {
@@ -28,6 +29,14 @@ class Tool;
// Re-export this as clang::driver::ArgStringList.
using llvm::opt::ArgStringList;
+struct CrashReportInfo {
+ StringRef Filename;
+ StringRef VFSPath;
+
+ CrashReportInfo(StringRef Filename, StringRef VFSPath)
+ : Filename(Filename), VFSPath(VFSPath) {}
+};
+
class Job {
public:
enum JobClass {
@@ -51,9 +60,9 @@ public:
/// \param OS - The stream to print on.
/// \param Terminator - A string to print at the end of the line.
/// \param Quote - Should separate arguments be quoted.
- /// \param CrashReport - Whether to print for inclusion in a crash report.
- virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
- bool Quote, bool CrashReport = false) const = 0;
+ /// \param CrashInfo - Details for inclusion in a crash report.
+ virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
+ CrashReportInfo *CrashInfo = nullptr) const = 0;
};
/// Command - An executable path/name and argument vector to
@@ -72,12 +81,36 @@ class Command : public Job {
/// argument, which will be the executable).
llvm::opt::ArgStringList Arguments;
+ /// Response file name, if this command is set to use one, or nullptr
+ /// otherwise
+ const char *ResponseFile;
+
+ /// The input file list in case we need to emit a file list instead of a
+ /// proper response file
+ llvm::opt::ArgStringList InputFileList;
+
+ /// String storage if we need to create a new argument to specify a response
+ /// file
+ std::string ResponseFileFlag;
+
+ /// When a response file is needed, we try to put most arguments in an
+ /// exclusive file, while others remains as regular command line arguments.
+ /// This functions fills a vector with the regular command line arguments,
+ /// argv, excluding the ones passed in a response file.
+ void buildArgvForResponseFile(llvm::SmallVectorImpl<const char *> &Out) const;
+
+ /// Encodes an array of C strings into a single string separated by whitespace.
+ /// This function will also put in quotes arguments that have whitespaces and
+ /// will escape the regular backslashes (used in Windows paths) and quotes.
+ /// The results are the contents of a response file, written into a raw_ostream.
+ void writeResponseFile(raw_ostream &OS) const;
+
public:
Command(const Action &_Source, const Tool &_Creator, const char *_Executable,
const llvm::opt::ArgStringList &_Arguments);
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
- bool CrashReport = false) const override;
+ CrashReportInfo *CrashInfo = nullptr) const override;
virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
bool *ExecutionFailed) const;
@@ -88,6 +121,15 @@ public:
/// getCreator - Return the Tool which caused the creation of this job.
const Tool &getCreator() const { return Creator; }
+ /// Set to pass arguments via a response file when launching the command
+ void setResponseFile(const char *FileName);
+
+ /// Set an input file list, necessary if we need to use a response file but
+ /// the tool being called only supports input files lists.
+ void setInputFileList(llvm::opt::ArgStringList List) {
+ InputFileList = std::move(List);
+ }
+
const char *getExecutable() const { return Executable; }
const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
@@ -104,10 +146,10 @@ class FallbackCommand : public Command {
public:
FallbackCommand(const Action &Source_, const Tool &Creator_,
const char *Executable_, const ArgStringList &Arguments_,
- Command *Fallback_);
+ std::unique_ptr<Command> Fallback_);
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
- bool CrashReport = false) const override;
+ CrashReportInfo *CrashInfo = nullptr) const override;
int Execute(const StringRef **Redirects, std::string *ErrMsg,
bool *ExecutionFailed) const override;
@@ -123,23 +165,23 @@ private:
/// JobList - A sequence of jobs to perform.
class JobList : public Job {
public:
- typedef SmallVector<Job*, 4> list_type;
+ typedef SmallVector<std::unique_ptr<Job>, 4> list_type;
typedef list_type::size_type size_type;
- typedef list_type::iterator iterator;
- typedef list_type::const_iterator const_iterator;
+ typedef llvm::pointee_iterator<list_type::iterator> iterator;
+ typedef llvm::pointee_iterator<list_type::const_iterator> const_iterator;
private:
list_type Jobs;
public:
JobList();
- virtual ~JobList();
+ virtual ~JobList() {}
void Print(llvm::raw_ostream &OS, const char *Terminator,
- bool Quote, bool CrashReport = false) const override;
+ bool Quote, CrashReportInfo *CrashInfo = nullptr) const override;
/// Add a job to the list (taking ownership).
- void addJob(Job *J) { Jobs.push_back(J); }
+ void addJob(std::unique_ptr<Job> J) { Jobs.push_back(std::move(J)); }
/// Clear the job list.
void clear();
diff --git a/include/clang/Driver/Multilib.h b/include/clang/Driver/Multilib.h
index 6c3738a9cc..501ffe5177 100644
--- a/include/clang/Driver/Multilib.h
+++ b/include/clang/Driver/Multilib.h
@@ -7,12 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_LIB_DRIVER_MULTILIB_H_
-#define CLANG_LIB_DRIVER_MULTILIB_H_
+#ifndef LLVM_CLANG_DRIVER_MULTILIB_H
+#define LLVM_CLANG_DRIVER_MULTILIB_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Option/Option.h"
+
+#include <functional>
#include <string>
#include <vector>
@@ -97,6 +99,10 @@ public:
typedef multilib_list::iterator iterator;
typedef multilib_list::const_iterator const_iterator;
+ typedef std::function<std::vector<std::string>(
+ StringRef InstallDir, StringRef Triple, const Multilib &M)>
+ IncludeDirsFunc;
+
struct FilterCallback {
virtual ~FilterCallback() {};
/// \return true iff the filter should remove the Multilib from the set
@@ -105,6 +111,7 @@ public:
private:
multilib_list Multilibs;
+ IncludeDirsFunc IncludeCallback;
public:
MultilibSet() {}
@@ -150,6 +157,12 @@ public:
void print(raw_ostream &OS) const;
+ MultilibSet &setIncludeDirsCallback(IncludeDirsFunc F) {
+ IncludeCallback = F;
+ return *this;
+ }
+ IncludeDirsFunc includeDirsCallback() const { return IncludeCallback; }
+
private:
/// Apply the filter to Multilibs and return the subset that remains
static multilib_list filterCopy(const FilterCallback &F,
diff --git a/include/clang/Driver/Options.h b/include/clang/Driver/Options.h
index cee705deac..2716fa9ae8 100644
--- a/include/clang/Driver/Options.h
+++ b/include/clang/Driver/Options.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_DRIVER_OPTIONS_H
-#define CLANG_DRIVER_OPTIONS_H
+#ifndef LLVM_CLANG_DRIVER_OPTIONS_H
+#define LLVM_CLANG_DRIVER_OPTIONS_H
namespace llvm {
namespace opt {
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index ab42aafedf..8b4aba4ebd 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -64,7 +64,9 @@ def M_Group : OptionGroup<"<M group>">, Group<CompileOnly_Group>;
def T_Group : OptionGroup<"<T group>">;
def O_Group : OptionGroup<"<O group>">, Group<CompileOnly_Group>;
def R_Group : OptionGroup<"<R group>">, Group<CompileOnly_Group>;
+def R_value_Group : OptionGroup<"<R (with value) group>">, Group<R_Group>;
def W_Group : OptionGroup<"<W group>">, Group<CompileOnly_Group>;
+def W_value_Group : OptionGroup<"<W (with value) group>">, Group<W_Group>;
def d_Group : OptionGroup<"<d group>">;
def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>;
def f_clang_Group : OptionGroup<"<f (clang-only) group>">, Group<CompileOnly_Group>;
@@ -73,11 +75,12 @@ def g_flags_Group : OptionGroup<"<g flags group>">;
def i_Group : OptionGroup<"<i group>">, Group<CompileOnly_Group>;
def clang_i_Group : OptionGroup<"<clang i group>">, Group<i_Group>;
def m_Group : OptionGroup<"<m group>">, Group<CompileOnly_Group>;
-def m_x86_Features_Group : OptionGroup<"<m x86 features group>">, Group<m_Group>;
+def m_x86_Features_Group : OptionGroup<"<m x86 features group>">, Group<m_Group>, Flags<[CoreOption]>;
def m_hexagon_Features_Group : OptionGroup<"<m hexagon features group>">, Group<m_Group>;
def m_arm_Features_Group : OptionGroup<"<m arm features group>">, Group<m_Group>;
def m_aarch64_Features_Group : OptionGroup<"<m aarch64 features group>">, Group<m_Group>;
def m_ppc_Features_Group : OptionGroup<"<m ppc features group>">, Group<m_Group>;
+def m_libc_Group : OptionGroup<"<m libc group>">, Group<m_Group>;
def u_Group : OptionGroup<"<u group>">;
def pedantic_Group : OptionGroup<"<pedantic group>">,
@@ -91,6 +94,10 @@ def clang_ignored_f_Group : OptionGroup<"<clang ignored f group>">,
def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">,
Group<m_Group>;
+// Group that ignores all gcc optimizations that won't be implemented
+def clang_ignored_gcc_optimization_f_Group : OptionGroup<
+ "<clang_ignored_gcc_optimization_f_Group>">, Group<f_Group>;
+
/////////
// Options
@@ -174,6 +181,8 @@ def objcmt_migrate_readonly_property : Flag<["-"], "objcmt-migrate-readonly-prop
HelpText<"Enable migration to modern ObjC readonly property">;
def objcmt_migrate_readwrite_property : Flag<["-"], "objcmt-migrate-readwrite-property">, Flags<[CC1Option]>,
HelpText<"Enable migration to modern ObjC readwrite property">;
+def objcmt_migrate_property_dot_syntax : Flag<["-"], "objcmt-migrate-property-dot-syntax">, Flags<[CC1Option]>,
+ HelpText<"Enable migration of setter/getter messages to property-dot syntax">;
def objcmt_migrate_annotation : Flag<["-"], "objcmt-migrate-annotation">, Flags<[CC1Option]>,
HelpText<"Enable migration to property and method annotations">;
def objcmt_migrate_instancetype : Flag<["-"], "objcmt-migrate-instancetype">, Flags<[CC1Option]>,
@@ -257,17 +266,19 @@ def Qn : Flag<["-"], "Qn">;
def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Flags<[DriverOption, CoreOption]>,
HelpText<"Don't emit warning for unused driver arguments">;
def Q : Flag<["-"], "Q">;
-def Rpass_EQ : Joined<["-"], "Rpass=">, Group<R_Group>, Flags<[CC1Option]>,
+def Rpass_EQ : Joined<["-"], "Rpass=">, Group<R_value_Group>, Flags<[CC1Option]>,
HelpText<"Report transformations performed by optimization passes whose "
"name matches the given POSIX regular expression">;
-def Rpass_missed_EQ : Joined<["-"], "Rpass-missed=">, Group<R_Group>,
+def Rpass_missed_EQ : Joined<["-"], "Rpass-missed=">, Group<R_value_Group>,
Flags<[CC1Option]>,
HelpText<"Report missed transformations by optimization passes whose "
"name matches the given POSIX regular expression">;
-def Rpass_analysis_EQ : Joined<["-"], "Rpass-analysis=">, Group<R_Group>,
+def Rpass_analysis_EQ : Joined<["-"], "Rpass-analysis=">, Group<R_value_Group>,
Flags<[CC1Option]>,
HelpText<"Report transformation analysis from optimization passes whose "
"name matches the given POSIX regular expression">;
+def R_Joined : Joined<["-"], "R">, Group<R_Group>, Flags<[CC1Option, CoreOption]>,
+ MetaVarName<"<remark>">, HelpText<"Enable the specified remark">;
def S : Flag<["-"], "S">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
HelpText<"Only run preprocess and compilation steps">;
def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>;
@@ -286,6 +297,7 @@ def Wextra : Flag<["-"], "Wextra">, Group<W_Group>, Flags<[CC1Option]>;
def Wl_COMMA : CommaJoined<["-"], "Wl,">, Flags<[LinkerInput, RenderAsInput]>,
HelpText<"Pass the comma separated arguments in <arg> to the linker">,
MetaVarName<"<arg>">;
+// FIXME: This is broken; these should not be Joined arguments.
def Wno_nonportable_cfstrings : Joined<["-"], "Wno-nonportable-cfstrings">, Group<W_Group>,
Flags<[CC1Option]>;
def Wnonportable_cfstrings : Joined<["-"], "Wnonportable-cfstrings">, Group<W_Group>,
@@ -305,6 +317,8 @@ def Xassembler : Separate<["-"], "Xassembler">,
def Xclang : Separate<["-"], "Xclang">,
HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">,
Flags<[DriverOption, CoreOption]>;
+def z : Separate<["-"], "z">, Flags<[LinkerInput, RenderAsInput]>,
+ HelpText<"Pass -z <arg> to the linker">, MetaVarName<"<arg>">;
def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">;
def Xpreprocessor : Separate<["-"], "Xpreprocessor">,
@@ -402,6 +416,9 @@ def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group<f_Group>;
def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">,
Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use instrumentation data for profile-guided optimization">;
+def fcoverage_mapping : Flag<["-"], "fcoverage-mapping">,
+ Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Generate coverage mapping to enable code coverage analysis">;
def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable the 'blocks' language feature">;
@@ -469,11 +486,13 @@ def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>;
def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>, Flags<[CoreOption]>;
def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable support for exception handling">;
-def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_f_Group>;
-def : Flag<["-"], "fno-expensive-optimizations">, Group<clang_ignored_f_Group>;
+def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">,
+ Group<clang_ignored_gcc_optimization_f_Group>;
+def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>;
+def : Flag<["-"], "fno-expensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>;
def fextdirs_EQ : Joined<["-"], "fextdirs=">, Group<f_Group>;
-def : Flag<["-"], "fdefer-pop">, Group<clang_ignored_f_Group>;
-def : Flag<["-"], "fno-defer-pop">, Group<clang_ignored_f_Group>;
+def : Flag<["-"], "fdefer-pop">, Group<clang_ignored_gcc_optimization_f_Group>;
+def : Flag<["-"], "fno-defer-pop">, Group<clang_ignored_gcc_optimization_f_Group>;
def : Flag<["-"], "fextended-identifiers">, Group<clang_ignored_f_Group>;
def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>, Flags<[Unsupported]>;
def fhosted : Flag<["-"], "fhosted">, Group<f_Group>;
@@ -500,6 +519,9 @@ def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">,
def fno_sanitize_blacklist : Flag<["-"], "fno-sanitize-blacklist">,
Group<f_clang_Group>,
HelpText<"Don't use blacklist file for sanitizers">;
+def fsanitize_coverage : Joined<["-"], "fsanitize-coverage=">,
+ Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Enable coverage instrumentation for Sanitizers">;
def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Enable origins tracking in MemorySanitizer">;
@@ -509,6 +531,9 @@ def fsanitize_memory_track_origins : Flag<["-"], "fsanitize-memory-track-origins
def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-origins">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Disable origins tracking in MemorySanitizer">;
+def fsanitize_address_field_padding : Joined<["-"], "fsanitize-address-field-padding=">,
+ Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Level of field padding for AddressSanitizer">;
def fsanitize_recover : Flag<["-"], "fsanitize-recover">,
Group<f_clang_Group>;
def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
@@ -518,6 +543,8 @@ def fsanitize_undefined_trap_on_error : Flag<["-"], "fsanitize-undefined-trap-on
Group<f_clang_Group>, Flags<[CC1Option]>;
def fno_sanitize_undefined_trap_on_error : Flag<["-"], "fno-sanitize-undefined-trap-on-error">,
Group<f_clang_Group>;
+def fsanitize_link_cxx_runtime : Flag<["-"], "fsanitize-link-c++-runtime">,
+ Group<f_clang_Group>;
def funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">,
Group<f_Group>;
def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations">,
@@ -562,15 +589,16 @@ def fgnu_runtime : Flag<["-"], "fgnu-runtime">, Group<f_Group>,
def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">, Flags<[CC1Option]>;
def filelist : Separate<["-"], "filelist">, Flags<[LinkerInput]>;
def : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>;
-def finline_functions : Flag<["-"], "finline-functions">, Group<clang_ignored_f_Group>;
+def finline_functions : Flag<["-"], "finline-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
def finput_charset_EQ : Joined<["-"], "finput-charset=">, Group<f_Group>;
+def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group<f_Group>;
def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Generate calls to instrument function entry and exit">;
-def : Flag<["-"], "fkeep-inline-functions">, Group<clang_ignored_f_Group>;
def flat__namespace : Flag<["-"], "flat_namespace">;
def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>;
def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;
+def flto_EQ : Joined<["-"], "flto=">, Group<clang_ignored_gcc_optimization_f_Group>;
def flto : Flag<["-"], "flto">, Group<f_Group>;
def fno_lto : Flag<["-"], "fno-lto">, Group<f_Group>;
def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">,
@@ -581,8 +609,15 @@ def fms_extensions : Flag<["-"], "fms-extensions">, Group<f_Group>, Flags<[CC1Op
HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">;
def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable full Microsoft Visual C++ compatibility">;
-def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
+def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[DriverOption, CoreOption]>,
HelpText<"Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default))">;
+def fms_compatibility_version
+ : Joined<["-"], "fms-compatibility-version=">,
+ Group<f_Group>,
+ Flags<[ CC1Option, CoreOption ]>,
+ HelpText<"Dot-separated value representing the Microsoft compiler "
+ "version number to report in _MSC_VER (0 = don't define it "
+ "(default))">;
def fdelayed_template_parsing : Flag<["-"], "fdelayed-template-parsing">, Group<f_Group>,
HelpText<"Parse templated function definitions at the end of the "
"translation unit">, Flags<[CC1Option]>;
@@ -605,10 +640,13 @@ def fmodules_search_all : Flag <["-"], "fmodules-search-all">, Group<f_Group>,
def fbuild_session_timestamp : Joined<["-"], "fbuild-session-timestamp=">,
Group<i_Group>, Flags<[CC1Option]>, MetaVarName<"<time since Epoch in seconds>">,
HelpText<"Time when the current build session started">;
+def fbuild_session_file : Joined<["-"], "fbuild-session-file=">,
+ Group<i_Group>, MetaVarName<"<file>">,
+ HelpText<"Use the last modification time of <file> as the build session timestamp">;
def fmodules_validate_once_per_build_session : Flag<["-"], "fmodules-validate-once-per-build-session">,
Group<i_Group>, Flags<[CC1Option]>,
HelpText<"Don't verify input files for the modules if the module has been "
- "successfully validate or loaded during this build session">;
+ "successfully validated or loaded during this build session">;
def fmodules_validate_system_headers : Flag<["-"], "fmodules-validate-system-headers">,
Group<i_Group>, Flags<[CC1Option]>,
HelpText<"Validate the system headers that a module depends on when loading the module">;
@@ -621,9 +659,12 @@ def fmodule_maps : Flag <["-"], "fmodule-maps">, Group<f_Group>,
def fmodule_name : JoinedOrSeparate<["-"], "fmodule-name=">, Group<f_Group>,
Flags<[DriverOption,CC1Option]>, MetaVarName<"<name>">,
HelpText<"Specify the name of the module to build">;
-def fmodule_map_file : JoinedOrSeparate<["-"], "fmodule-map-file=">,
+def fmodule_map_file : Joined<["-"], "fmodule-map-file=">,
Group<f_Group>, Flags<[DriverOption,CC1Option]>, MetaVarName<"<file>">,
HelpText<"Load this module map file">;
+def fmodule_file : Joined<["-"], "fmodule-file=">,
+ Group<f_Group>, Flags<[DriverOption,CC1Option]>,
+ HelpText<"Load this precompiled module file">, MetaVarName<"<file>">;
def fmodules_ignore_macro : Joined<["-"], "fmodules-ignore-macro=">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Ignore the definition of the given macro when building and loading modules">;
def fmodules_decluse : Flag <["-"], "fmodules-decluse">, Group<f_Group>,
@@ -682,7 +723,6 @@ def fno_exceptions : Flag<["-"], "fno-exceptions">, Group<f_Group>;
def fno_gnu_keywords : Flag<["-"], "fno-gnu-keywords">, Group<f_Group>, Flags<[CC1Option]>;
def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>;
def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>, Flags<[CC1Option]>;
-def : Flag<["-"], "fno-keep-inline-functions">, Group<clang_ignored_f_Group>;
def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>,
HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">, Flags<[CC1Option]>;
def fno_merge_all_constants : Flag<["-"], "fno-merge-all-constants">, Group<f_Group>,
@@ -777,11 +817,15 @@ def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Gr
def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;
def force__flat__namespace : Flag<["-"], "force_flat_namespace">;
def force__load : Separate<["-"], "force_load">;
+def force_addr : Joined<["-"], "fforce-addr">, Group<clang_ignored_f_Group>;
def foutput_class_dir_EQ : Joined<["-"], "foutput-class-dir=">, Group<f_Group>;
def fpack_struct : Flag<["-"], "fpack-struct">, Group<f_Group>;
def fno_pack_struct : Flag<["-"], "fno-pack-struct">, Group<f_Group>;
def fpack_struct_EQ : Joined<["-"], "fpack-struct=">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Specify the default maximum struct packing alignment">;
+def fmax_type_align_EQ : Joined<["-"], "fmax-type-align=">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Specify the maximum alignment to enforce on pointers lacking an explicit alignment">;
+def fno_max_type_align : Flag<["-"], "fno-max-type-align">, Group<f_Group>;
def fpascal_strings : Flag<["-"], "fpascal-strings">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Recognize and construct Pascal-style string literals">;
def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">, Group<f_Group>, Flags<[CC1Option]>,
@@ -792,6 +836,7 @@ def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>;
def fpie : Flag<["-"], "fpie">, Group<f_Group>;
def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>;
def fprofile_arcs : Flag<["-"], "fprofile-arcs">, Group<f_Group>;
+def fno_profile_arcs : Flag<["-"], "fno-profile-arcs">, Group<f_Group>;
def fprofile_generate : Flag<["-"], "fprofile-generate">, Group<f_Group>;
def framework : Separate<["-"], "framework">, Flags<[LinkerInput]>;
def frandom_seed_EQ : Joined<["-"], "frandom-seed=">, Group<clang_ignored_f_Group>;
@@ -801,7 +846,6 @@ def frtti : Flag<["-"], "frtti">, Group<f_Group>;
def : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>;
def fshort_enums : Flag<["-"], "fshort-enums">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Allocate to an enum type only as many bytes as it needs for the declared range of possible values">;
-def : Flag<["-"], "freorder-blocks">, Group<clang_ignored_f_Group>;
def fshort_wchar : Flag<["-"], "fshort-wchar">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Force wchar_t to be a short unsigned int">;
def fno_short_wchar : Flag<["-"], "fno-short-wchar">, Group<f_Group>, Flags<[CC1Option]>,
@@ -896,8 +940,7 @@ def funwind_tables : Flag<["-"], "funwind-tables">, Group<f_Group>;
def fuse_cxa_atexit : Flag<["-"], "fuse-cxa-atexit">, Group<f_Group>;
def fuse_init_array : Flag<["-"], "fuse-init-array">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use .init_array instead of .ctors">;
-def fno_var_tracking : Flag<["-"], "fno-var-tracking">,
- Group<clang_ignored_f_Group>;
+def fno_var_tracking : Flag<["-"], "fno-var-tracking">, Group<clang_ignored_f_Group>;
def fverbose_asm : Flag<["-"], "fverbose-asm">, Group<f_Group>;
def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group<f_Group>,
HelpText<"Set the default symbol visibility for all global declarations">;
@@ -958,6 +1001,7 @@ def gno_record_gcc_switches : Flag<["-"], "gno-record-gcc-switches">,
def gstrict_dwarf : Flag<["-"], "gstrict-dwarf">, Group<g_flags_Group>;
def gno_strict_dwarf : Flag<["-"], "gno-strict-dwarf">, Group<g_flags_Group>;
def gcolumn_info : Flag<["-"], "gcolumn-info">, Group<g_flags_Group>;
+def gno_column_info : Flag<["-"], "gno-column-info">, Group<g_flags_Group>;
def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>;
def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>;
def gdwarf_aranges : Flag<["-"], "gdwarf-aranges">, Group<g_flags_Group>;
@@ -1018,7 +1062,12 @@ def mqdsp6_compat : Flag<["-"], "mqdsp6-compat">, Group<m_Group>, Flags<[DriverO
def m3dnowa : Flag<["-"], "m3dnowa">, Group<m_x86_Features_Group>;
def m3dnow : Flag<["-"], "m3dnow">, Group<m_x86_Features_Group>;
def m64 : Flag<["-"], "m64">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
+def mx32 : Flag<["-"], "mx32">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>;
+def malign_functions_EQ : Joined<["-"], "malign-functions=">, Group<clang_ignored_m_Group>;
+def malign_loops_EQ : Joined<["-"], "malign-loops=">, Group<clang_ignored_m_Group>;
+def malign_jumps_EQ : Joined<["-"], "malign-jumps=">, Group<clang_ignored_m_Group>;
+def mfancy_math_387 : Flag<["-"], "mfancy-math-387">, Group<clang_ignored_m_Group>;
def march_EQ : Joined<["-"], "march=">, Group<m_Group>;
def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[DriverOption]>;
def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>;
@@ -1037,7 +1086,7 @@ def mglobal_merge : Flag<["-"], "mglobal-merge">, Group<m_Group>;
def mhard_float : Flag<["-"], "mhard-float">, Group<m_Group>;
def miphoneos_version_min_EQ : Joined<["-"], "miphoneos-version-min=">, Group<m_Group>;
def mios_version_min_EQ : Joined<["-"], "mios-version-min=">, Alias<miphoneos_version_min_EQ>;
-def mios_simulator_version_min_EQ : Joined<["-"], "mios-simulator-version-min=">, Group<m_Group>;
+def mios_simulator_version_min_EQ : Joined<["-"], "mios-simulator-version-min=">, Alias<miphoneos_version_min_EQ>;
def mkernel : Flag<["-"], "mkernel">, Group<m_Group>;
def mlinker_version_EQ : Joined<["-"], "mlinker-version=">,
Flags<[DriverOption]>;
@@ -1050,6 +1099,9 @@ def mstackrealign : Flag<["-"], "mstackrealign">, Group<m_Group>, Flags<[CC1Opti
HelpText<"Force realign the stack at entry to every function">;
def mstack_alignment : Joined<["-"], "mstack-alignment=">, Group<m_Group>, Flags<[CC1Option]>,
HelpText<"Set the stack alignment">;
+def mthread_model : Separate<["-"], "mthread-model">, Group<m_Group>, Flags<[CC1Option]>,
+ HelpText<"The thread model to use, e.g. posix, single (posix by default)">;
+
def mmmx : Flag<["-"], "mmmx">, Group<m_x86_Features_Group>;
def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group<m_x86_Features_Group>;
def mno_3dnow : Flag<["-"], "mno-3dnow">, Group<m_x86_Features_Group>;
@@ -1079,9 +1131,13 @@ def mno_avx512f : Flag<["-"], "mno-avx512f">, Group<m_x86_Features_Group>;
def mno_avx512cd : Flag<["-"], "mno-avx512cd">, Group<m_x86_Features_Group>;
def mno_avx512er : Flag<["-"], "mno-avx512er">, Group<m_x86_Features_Group>;
def mno_avx512pf : Flag<["-"], "mno-avx512pf">, Group<m_x86_Features_Group>;
+def mno_avx512dq : Flag<["-"], "mno-avx512dq">, Group<m_x86_Features_Group>;
+def mno_avx512bw : Flag<["-"], "mno-avx512bw">, Group<m_x86_Features_Group>;
+def mno_avx512vl : Flag<["-"], "mno-avx512vl">, Group<m_x86_Features_Group>;
def mno_pclmul : Flag<["-"], "mno-pclmul">, Group<m_x86_Features_Group>;
def mno_lzcnt : Flag<["-"], "mno-lzcnt">, Group<m_x86_Features_Group>;
def mno_rdrnd : Flag<["-"], "mno-rdrnd">, Group<m_x86_Features_Group>;
+def mno_fsgsbase : Flag<["-"], "mno-fsgsbase">, Group<m_x86_Features_Group>;
def mno_bmi : Flag<["-"], "mno-bmi">, Group<m_x86_Features_Group>;
def mno_bmi2 : Flag<["-"], "mno-bmi2">, Group<m_x86_Features_Group>;
def mno_popcnt : Flag<["-"], "mno-popcnt">, Group<m_x86_Features_Group>;
@@ -1093,6 +1149,7 @@ def mno_f16c : Flag<["-"], "mno-f16c">, Group<m_x86_Features_Group>;
def mno_rtm : Flag<["-"], "mno-rtm">, Group<m_x86_Features_Group>;
def mno_prfchw : Flag<["-"], "mno-prfchw">, Group<m_x86_Features_Group>;
def mno_rdseed : Flag<["-"], "mno-rdseed">, Group<m_x86_Features_Group>;
+def mno_adx : Flag<["-"], "mno-adx">, Group<m_x86_Features_Group>;
def mno_sha : Flag<["-"], "mno-sha">, Group<m_x86_Features_Group>;
def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>,
@@ -1100,7 +1157,7 @@ def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_G
def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group<m_arm_Features_Group>,
HelpText<"Force all memory accesses to be aligned (AArch32/AArch64 only)">;
def mstrict_align : Flag<["-"], "mstrict-align">, Alias<mno_unaligned_access>, Flags<[CC1Option,HelpHidden]>,
- HelpText<"Force all memory accesses to be aligned (AArch64 only, same as mno-unaligned-access)">;
+ HelpText<"Force all memory accesses to be aligned (same as mno-unaligned-access)">;
def mno_thumb : Flag<["-"], "mno-thumb">, Group<m_arm_Features_Group>;
def mrestrict_it: Flag<["-"], "mrestrict-it">, Group<m_arm_Features_Group>,
HelpText<"Disallow generation of deprecated IT blocks for ARMv8. It is on by default for ARMv8 Thumb mode.">;
@@ -1130,6 +1187,10 @@ def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">,
def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>;
def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>;
+def mpower8_vector : Flag<["-"], "mpower8-vector">,
+ Group<m_ppc_Features_Group>;
+def mno_power8_vector : Flag<["-"], "mno-power8-vector">,
+ Group<m_ppc_Features_Group>;
def mfprnd : Flag<["-"], "mfprnd">, Group<m_ppc_Features_Group>;
def mno_fprnd : Flag<["-"], "mno-fprnd">, Group<m_ppc_Features_Group>;
def mmfcrf : Flag<["-"], "mmfcrf">, Group<m_ppc_Features_Group>;
@@ -1180,9 +1241,13 @@ def mavx512f : Flag<["-"], "mavx512f">, Group<m_x86_Features_Group>;
def mavx512cd : Flag<["-"], "mavx512cd">, Group<m_x86_Features_Group>;
def mavx512er : Flag<["-"], "mavx512er">, Group<m_x86_Features_Group>;
def mavx512pf : Flag<["-"], "mavx512pf">, Group<m_x86_Features_Group>;
+def mavx512dq : Flag<["-"], "mavx512dq">, Group<m_x86_Features_Group>;
+def mavx512bw : Flag<["-"], "mavx512bw">, Group<m_x86_Features_Group>;
+def mavx512vl : Flag<["-"], "mavx512vl">, Group<m_x86_Features_Group>;
def mpclmul : Flag<["-"], "mpclmul">, Group<m_x86_Features_Group>;
def mlzcnt : Flag<["-"], "mlzcnt">, Group<m_x86_Features_Group>;
def mrdrnd : Flag<["-"], "mrdrnd">, Group<m_x86_Features_Group>;
+def mfsgsbase : Flag<["-"], "mfsgsbase">, Group<m_x86_Features_Group>;
def mbmi : Flag<["-"], "mbmi">, Group<m_x86_Features_Group>;
def mbmi2 : Flag<["-"], "mbmi2">, Group<m_x86_Features_Group>;
def mpopcnt : Flag<["-"], "mpopcnt">, Group<m_x86_Features_Group>;
@@ -1194,6 +1259,7 @@ def mf16c : Flag<["-"], "mf16c">, Group<m_x86_Features_Group>;
def mrtm : Flag<["-"], "mrtm">, Group<m_x86_Features_Group>;
def mprfchw : Flag<["-"], "mprfchw">, Group<m_x86_Features_Group>;
def mrdseed : Flag<["-"], "mrdseed">, Group<m_x86_Features_Group>;
+def madx : Flag<["-"], "madx">, Group<m_x86_Features_Group>;
def msha : Flag<["-"], "msha">, Group<m_x86_Features_Group>;
def mcx16 : Flag<["-"], "mcx16">, Group<m_x86_Features_Group>;
def mips16 : Flag<["-"], "mips16">, Group<m_Group>;
@@ -1222,6 +1288,10 @@ def mfp64 : Flag<["-"], "mfp64">, Group<m_Group>,
def mfp32 : Flag<["-"], "mfp32">, Group<m_Group>,
HelpText<"Use 32-bit floating point registers (MIPS only)">;
def mnan_EQ : Joined<["-"], "mnan=">, Group<m_Group>;
+def mabicalls : Flag<["-"], "mabicalls">, Group<m_Group>,
+ HelpText<"Enable SVR4-style position-independent code (Mips only)">;
+def mno_abicalls : Flag<["-"], "mno-abicalls">, Group<m_Group>,
+ HelpText<"Disable SVR4-style position-independent code (Mips only)">;
def mips1 : Flag<["-"], "mips1">,
Alias<march_EQ>, AliasArgs<["mips1"]>,
HelpText<"Equivalent to -march=mips1">, Flags<[HelpHidden]>;
@@ -1255,12 +1325,17 @@ def mips64r2 : Flag<["-"], "mips64r2">,
def mips64r6 : Flag<["-"], "mips64r6">,
Alias<march_EQ>, AliasArgs<["mips64r6"]>,
HelpText<"Equivalent to -march=mips64r6">, Flags<[HelpHidden]>;
+def mfpxx : Flag<["-"], "mfpxx">, Group<m_Group>,
+ HelpText<"Avoid FPU mode dependent operations when used with the O32 ABI">,
+ Flags<[HelpHidden]>;
def modd_spreg : Flag<["-"], "modd-spreg">, Group<m_Group>,
HelpText<"Enable odd single-precision floating point registers">,
Flags<[HelpHidden]>;
def mno_odd_spreg : Flag<["-"], "mno-odd-spreg">, Group<m_Group>,
HelpText<"Disable odd single-precision floating point registers">,
Flags<[HelpHidden]>;
+def mglibc : Flag<["-"], "mglibc">, Group<m_libc_Group>, Flags<[HelpHidden]>;
+def muclibc : Flag<["-"], "muclibc">, Group<m_libc_Group>, Flags<[HelpHidden]>;
def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>;
def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>;
@@ -1380,7 +1455,7 @@ def no_system_header_prefix : Joined<["--"], "no-system-header-prefix=">,
"system header.">;
def : Separate<["--"], "no-system-header-prefix">, Alias<no_system_header_prefix>;
def s : Flag<["-"], "s">;
-def target : Joined<["--"], "target=">, Flags<[DriverOption]>,
+def target : Joined<["--"], "target=">, Flags<[DriverOption, CoreOption]>,
HelpText<"Generate code for the given target">;
def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[DriverOption]>,
HelpText<"Use the gcc toolchain at the given directory">;
@@ -1441,7 +1516,7 @@ def _all_warnings : Flag<["--"], "all-warnings">, Alias<Wall>;
def _analyze_auto : Flag<["--"], "analyze-auto">, Flags<[DriverOption]>;
def _analyzer_no_default_checks : Flag<["--"], "analyzer-no-default-checks">, Flags<[DriverOption]>;
def _analyzer_output : JoinedOrSeparate<["--"], "analyzer-output">, Flags<[DriverOption]>;
-def _analyze : Flag<["--"], "analyze">, Flags<[DriverOption]>,
+def _analyze : Flag<["--"], "analyze">, Flags<[DriverOption, CoreOption]>,
HelpText<"Run the static analyzer">;
def _assemble : Flag<["--"], "assemble">, Alias<S>;
def _assert_EQ : Joined<["--"], "assert=">, Alias<A>;
@@ -1577,53 +1652,107 @@ multiclass BooleanFFlag<string name> {
def _fno : Flag<["-"], "fno-"#name>;
}
-def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<clang_ignored_f_Group>;
+defm : BooleanFFlag<"keep-inline-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm profile_use : BooleanFFlag<"profile-use">, Group<clang_ignored_f_Group>;
-def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<clang_ignored_f_Group>;
+def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<clang_ignored_gcc_optimization_f_Group>;
+
+defm profile_use : BooleanFFlag<"profile-use">, Group<clang_ignored_gcc_optimization_f_Group>;
+def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<clang_ignored_gcc_optimization_f_Group>;
def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>;
-defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_f_Group>;
-def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<clang_ignored_f_Group>;
+defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
+def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm align_labels : BooleanFFlag<"align-labels">, Group<clang_ignored_gcc_optimization_f_Group>;
+def falign_labels_EQ : Joined<["-"], "falign-labels=">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm align_loops : BooleanFFlag<"align-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
+def falign_loops_EQ : Joined<["-"], "falign-loops=">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm align_jumps : BooleanFFlag<"align-jumps">, Group<clang_ignored_gcc_optimization_f_Group>;
+def falign_jumps_EQ : Joined<["-"], "falign-jumps=">, Group<clang_ignored_gcc_optimization_f_Group>;
// FIXME: This option should be supported and wired up to our diognostics, but
// ignore it for now to avoid breaking builds that use it.
def fdiagnostics_show_location_EQ : Joined<["-"], "fdiagnostics-show-location=">, Group<clang_ignored_f_Group>;
+defm fcheck_new : BooleanFFlag<"check-new">, Group<clang_ignored_f_Group>;
+defm caller_saves : BooleanFFlag<"caller-saves">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm reorder_blocks : BooleanFFlag<"reorder-blocks">, Group<clang_ignored_gcc_optimization_f_Group>;
defm eliminate_unused_debug_types : BooleanFFlag<"eliminate-unused-debug-types">, Group<clang_ignored_f_Group>;
-defm float_store : BooleanFFlag<"float-store">, Group<clang_ignored_f_Group>;
+defm branch_count_reg : BooleanFFlag<"branch-count-reg">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm default_inline : BooleanFFlag<"default-inline">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm delete_null_pointer_checks : BooleanFFlag<"delete-null-pointer-checks">,
+ Group<clang_ignored_gcc_optimization_f_Group>;
+defm fat_lto_objects : BooleanFFlag<"fat-lto-objects">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm float_store : BooleanFFlag<"float-store">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm friend_injection : BooleanFFlag<"friend-injection">, Group<clang_ignored_f_Group>;
defm function_attribute_list : BooleanFFlag<"function-attribute-list">, Group<clang_ignored_f_Group>;
-defm gcse : BooleanFFlag<"gcse">, Group<clang_ignored_f_Group>;
+defm gcse : BooleanFFlag<"gcse">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm gcse_after_reload: BooleanFFlag<"gcse-after-reload">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm gcse_las: BooleanFFlag<"gcse-las">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm gcse_sm: BooleanFFlag<"gcse-sm">, Group<clang_ignored_gcc_optimization_f_Group>;
defm gnu : BooleanFFlag<"gnu">, Group<clang_ignored_f_Group>;
defm ident : BooleanFFlag<"ident">, Group<clang_ignored_f_Group>;
defm implicit_templates : BooleanFFlag<"implicit-templates">, Group<clang_ignored_f_Group>;
-defm inline_limit : BooleanFFlag<"inline-limit">, Group<clang_ignored_f_Group>;
-defm ivopts : BooleanFFlag<"ivopts">, Group<clang_ignored_f_Group>;
+defm implement_inlines : BooleanFFlag<"implement-inlines">, Group<clang_ignored_f_Group>;
+defm merge_constants : BooleanFFlag<"merge-constants">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm modulo_sched : BooleanFFlag<"modulo-sched">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm modulo_sched_allow_regmoves : BooleanFFlag<"modulo-sched-allow-regmoves">,
+ Group<clang_ignored_gcc_optimization_f_Group>;
+defm inline_functions_called_once : BooleanFFlag<"inline-functions-called-once">,
+ Group<clang_ignored_gcc_optimization_f_Group>;
+def finline_limit_EQ : Joined<["-"], "finline-limit=">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm finline_limit : BooleanFFlag<"inline-limit">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm inline_small_functions : BooleanFFlag<"inline-small-functions">,
+ Group<clang_ignored_gcc_optimization_f_Group>;
+defm ipa_cp : BooleanFFlag<"ipa-cp">,
+ Group<clang_ignored_gcc_optimization_f_Group>;
+defm ivopts : BooleanFFlag<"ivopts">, Group<clang_ignored_gcc_optimization_f_Group>;
defm non_call_exceptions : BooleanFFlag<"non-call-exceptions">, Group<clang_ignored_f_Group>;
+defm peel_loops : BooleanFFlag<"peel-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
defm permissive : BooleanFFlag<"permissive">, Group<clang_ignored_f_Group>;
-defm prefetch_loop_arrays : BooleanFFlag<"prefetch-loop-arrays">, Group<clang_ignored_f_Group>;
+defm prefetch_loop_arrays : BooleanFFlag<"prefetch-loop-arrays">, Group<clang_ignored_gcc_optimization_f_Group>;
defm printf : BooleanFFlag<"printf">, Group<clang_ignored_f_Group>;
defm profile : BooleanFFlag<"profile">, Group<clang_ignored_f_Group>;
-defm profile_correction : BooleanFFlag<"profile-correction">, Group<clang_ignored_f_Group>;
+defm profile_correction : BooleanFFlag<"profile-correction">, Group<clang_ignored_gcc_optimization_f_Group>;
defm profile_generate_sampling : BooleanFFlag<"profile-generate-sampling">, Group<clang_ignored_f_Group>;
defm profile_reusedist : BooleanFFlag<"profile-reusedist">, Group<clang_ignored_f_Group>;
-defm profile_values : BooleanFFlag<"profile-values">, Group<clang_ignored_f_Group>;
+defm profile_values : BooleanFFlag<"profile-values">, Group<clang_ignored_gcc_optimization_f_Group>;
defm regs_graph : BooleanFFlag<"regs-graph">, Group<clang_ignored_f_Group>;
+defm rename_registers : BooleanFFlag<"rename-registers">, Group<clang_ignored_gcc_optimization_f_Group>;
defm ripa : BooleanFFlag<"ripa">, Group<clang_ignored_f_Group>;
-defm rounding_math : BooleanFFlag<"rounding-math">, Group<clang_ignored_f_Group>;
-defm schedule_insns : BooleanFFlag<"schedule-insns">, Group<clang_ignored_f_Group>;
+defm rounding_math : BooleanFFlag<"rounding-math">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm schedule_insns : BooleanFFlag<"schedule-insns">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm schedule_insns2 : BooleanFFlag<"schedule-insns2">, Group<clang_ignored_gcc_optimization_f_Group>;
defm see : BooleanFFlag<"see">, Group<clang_ignored_f_Group>;
-defm signaling_nans : BooleanFFlag<"signaling-nans">, Group<clang_ignored_f_Group>;
+defm signaling_nans : BooleanFFlag<"signaling-nans">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm single_precision_constant : BooleanFFlag<"single-precision-constant">,
+ Group<clang_ignored_gcc_optimization_f_Group>;
defm spec_constr_count : BooleanFFlag<"spec-constr-count">, Group<clang_ignored_f_Group>;
+defm stack_check : BooleanFFlag<"stack-check">, Group<clang_ignored_f_Group>;
defm strength_reduce :
- BooleanFFlag<"strength-reduce">, Group<clang_ignored_f_Group>;
+ BooleanFFlag<"strength-reduce">, Group<clang_ignored_gcc_optimization_f_Group>;
defm tls_model : BooleanFFlag<"tls-model">, Group<clang_ignored_f_Group>;
-defm tracer : BooleanFFlag<"tracer">, Group<clang_ignored_f_Group>;
+defm tracer : BooleanFFlag<"tracer">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm tree_dce : BooleanFFlag<"tree-dce">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm tree_loop_im : BooleanFFlag<"tree_loop_im">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm tree_loop_ivcanon : BooleanFFlag<"tree_loop_ivcanon">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm tree_loop_linear : BooleanFFlag<"tree_loop_linear">, Group<clang_ignored_gcc_optimization_f_Group>;
defm tree_salias : BooleanFFlag<"tree-salias">, Group<clang_ignored_f_Group>;
+defm tree_ter : BooleanFFlag<"tree-ter">, Group<clang_ignored_gcc_optimization_f_Group>;
defm tree_vectorizer_verbose : BooleanFFlag<"tree-vectorizer-verbose">, Group<clang_ignored_f_Group>;
-defm unroll_all_loops : BooleanFFlag<"unroll-all-loops">, Group<clang_ignored_f_Group>;
-defm unswitch_loops : BooleanFFlag<"unswitch-loops">, Group<clang_ignored_f_Group>;
-
+defm tree_vrp : BooleanFFlag<"tree-vrp">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm unroll_all_loops : BooleanFFlag<"unroll-all-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm unsafe_loop_optimizations : BooleanFFlag<"unsafe-loop-optimizations">,
+ Group<clang_ignored_gcc_optimization_f_Group>;
+defm unswitch_loops : BooleanFFlag<"unswitch-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm use_linker_plugin : BooleanFFlag<"use-linker-plugin">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm vect_cost_model : BooleanFFlag<"vect-cost-model">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm variable_expansion_in_unroller : BooleanFFlag<"variable-expansion-in-unroller">,
+ Group<clang_ignored_gcc_optimization_f_Group>;
+defm web : BooleanFFlag<"web">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm whole_program : BooleanFFlag<"whole-program">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm devirtualize : BooleanFFlag<"devirtualize">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm devirtualize_speculatively : BooleanFFlag<"devirtualize-speculatively">,
+ Group<clang_ignored_gcc_optimization_f_Group>;
// gfortran options that we recognize in the driver and pass along when
// invoking GCC to compile Fortran code.
diff --git a/include/clang/Driver/Phases.h b/include/clang/Driver/Phases.h
index 4e0f40c17d..e2160e6531 100644
--- a/include/clang/Driver/Phases.h
+++ b/include/clang/Driver/Phases.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_DRIVER_PHASES_H_
-#define CLANG_DRIVER_PHASES_H_
+#ifndef LLVM_CLANG_DRIVER_PHASES_H
+#define LLVM_CLANG_DRIVER_PHASES_H
namespace clang {
namespace driver {
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
index c79c4714f4..32b2e8935e 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_LIB_DRIVER_SANITIZERARGS_H_
-#define CLANG_LIB_DRIVER_SANITIZERARGS_H_
+#ifndef LLVM_CLANG_DRIVER_SANITIZERARGS_H
+#define LLVM_CLANG_DRIVER_SANITIZERARGS_H
+#include "clang/Basic/Sanitizers.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include <string>
@@ -20,131 +21,46 @@ class Driver;
class ToolChain;
class SanitizerArgs {
- /// Assign ordinals to sanitizer flags. We'll use the ordinal values as
- /// bit positions within \c Kind.
- enum SanitizeOrdinal {
-#define SANITIZER(NAME, ID) SO_##ID,
-#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
-#include "clang/Basic/Sanitizers.def"
- SO_Count
- };
-
- /// Bugs to catch at runtime.
- enum SanitizeKind {
-#define SANITIZER(NAME, ID) ID = 1 << SO_##ID,
-#define SANITIZER_GROUP(NAME, ID, ALIAS) \
- ID = ALIAS, ID##Group = 1 << SO_##ID##Group,
-#include "clang/Basic/Sanitizers.def"
- NeedsAsanRt = Address,
- NeedsTsanRt = Thread,
- NeedsMsanRt = Memory,
- NeedsDfsanRt = DataFlow,
- NeedsLeakDetection = Leak,
- NeedsUbsanRt = Undefined | Integer,
- NotAllowedWithTrap = Vptr,
- HasZeroBaseShadow = Thread | Memory | DataFlow,
- NeedsUnwindTables = Address | Thread | Memory | DataFlow
- };
- unsigned Kind;
+ SanitizerSet Sanitizers;
+ bool SanitizeRecover;
std::string BlacklistFile;
+ int SanitizeCoverage;
int MsanTrackOrigins;
+ int AsanFieldPadding;
bool AsanZeroBaseShadow;
bool UbsanTrapOnError;
bool AsanSharedRuntime;
+ bool LinkCXXRuntimes;
public:
- SanitizerArgs();
/// Parses the sanitizer arguments from an argument list.
SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
- bool needsAsanRt() const { return Kind & NeedsAsanRt; }
+ bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); }
bool needsSharedAsanRt() const { return AsanSharedRuntime; }
- bool needsTsanRt() const { return Kind & NeedsTsanRt; }
- bool needsMsanRt() const { return Kind & NeedsMsanRt; }
- bool needsLeakDetection() const { return Kind & NeedsLeakDetection; }
+ bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); }
+ bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); }
bool needsLsanRt() const {
- return needsLeakDetection() && !needsAsanRt();
- }
- bool needsUbsanRt() const {
- return !UbsanTrapOnError && (Kind & NeedsUbsanRt);
+ return Sanitizers.has(SanitizerKind::Leak) &&
+ !Sanitizers.has(SanitizerKind::Address);
}
- bool needsDfsanRt() const { return Kind & NeedsDfsanRt; }
+ bool needsUbsanRt() const;
+ bool needsDfsanRt() const { return Sanitizers.has(SanitizerKind::DataFlow); }
- bool sanitizesVptr() const { return Kind & Vptr; }
- bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; }
- bool hasZeroBaseShadow() const {
- return (Kind & HasZeroBaseShadow) || AsanZeroBaseShadow;
- }
- bool needsUnwindTables() const { return Kind & NeedsUnwindTables; }
+ bool sanitizesVptr() const { return Sanitizers.has(SanitizerKind::Vptr); }
+ bool hasZeroBaseShadow() const;
+ bool needsUnwindTables() const;
+ bool linkCXXRuntimes() const { return LinkCXXRuntimes; }
void addArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
private:
void clear();
-
- /// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
- /// Returns OR of members of the \c SanitizeKind enumeration, or \c 0
- /// if \p Value is not known.
- static unsigned parse(const char *Value);
-
- /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
- /// invalid components.
- static unsigned parse(const Driver &D, const llvm::opt::Arg *A,
- bool DiagnoseErrors);
-
- /// Parse a single flag of the form -f[no]sanitize=, or
- /// -f*-sanitizer. Sets the masks defining required change of Kind value.
- /// Returns true if the flag was parsed successfully.
- static bool parse(const Driver &D, const llvm::opt::ArgList &Args,
- const llvm::opt::Arg *A, unsigned &Add, unsigned &Remove,
- bool DiagnoseErrors);
-
- /// Produce an argument string from ArgList \p Args, which shows how it
- /// provides a sanitizer kind in \p Mask. For example, the argument list
- /// "-fsanitize=thread,vptr -fsanitize=address" with mask \c NeedsUbsanRt
- /// would produce "-fsanitize=vptr".
- static std::string lastArgumentForKind(const Driver &D,
- const llvm::opt::ArgList &Args,
- unsigned Kind);
-
- /// Produce an argument string from argument \p A, which shows how it provides
- /// a value in \p Mask. For instance, the argument
- /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
- /// "-fsanitize=alignment".
- static std::string describeSanitizeArg(const llvm::opt::ArgList &Args,
- const llvm::opt::Arg *A,
- unsigned Mask);
-
- static bool getDefaultBlacklistForKind(const Driver &D, unsigned Kind,
- std::string &BLPath);
-
- /// Return the smallest superset of sanitizer set \p Kinds such that each
- /// member of each group whose flag is set in \p Kinds has its flag set in the
- /// result.
- static unsigned expandGroups(unsigned Kinds);
-
- /// Return the subset of \p Kinds supported by toolchain \p TC. If
- /// \p DiagnoseErrors is true, produce an error diagnostic for each sanitizer
- /// removed from \p Kinds.
- static unsigned filterUnsupportedKinds(const ToolChain &TC, unsigned Kinds,
- const llvm::opt::ArgList &Args,
- const llvm::opt::Arg *A,
- bool DiagnoseErrors,
- unsigned &DiagnosedKinds);
-
- /// The flags in \p Mask are unsupported by \p TC. If present in \p Kinds,
- /// remove them and produce an error diagnostic referring to \p A if
- /// \p DiagnoseErrors is true.
- static void filterUnsupportedMask(const ToolChain &TC, unsigned &Kinds,
- unsigned Mask,
- const llvm::opt::ArgList &Args,
- const llvm::opt::Arg *A,
- bool DiagnoseErrors,
- unsigned &DiagnosedKinds);
+ bool getDefaultBlacklist(const Driver &D, std::string &BLPath);
};
} // namespace driver
} // namespace clang
-#endif // CLANG_LIB_DRIVER_SANITIZERARGS_H_
+#endif
diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h
index 015dcf513e..aa895d0ba6 100644
--- a/include/clang/Driver/Tool.h
+++ b/include/clang/Driver/Tool.h
@@ -7,10 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_DRIVER_TOOL_H_
-#define CLANG_DRIVER_TOOL_H_
+#ifndef LLVM_CLANG_DRIVER_TOOL_H
+#define LLVM_CLANG_DRIVER_TOOL_H
#include "clang/Basic/LLVM.h"
+#include "llvm/Support/Program.h"
namespace llvm {
namespace opt {
@@ -31,6 +32,24 @@ namespace driver {
/// Tool - Information on a specific compilation tool.
class Tool {
+public:
+ // Documents the level of support for response files in this tool.
+ // Response files are necessary if the command line gets too large,
+ // requiring the arguments to be transfered to a file.
+ enum ResponseFileSupport {
+ // Provides full support for response files, which means we can transfer
+ // all tool input arguments to a file. E.g.: clang, gcc, binutils and MSVC
+ // tools.
+ RF_Full,
+ // Input file names can live in a file, but flags can't. E.g.: ld64 (Mac
+ // OS X linker).
+ RF_FileList,
+ // Does not support response files: all arguments must be passed via
+ // command line.
+ RF_None
+ };
+
+private:
/// The tool name (for debugging).
const char *Name;
@@ -40,9 +59,20 @@ class Tool {
/// The tool chain this tool is a part of.
const ToolChain &TheToolChain;
+ /// The level of support for response files seen in this tool
+ const ResponseFileSupport ResponseSupport;
+
+ /// The encoding to use when writing response files for this tool on Windows
+ const llvm::sys::WindowsEncodingMethod ResponseEncoding;
+
+ /// The flag used to pass a response file via command line to this tool
+ const char *const ResponseFlag;
+
public:
- Tool(const char *Name, const char *ShortName,
- const ToolChain &TC);
+ Tool(const char *Name, const char *ShortName, const ToolChain &TC,
+ ResponseFileSupport ResponseSupport = RF_None,
+ llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8,
+ const char *ResponseFlag = "@");
public:
virtual ~Tool();
@@ -57,6 +87,29 @@ public:
virtual bool hasIntegratedCPP() const = 0;
virtual bool isLinkJob() const { return false; }
virtual bool isDsymutilJob() const { return false; }
+ /// \brief Returns the level of support for response files of this tool,
+ /// whether it accepts arguments to be passed via a file on disk.
+ ResponseFileSupport getResponseFilesSupport() const {
+ return ResponseSupport;
+ }
+ /// \brief Returns which encoding the response file should use. This is only
+ /// relevant on Windows platforms where there are different encodings being
+ /// accepted for different tools. On UNIX, UTF8 is universal.
+ ///
+ /// Windows use cases: - GCC and Binutils on mingw only accept ANSI response
+ /// files encoded with the system current code page.
+ /// - MSVC's CL.exe and LINK.exe accept UTF16 on Windows.
+ /// - Clang accepts both UTF8 and UTF16.
+ ///
+ /// FIXME: When GNU tools learn how to parse UTF16 on Windows, we should
+ /// always use UTF16 for Windows, which is the Windows official encoding for
+ /// international characters.
+ llvm::sys::WindowsEncodingMethod getResponseFileEncoding() const {
+ return ResponseEncoding;
+ }
+ /// \brief Returns which prefix to use when passing the name of a response
+ /// file as a parameter to this tool.
+ const char *getResponseFileFlag() const { return ResponseFlag; }
/// \brief Does this tool have "good" standardized diagnostics, or should the
/// driver add an additional "command failed" diagnostic on failures.
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index c9a6c4b57f..7279951c73 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_DRIVER_TOOLCHAIN_H_
-#define CLANG_DRIVER_TOOLCHAIN_H_
+#ifndef LLVM_CLANG_DRIVER_TOOLCHAIN_H
+#define LLVM_CLANG_DRIVER_TOOLCHAIN_H
#include "clang/Driver/Action.h"
#include "clang/Driver/Multilib.h"
@@ -41,7 +41,7 @@ namespace driver {
/// ToolChain - Access to tools for a single platform.
class ToolChain {
public:
- typedef SmallVector<std::string, 4> path_list;
+ typedef SmallVector<std::string, 16> path_list;
enum CXXStdlibType {
CST_Libcxx,
@@ -116,12 +116,9 @@ public:
StringRef getPlatform() const { return Triple.getVendorName(); }
StringRef getOS() const { return Triple.getOSName(); }
- /// \brief Returns true if the toolchain is targeting a non-native architecture.
- bool isCrossCompiling() const;
-
/// \brief Provide the default architecture name (as expected by -arch) for
/// this toolchain. Note t
- std::string getDefaultUniversalArchName() const;
+ StringRef getDefaultUniversalArchName() const;
std::string getTripleString() const {
return Triple.getTriple();
@@ -171,6 +168,10 @@ public:
// Platform defaults information
+ /// \brief Returns true if the toolchain is targeting a non-native
+ /// architecture.
+ virtual bool isCrossCompiling() const;
+
/// HasNativeLTOLinker - Check whether the linker and related tools have
/// native LLVM support.
virtual bool HasNativeLLVMSupport() const;
@@ -247,6 +248,12 @@ public:
/// UseSjLjExceptions - Does this tool chain use SjLj exceptions.
virtual bool UseSjLjExceptions() const { return false; }
+ /// getThreadModel() - Which thread model does this target use?
+ virtual std::string getThreadModel() const { return "posix"; }
+
+ /// supportsThreadModel() - Does this target support a thread model?
+ virtual bool isThreadModelSupported(const StringRef Model) const;
+
/// ComputeLLVMTriple - Return the LLVM target triple to use, after taking
/// command line arguments into account.
virtual std::string
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
index cca576a054..34442eb637 100644
--- a/include/clang/Driver/Types.h
+++ b/include/clang/Driver/Types.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_DRIVER_TYPES_H_
-#define CLANG_DRIVER_TYPES_H_
+#ifndef LLVM_CLANG_DRIVER_TYPES_H
+#define LLVM_CLANG_DRIVER_TYPES_H
#include "clang/Driver/Phases.h"
#include "llvm/ADT/SmallVector.h"
diff --git a/include/clang/Driver/Util.h b/include/clang/Driver/Util.h
index c671ca47a2..07495a1850 100644
--- a/include/clang/Driver/Util.h
+++ b/include/clang/Driver/Util.h
@@ -7,16 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_DRIVER_UTIL_H_
-#define CLANG_DRIVER_UTIL_H_
+#ifndef LLVM_CLANG_DRIVER_UTIL_H
+#define LLVM_CLANG_DRIVER_UTIL_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
-namespace llvm {
- class Triple;
-}
-
namespace clang {
class DiagnosticsEngine;
@@ -30,9 +26,6 @@ namespace driver {
/// ActionList - Type used for lists of actions.
typedef SmallVector<Action*, 3> ActionList;
-/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
-const char* getARMCPUForMArch(StringRef MArch, const llvm::Triple &Triple);
-
} // end namespace driver
} // end namespace clang
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index 45cccaacd5..a04705c36d 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -15,8 +15,9 @@
#ifndef LLVM_CLANG_FORMAT_FORMAT_H
#define LLVM_CLANG_FORMAT_FORMAT_H
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/Tooling/Refactoring.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/ArrayRef.h"
#include <system_error>
namespace clang {
@@ -47,6 +48,8 @@ struct FormatStyle {
LK_None,
/// Should be used for C, C++, ObjectiveC, ObjectiveC++.
LK_Cpp,
+ /// Should be used for Java.
+ LK_Java,
/// Should be used for JavaScript.
LK_JavaScript,
/// Should be used for Protocol Buffers
@@ -150,10 +153,14 @@ struct FormatStyle {
/// commonly have different usage patterns and a number of special cases.
unsigned SpacesBeforeTrailingComments;
- /// \brief If \c false, a function call's or function definition's parameters
- /// will either all be on the same line or will have one line each.
+ /// \brief If \c false, a function declaration's or function definition's
+ /// parameters will either all be on the same line or will have one line each.
bool BinPackParameters;
+ /// \brief If \c false, a function call's arguments will either be all on the
+ /// same line or will have one line each.
+ bool BinPackArguments;
+
/// \brief If \c true, clang-format detects whether function calls and
/// definitions are formatted with one parameter per line.
///
@@ -195,6 +202,9 @@ struct FormatStyle {
/// single line.
bool AllowShortLoopsOnASingleLine;
+ /// \brief If \c true, short case labels will be contracted to a single line.
+ bool AllowShortCaseLabelsOnASingleLine;
+
/// \brief Different styles for merging short functions containing at most one
/// statement.
enum ShortFunctionStyle {
@@ -218,6 +228,16 @@ struct FormatStyle {
/// <tt>Foo <Protocol></tt> instead of \c Foo<Protocol>.
bool ObjCSpaceBeforeProtocolList;
+ /// \brief If \c true, horizontally aligns arguments after an open bracket.
+ ///
+ /// This applies to round brackets (parentheses), angle brackets and square
+ /// brackets. This will result in formattings like
+ /// \code
+ /// someLongFunction(argument1,
+ /// argument2);
+ /// \endcode
+ bool AlignAfterOpenBracket;
+
/// \brief If \c true, aligns trailing comments.
bool AlignTrailingComments;
@@ -235,6 +255,16 @@ struct FormatStyle {
/// initializer lists.
unsigned ConstructorInitializerIndentWidth;
+ /// \brief The number of characters to use for indentation of ObjC blocks.
+ unsigned ObjCBlockIndentWidth;
+
+ /// \brief If \c true, always break after function definition return types.
+ ///
+ /// More truthfully called 'break before the identifier following the type
+ /// in a function definition'. PenaltyReturnTypeOnItsOwnLine becomes
+ /// irrelevant.
+ bool AlwaysBreakAfterDefinitionReturnType;
+
/// \brief If \c true, always break after the <tt>template<...></tt> of a
/// template declaration.
bool AlwaysBreakTemplateDeclarations;
@@ -256,8 +286,18 @@ struct FormatStyle {
/// \brief The way to use tab characters in the resulting file.
UseTabStyle UseTab;
- /// \brief If \c true, binary operators will be placed after line breaks.
- bool BreakBeforeBinaryOperators;
+ /// \brief The style of breaking before or after binary operators.
+ enum BinaryOperatorStyle {
+ /// Break after operators.
+ BOS_None,
+ /// Break before operators that aren't assignments.
+ BOS_NonAssignment,
+ /// Break before operators.
+ BOS_All,
+ };
+
+ /// \brief The way to wrap binary operators.
+ BinaryOperatorStyle BreakBeforeBinaryOperators;
/// \brief If \c true, ternary operators will be placed after line breaks.
bool BreakBeforeTernaryOperators;
@@ -269,7 +309,7 @@ struct FormatStyle {
/// Like \c Attach, but break before braces on function, namespace and
/// class definitions.
BS_Linux,
- /// Like \c Attach, but break before function definitions.
+ /// Like \c Attach, but break before function definitions, and 'else'.
BS_Stroustrup,
/// Always break before braces.
BS_Allman,
@@ -304,6 +344,9 @@ struct FormatStyle {
/// template argument lists
bool SpacesInAngles;
+ /// \brief If \c true, spaces will be inserted after '[' and before ']'.
+ bool SpacesInSquareBrackets;
+
/// \brief If \c true, spaces may be inserted into '()'.
bool SpaceInEmptyParentheses;
@@ -314,6 +357,9 @@ struct FormatStyle {
/// \brief If \c true, spaces may be inserted into C style casts.
bool SpacesInCStyleCastParentheses;
+ /// \brief If \c true, a space may be inserted after C style casts.
+ bool SpaceAfterCStyleCast;
+
/// \brief Different ways to put a space before opening parentheses.
enum SpaceBeforeParensOptions {
/// Never put a space before opening parentheses.
@@ -358,8 +404,7 @@ struct FormatStyle {
bool operator==(const FormatStyle &R) const {
return AccessModifierOffset == R.AccessModifierOffset &&
- ConstructorInitializerIndentWidth ==
- R.ConstructorInitializerIndentWidth &&
+ AlignAfterOpenBracket == R.AlignAfterOpenBracket &&
AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft &&
AlignTrailingComments == R.AlignTrailingComments &&
AllowAllParametersOfDeclarationOnNextLine ==
@@ -370,11 +415,14 @@ struct FormatStyle {
AllowShortIfStatementsOnASingleLine ==
R.AllowShortIfStatementsOnASingleLine &&
AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine &&
+ AlwaysBreakAfterDefinitionReturnType ==
+ R.AlwaysBreakAfterDefinitionReturnType &&
AlwaysBreakTemplateDeclarations ==
R.AlwaysBreakTemplateDeclarations &&
AlwaysBreakBeforeMultilineStrings ==
R.AlwaysBreakBeforeMultilineStrings &&
BinPackParameters == R.BinPackParameters &&
+ BinPackArguments == R.BinPackArguments &&
BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBeforeBraces == R.BreakBeforeBraces &&
@@ -383,6 +431,8 @@ struct FormatStyle {
ColumnLimit == R.ColumnLimit &&
ConstructorInitializerAllOnOneLineOrOnePerLine ==
R.ConstructorInitializerAllOnOneLineOrOnePerLine &&
+ ConstructorInitializerIndentWidth ==
+ R.ConstructorInitializerIndentWidth &&
DerivePointerAlignment == R.DerivePointerAlignment &&
ExperimentalAutoDetectBinPacking ==
R.ExperimentalAutoDetectBinPacking &&
@@ -393,6 +443,7 @@ struct FormatStyle {
KeepEmptyLinesAtTheStartOfBlocks ==
R.KeepEmptyLinesAtTheStartOfBlocks &&
NamespaceIndentation == R.NamespaceIndentation &&
+ ObjCBlockIndentWidth == R.ObjCBlockIndentWidth &&
ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty &&
ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList &&
PenaltyBreakComment == R.PenaltyBreakComment &&
@@ -405,10 +456,12 @@ struct FormatStyle {
Cpp11BracedListStyle == R.Cpp11BracedListStyle &&
Standard == R.Standard && TabWidth == R.TabWidth &&
UseTab == R.UseTab && SpacesInParentheses == R.SpacesInParentheses &&
+ SpacesInSquareBrackets == R.SpacesInSquareBrackets &&
SpacesInAngles == R.SpacesInAngles &&
SpaceInEmptyParentheses == R.SpaceInEmptyParentheses &&
SpacesInContainerLiterals == R.SpacesInContainerLiterals &&
SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses &&
+ SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
SpaceBeforeParens == R.SpaceBeforeParens &&
SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators &&
ContinuationIndentWidth == R.ContinuationIndentWidth &&
@@ -470,29 +523,34 @@ std::string configurationAsText(const FormatStyle &Style);
/// \brief Reformats the given \p Ranges in the token stream coming out of
/// \c Lex.
///
+/// DEPRECATED: Do not use.
+tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex,
+ SourceManager &SourceMgr,
+ ArrayRef<CharSourceRange> Ranges);
+
+/// \brief Reformats the given \p Ranges in the file \p ID.
+///
/// Each range is extended on either end to its next bigger logic unit, i.e.
/// everything that might influence its formatting or might be influenced by its
/// formatting.
///
/// Returns the \c Replacements necessary to make all \p Ranges comply with
/// \p Style.
-tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex,
- SourceManager &SourceMgr,
- std::vector<CharSourceRange> Ranges);
+tooling::Replacements reformat(const FormatStyle &Style,
+ SourceManager &SourceMgr, FileID ID,
+ ArrayRef<CharSourceRange> Ranges);
/// \brief Reformats the given \p Ranges in \p Code.
///
/// Otherwise identical to the reformat() function consuming a \c Lexer.
tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
- std::vector<tooling::Range> Ranges,
+ ArrayRef<tooling::Range> Ranges,
StringRef FileName = "<stdin>");
/// \brief Returns the \c LangOpts that the formatter expects you to set.
///
-/// \param Standard determines lexing mode: LC_Cpp11 and LS_Auto turn on C++11
-/// lexing mode, LS_Cpp03 - C++03 mode.
-LangOptions getFormattingLangOpts(
- FormatStyle::LanguageStandard Standard = FormatStyle::LS_Cpp11);
+/// \param Style determines specific settings for lexing mode.
+LangOptions getFormattingLangOpts(const FormatStyle &Style = getLLVMStyle());
/// \brief Description to be used for help text for a llvm::cl option for
/// specifying format style. The description is closely related to the operation
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 366c499b67..54e06efefd 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -11,11 +11,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef DRIVER_ASTCONSUMERS_H
-#define DRIVER_ASTCONSUMERS_H
+#ifndef LLVM_CLANG_FRONTEND_ASTCONSUMERS_H
+#define LLVM_CLANG_FRONTEND_ASTCONSUMERS_H
#include "clang/Basic/LLVM.h"
+#include <memory>
+
namespace clang {
class ASTConsumer;
@@ -30,24 +32,27 @@ class TargetOptions;
// original C code. The output is intended to be in a format such that
// clang could re-parse the output back into the same AST, but the
// implementation is still incomplete.
-ASTConsumer *CreateASTPrinter(raw_ostream *OS, StringRef FilterString);
+std::unique_ptr<ASTConsumer> CreateASTPrinter(raw_ostream *OS,
+ StringRef FilterString);
// AST dumper: dumps the raw AST in human-readable form to stderr; this is
// intended for debugging.
-ASTConsumer *CreateASTDumper(StringRef FilterString, bool DumpLookups = false);
+std::unique_ptr<ASTConsumer> CreateASTDumper(StringRef FilterString,
+ bool DumpDecls,
+ bool DumpLookups);
// AST Decl node lister: prints qualified names of all filterable AST Decl
// nodes.
-ASTConsumer *CreateASTDeclNodeLister();
+std::unique_ptr<ASTConsumer> CreateASTDeclNodeLister();
// Graphical AST viewer: for each function definition, creates a graph of
// the AST and displays it with the graph viewer "dotty". Also outputs
// function declarations to stderr.
-ASTConsumer *CreateASTViewer();
+std::unique_ptr<ASTConsumer> CreateASTViewer();
// DeclContext printer: prints out the DeclContext tree in human-readable form
// to stderr; this is intended for debugging.
-ASTConsumer *CreateDeclContextPrinter();
+std::unique_ptr<ASTConsumer> CreateDeclContextPrinter();
} // end clang namespace
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 42dc69ab4a..634224d08b 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -272,12 +272,12 @@ private:
/// \brief When non-NULL, this is the buffer used to store the contents of
/// the main file when it has been padded for use with the precompiled
/// preamble.
- llvm::MemoryBuffer *SavedMainFileBuffer;
+ std::unique_ptr<llvm::MemoryBuffer> SavedMainFileBuffer;
/// \brief When non-NULL, this is the buffer used to store the
/// contents of the preamble when it has been padded to build the
/// precompiled preamble.
- llvm::MemoryBuffer *PreambleBuffer;
+ std::unique_ptr<llvm::MemoryBuffer> PreambleBuffer;
/// \brief The number of warnings that occurred while parsing the preamble.
///
@@ -305,8 +305,7 @@ private:
/// \brief The language options used when we load an AST file.
LangOptions ASTFileLangOpts;
- static void ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags,
- const char **ArgBegin, const char **ArgEnd,
+ static void ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
ASTUnit &AST, bool CaptureDiagnostics);
void TranslateStoredDiagnostics(FileManager &FileMgr,
@@ -423,16 +422,28 @@ private:
explicit ASTUnit(bool MainFileIsAST);
void CleanTemporaryFiles();
- bool Parse(llvm::MemoryBuffer *OverrideMainBuffer);
-
- std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> >
- ComputePreamble(CompilerInvocation &Invocation,
- unsigned MaxLines, bool &CreatedBuffer);
-
- llvm::MemoryBuffer *getMainBufferWithPrecompiledPreamble(
- const CompilerInvocation &PreambleInvocationIn,
- bool AllowRebuild = true,
- unsigned MaxLines = 0);
+ bool Parse(std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer);
+
+ struct ComputedPreamble {
+ llvm::MemoryBuffer *Buffer;
+ std::unique_ptr<llvm::MemoryBuffer> Owner;
+ unsigned Size;
+ bool PreambleEndsAtStartOfLine;
+ ComputedPreamble(llvm::MemoryBuffer *Buffer,
+ std::unique_ptr<llvm::MemoryBuffer> Owner, unsigned Size,
+ bool PreambleEndsAtStartOfLine)
+ : Buffer(Buffer), Owner(std::move(Owner)), Size(Size),
+ PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) {}
+ ComputedPreamble(ComputedPreamble &&C)
+ : Buffer(C.Buffer), Owner(std::move(C.Owner)), Size(C.Size),
+ PreambleEndsAtStartOfLine(C.PreambleEndsAtStartOfLine) {}
+ };
+ ComputedPreamble ComputePreamble(CompilerInvocation &Invocation,
+ unsigned MaxLines);
+
+ std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble(
+ const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild = true,
+ unsigned MaxLines = 0);
void RealizeTopLevelDeclsFromPreamble();
/// \brief Transfers ownership of the objects (like SourceManager) from
@@ -684,8 +695,8 @@ public:
/// module file.
bool isModuleFile();
- llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
- std::string *ErrorStr = nullptr);
+ std::unique_ptr<llvm::MemoryBuffer>
+ getBufferForFile(StringRef Filename, std::string *ErrorStr = nullptr);
/// \brief Determine what kind of translation unit this AST represents.
TranslationUnitKind getTranslationUnitKind() const { return TUKind; }
@@ -708,14 +719,12 @@ public:
/// lifetime is expected to extend past that of the returned ASTUnit.
///
/// \returns - The initialized ASTUnit or null if the AST failed to load.
- static ASTUnit *LoadFromASTFile(const std::string &Filename,
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
- const FileSystemOptions &FileSystemOpts,
- bool OnlyLocalDecls = false,
- ArrayRef<RemappedFile> RemappedFiles = None,
- bool CaptureDiagnostics = false,
- bool AllowPCHWithCompilerErrors = false,
- bool UserFilesAreVolatile = false);
+ static std::unique_ptr<ASTUnit> LoadFromASTFile(
+ const std::string &Filename, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+ const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls = false,
+ ArrayRef<RemappedFile> RemappedFiles = None,
+ bool CaptureDiagnostics = false, bool AllowPCHWithCompilerErrors = false,
+ bool UserFilesAreVolatile = false);
private:
/// \brief Helper function for \c LoadFromCompilerInvocation() and
diff --git a/include/clang/Frontend/ChainedDiagnosticConsumer.h b/include/clang/Frontend/ChainedDiagnosticConsumer.h
index 11762a97cf..eb33273c2f 100644
--- a/include/clang/Frontend/ChainedDiagnosticConsumer.h
+++ b/include/clang/Frontend/ChainedDiagnosticConsumer.h
@@ -22,15 +22,20 @@ class LangOptions;
/// diagnostics should be included in counts.
class ChainedDiagnosticConsumer : public DiagnosticConsumer {
virtual void anchor();
- std::unique_ptr<DiagnosticConsumer> Primary;
+ std::unique_ptr<DiagnosticConsumer> OwningPrimary;
+ DiagnosticConsumer *Primary;
std::unique_ptr<DiagnosticConsumer> Secondary;
public:
- ChainedDiagnosticConsumer(DiagnosticConsumer *_Primary,
- DiagnosticConsumer *_Secondary) {
- Primary.reset(_Primary);
- Secondary.reset(_Secondary);
- }
+ ChainedDiagnosticConsumer(std::unique_ptr<DiagnosticConsumer> Primary,
+ std::unique_ptr<DiagnosticConsumer> Secondary)
+ : OwningPrimary(std::move(Primary)), Primary(OwningPrimary.get()),
+ Secondary(std::move(Secondary)) {}
+
+ /// \brief Construct without taking ownership of \c Primary.
+ ChainedDiagnosticConsumer(DiagnosticConsumer *Primary,
+ std::unique_ptr<DiagnosticConsumer> Secondary)
+ : Primary(Primary), Secondary(std::move(Secondary)) {}
void BeginSourceFile(const LangOptions &LO,
const Preprocessor *PP) override {
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 1d92efeda2..8e0c78a7bd 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -67,10 +67,13 @@ CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to
///< be generated.
CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.
+CODEGENOPT(MergeFunctions , 1, 0) ///< Set when -fmerge-functions is enabled.
CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled.
CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is
///< enabled.
CODEGENOPT(NoExecStack , 1, 0) ///< Set when -Wa,--noexecstack is enabled.
+CODEGENOPT(FatalWarnings , 1, 0) ///< Set when -Wa,--fatal-warnings is
+ ///< enabled.
CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled.
CODEGENOPT(NoGlobalMerge , 1, 0) ///< Set when -mno-global-merge is enabled.
CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled.
@@ -88,6 +91,10 @@ VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified
CODEGENOPT(ProfileInstrGenerate , 1, 0) ///< Instrument code to generate
///< execution counts to use with PGO.
+CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping regions to
+ ///< enable code coverage analysis.
+CODEGENOPT(DumpCoverageMapping , 1, 0) ///< Dump the generated coverage mapping
+ ///< regions.
/// If -fpcc-struct-return or -freg-struct-return is specified.
ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default)
@@ -100,6 +107,7 @@ CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero
///< offset in AddressSanitizer.
CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
///< MemorySanitizer
+CODEGENOPT(SanitizeCoverage, 3, 0) ///< Enable sanitizer coverage instrumentation.
CODEGENOPT(SanitizeUndefinedTrapOnError, 1, 0) ///< Set on
/// -fsanitize-undefined-trap-on-error
CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 3d532cea34..4e6171fbfe 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H
#define LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H
+#include <memory>
#include <string>
#include <vector>
#include "llvm/Support/Regex.h"
@@ -134,8 +135,8 @@ public:
/// The name of the relocation model to use.
std::string RelocationModel;
- /// Path to blacklist file for sanitizers.
- std::string SanitizerBlacklistFile;
+ /// The thread model to use
+ std::string ThreadModel;
/// If not an empty string, trap intrinsics are lowered to calls to this
/// function instead of to trap instructions.
@@ -183,15 +184,7 @@ public:
void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
#include "clang/Frontend/CodeGenOptions.def"
- CodeGenOptions() {
-#define CODEGENOPT(Name, Bits, Default) Name = Default;
-#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
- set##Name(Default);
-#include "clang/Frontend/CodeGenOptions.def"
-
- RelocationModel = "pic";
- memcpy(CoverageVersion, "402*", 4);
- }
+ CodeGenOptions();
};
} // end namespace clang
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 44e91026ac..31a0d098a2 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -14,6 +14,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/Utils.h"
+#include "clang/AST/ASTConsumer.h"
#include "clang/Lex/ModuleLoader.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
@@ -116,7 +117,10 @@ class CompilerInstance : public ModuleLoader {
/// \brief The set of top-level modules that has already been loaded,
/// along with the module map
llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules;
-
+
+ /// \brief Module names that have an override for the target file.
+ llvm::StringMap<std::string> ModuleFileOverrides;
+
/// \brief The location of the module-import keyword for the last module
/// import.
SourceLocation LastModuleImportLoc;
@@ -443,11 +447,11 @@ public:
/// takeASTConsumer - Remove the current AST consumer and give ownership to
/// the caller.
- ASTConsumer *takeASTConsumer() { return Consumer.release(); }
+ std::unique_ptr<ASTConsumer> takeASTConsumer() { return std::move(Consumer); }
/// setASTConsumer - Replace the current AST consumer; the compiler instance
/// takes ownership of \p Value.
- void setASTConsumer(ASTConsumer *Value);
+ void setASTConsumer(std::unique_ptr<ASTConsumer> Value);
/// }
/// @name Semantic analysis
@@ -459,8 +463,8 @@ public:
return *TheSema;
}
- Sema *takeSema() { return TheSema.release(); }
- void resetAndLeakSema() { BuryPointer(TheSema.release()); }
+ std::unique_ptr<Sema> takeSema();
+ void resetAndLeakSema();
/// }
/// @name Module Management
@@ -485,12 +489,6 @@ public:
return *CompletionConsumer;
}
- /// takeCodeCompletionConsumer - Remove the current code completion consumer
- /// and give ownership to the caller.
- CodeCompleteConsumer *takeCodeCompletionConsumer() {
- return CompletionConsumer.release();
- }
-
/// setCodeCompletionConsumer - Replace the current code completion consumer;
/// the compiler instance takes ownership of \p Value.
void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
@@ -646,7 +644,7 @@ public:
/// renamed to \p OutputPath in the end.
///
/// \param OutputPath - If given, the path to the output file.
- /// \param Error [out] - On failure, the error message.
+ /// \param Error [out] - On failure, the error.
/// \param BaseInput - If \p OutputPath is empty, the input path name to use
/// for deriving the output path.
/// \param Extension - The extension to use for derived output names.
@@ -663,13 +661,10 @@ public:
/// \param TempPathName [out] - If given, the temporary file path name
/// will be stored here on success.
static llvm::raw_fd_ostream *
- createOutputFile(StringRef OutputPath, std::string &Error,
- bool Binary, bool RemoveFileOnSignal,
- StringRef BaseInput,
- StringRef Extension,
- bool UseTemporary,
- bool CreateMissingDirectories,
- std::string *ResultPathName,
+ createOutputFile(StringRef OutputPath, std::error_code &Error, bool Binary,
+ bool RemoveFileOnSignal, StringRef BaseInput,
+ StringRef Extension, bool UseTemporary,
+ bool CreateMissingDirectories, std::string *ResultPathName,
std::string *TempPathName);
llvm::raw_null_ostream *createNullOutputFile();
@@ -699,6 +694,8 @@ public:
// Create module manager.
void createModuleManager();
+ bool loadModuleFile(StringRef FileName);
+
ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
Module::NameVisibilityKind Visibility,
bool IsInclusionDirective) override;
diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h
index ce1dc90465..5becadf40e 100644
--- a/include/clang/Frontend/DiagnosticRenderer.h
+++ b/include/clang/Frontend/DiagnosticRenderer.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_DIAGNOSTIC_RENDERER_H_
-#define LLVM_CLANG_FRONTEND_DIAGNOSTIC_RENDERER_H_
+#ifndef LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_H
+#define LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
index 9ac9d2828f..c407ff80ac 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -18,8 +18,10 @@
#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
+#include "clang/AST/ASTConsumer.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/FrontendOptions.h"
#include "llvm/ADT/StringRef.h"
#include <memory>
@@ -27,9 +29,7 @@
#include <vector>
namespace clang {
-class ASTConsumer;
class ASTMergeAction;
-class ASTUnit;
class CompilerInstance;
/// Abstract base class for actions which can be performed by the frontend.
@@ -41,8 +41,8 @@ class FrontendAction {
friend class WrapperFrontendAction;
private:
- ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ std::unique_ptr<ASTConsumer> CreateWrappedASTConsumer(CompilerInstance &CI,
+ StringRef InFile);
protected:
/// @name Implementation Action Interface
@@ -61,8 +61,8 @@ protected:
/// getCurrentFile().
///
/// \return The new AST consumer, or null on failure.
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) = 0;
+ virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) = 0;
/// \brief Callback before starting processing a single input, giving the
/// opportunity to modify the CompilerInvocation or do some other action
@@ -146,15 +146,24 @@ public:
return *CurrentASTUnit;
}
- ASTUnit *takeCurrentASTUnit() { return CurrentASTUnit.release(); }
+ std::unique_ptr<ASTUnit> takeCurrentASTUnit() {
+ return std::move(CurrentASTUnit);
+ }
void setCurrentInput(const FrontendInputFile &CurrentInput,
- ASTUnit *AST = nullptr);
+ std::unique_ptr<ASTUnit> AST = nullptr);
/// @}
/// @name Supported Modes
/// @{
+ /// \brief Is this action invoked on a model file?
+ ///
+ /// Model files are incomplete translation units that relies on type
+ /// information from another translation unit. Check ParseModelFileAction for
+ /// details.
+ virtual bool isModelParsingAction() const { return false; }
+
/// \brief Does this action only use the preprocessor?
///
/// If so no AST context will be created and this action will be invalid
@@ -222,16 +231,16 @@ protected:
void ExecuteAction() override;
public:
+ ASTFrontendAction() {}
bool usesPreprocessorOnly() const override { return false; }
};
class PluginASTAction : public ASTFrontendAction {
virtual void anchor();
-protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override = 0;
-
public:
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override = 0;
+
/// \brief Parse the given plugin command line arguments.
///
/// \param CI - The compiler instance, for use in reporting diagnostics.
@@ -247,8 +256,8 @@ class PreprocessorFrontendAction : public FrontendAction {
protected:
/// \brief Provide a default implementation which returns aborts;
/// this method should never be called by FrontendAction clients.
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
public:
bool usesPreprocessorOnly() const override { return true; }
@@ -264,8 +273,8 @@ class WrapperFrontendAction : public FrontendAction {
std::unique_ptr<FrontendAction> WrappedAction;
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
bool BeginInvocation(CompilerInstance &CI) override;
bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
void ExecuteAction() override;
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index 84cc82cfbe..850f87c073 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -26,8 +26,8 @@ class FileEntry;
class InitOnlyAction : public FrontendAction {
void ExecuteAction() override;
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
public:
// Don't claim to only use the preprocessor, we want to follow the AST path,
@@ -41,38 +41,38 @@ public:
class ASTPrintAction : public ASTFrontendAction {
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class ASTDumpAction : public ASTFrontendAction {
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class ASTDeclListAction : public ASTFrontendAction {
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class ASTViewAction : public ASTFrontendAction {
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class DeclContextPrintAction : public ASTFrontendAction {
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class GeneratePCHAction : public ASTFrontendAction {
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
TranslationUnitKind getTranslationUnitKind() override {
return TU_Prefix;
@@ -98,8 +98,8 @@ class GenerateModuleAction : public ASTFrontendAction {
bool IsSystem;
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
TranslationUnitKind getTranslationUnitKind() override {
return TU_Module;
@@ -128,8 +128,8 @@ public:
class SyntaxOnlyAction : public ASTFrontendAction {
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
public:
bool hasCodeCompletionSupport() const override { return true; }
@@ -139,8 +139,8 @@ public:
/// basic debugging and discovery.
class DumpModuleInfoAction : public ASTFrontendAction {
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
void ExecuteAction() override;
public:
@@ -152,8 +152,8 @@ public:
class VerifyPCHAction : public ASTFrontendAction {
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
void ExecuteAction() override;
@@ -177,8 +177,8 @@ class ASTMergeAction : public FrontendAction {
std::vector<std::string> ASTFiles;
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
bool BeginSourceFileAction(CompilerInstance &CI,
StringRef Filename) override;
@@ -200,7 +200,8 @@ public:
class PrintPreambleAction : public FrontendAction {
protected:
void ExecuteAction() override;
- ASTConsumer *CreateASTConsumer(CompilerInstance &, StringRef) override {
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &,
+ StringRef) override {
return nullptr;
}
diff --git a/include/clang/Frontend/FrontendDiagnostic.h b/include/clang/Frontend/FrontendDiagnostic.h
index 312dbf1411..0f37b7ece7 100644
--- a/include/clang/Frontend/FrontendDiagnostic.h
+++ b/include/clang/Frontend/FrontendDiagnostic.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTENDDIAGNOSTIC_H
-#define LLVM_CLANG_FRONTENDDIAGNOSTIC_H
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDDIAGNOSTIC_H
+#define LLVM_CLANG_FRONTEND_FRONTENDDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index e87da8de1c..4e93b4ee10 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -142,6 +142,8 @@ public:
///< global module index if available.
unsigned GenerateGlobalModuleIndex : 1; ///< Whether we can generate the
///< global module index if needed.
+ unsigned ASTDumpDecls : 1; ///< Whether we include declaration
+ ///< dumps in AST dumps.
unsigned ASTDumpLookups : 1; ///< Whether we include lookup table
///< dumps in AST dumps.
@@ -182,12 +184,15 @@ public:
ObjCMT_NsAtomicIOSOnlyProperty = 0x400,
/// \brief Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods.
ObjCMT_DesignatedInitializer = 0x800,
+ /// \brief Enable converting setter/getter expressions to property-dot syntx.
+ ObjCMT_PropertyDotSyntax = 0x1000,
ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty |
ObjCMT_Annotation | ObjCMT_Instancetype |
ObjCMT_NsMacros | ObjCMT_ProtocolConformance |
ObjCMT_NsAtomicIOSOnlyProperty |
ObjCMT_DesignatedInitializer),
- ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | ObjCMT_MigrateDecls)
+ ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting |
+ ObjCMT_MigrateDecls | ObjCMT_PropertyDotSyntax)
};
unsigned ObjCMTAction;
std::string ObjCMTWhiteListPath;
@@ -228,6 +233,10 @@ public:
/// The list of plugins to load.
std::vector<std::string> Plugins;
+ /// \brief The list of additional prebuilt module files to load before
+ /// processing the input.
+ std::vector<std::string> ModuleFiles;
+
/// \brief The list of AST files to merge.
std::vector<std::string> ASTMergeFiles;
@@ -246,7 +255,7 @@ public:
FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false),
FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false),
SkipFunctionBodies(false), UseGlobalModuleIndex(true),
- GenerateGlobalModuleIndex(true), ASTDumpLookups(false),
+ GenerateGlobalModuleIndex(true), ASTDumpDecls(false), ASTDumpLookups(false),
ARCMTAction(ARCMT_None), ObjCMTAction(ObjCMT_None),
ProgramAction(frontend::ParseSyntaxOnly)
{}
diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h
index ec925adb01..ecab630c12 100644
--- a/include/clang/Frontend/FrontendPluginRegistry.h
+++ b/include/clang/Frontend/FrontendPluginRegistry.h
@@ -7,12 +7,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
-#define LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H
+#define LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H
#include "clang/Frontend/FrontendAction.h"
#include "llvm/Support/Registry.h"
+// Instantiated in FrontendAction.cpp.
+extern template class llvm::Registry<clang::PluginASTAction>;
+
namespace clang {
/// The frontend plugin registry.
diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h
index 9680e1f2e0..8021d08942 100644
--- a/include/clang/Frontend/LangStandard.h
+++ b/include/clang/Frontend/LangStandard.h
@@ -24,7 +24,7 @@ enum LangFeatures {
C11 = (1 << 3),
CPlusPlus = (1 << 4),
CPlusPlus11 = (1 << 5),
- CPlusPlus1y = (1 << 6),
+ CPlusPlus14 = (1 << 6),
CPlusPlus1z = (1 << 7),
Digraphs = (1 << 8),
GNUMode = (1 << 9),
@@ -73,8 +73,8 @@ public:
/// isCPlusPlus11 - Language is a C++11 variant (or later).
bool isCPlusPlus11() const { return Flags & frontend::CPlusPlus11; }
- /// isCPlusPlus1y - Language is a C++14 variant (or later).
- bool isCPlusPlus1y() const { return Flags & frontend::CPlusPlus1y; }
+ /// isCPlusPlus14 - Language is a C++14 variant (or later).
+ bool isCPlusPlus14() const { return Flags & frontend::CPlusPlus14; }
/// isCPlusPlus1z - Language is a C++17 variant (or later).
bool isCPlusPlus1z() const { return Flags & frontend::CPlusPlus1z; }
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
index da9a118499..cac9c3c415 100644
--- a/include/clang/Frontend/LangStandards.def
+++ b/include/clang/Frontend/LangStandards.def
@@ -108,20 +108,27 @@ LANGSTANDARD(gnucxx11, "gnu++11",
LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode)
LANGSTANDARD(cxx1y, "c++1y",
- "Working draft for ISO C++ 2014",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs)
+ "ISO C++ 2014 with amendments",
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs)
+LANGSTANDARD(cxx14, "c++14",
+ "ISO C++ 2014 with amendments",
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs)
LANGSTANDARD(gnucxx1y, "gnu++1y",
- "Working draft for ISO C++ 2014 with GNU extensions",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs |
+ "ISO C++ 2014 with amendments and GNU extensions",
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs |
+ GNUMode)
+LANGSTANDARD(gnucxx14, "gnu++14",
+ "ISO C++ 2014 with amendments and GNU extensions",
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs |
GNUMode)
LANGSTANDARD(cxx1z, "c++1z",
"Working draft for ISO C++ 2017",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | CPlusPlus1z |
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z |
Digraphs)
LANGSTANDARD(gnucxx1z, "gnu++1z",
"Working draft for ISO C++ 2017 with GNU extensions",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | CPlusPlus1z |
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z |
Digraphs | GNUMode)
// OpenCL
@@ -134,6 +141,9 @@ LANGSTANDARD(opencl11, "CL1.1",
LANGSTANDARD(opencl12, "CL1.2",
"OpenCL 1.2",
LineComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(opencl20, "CL2.0",
+ "OpenCL 2.0",
+ LineComment | C99 | Digraphs | HexFloat)
// CUDA
LANGSTANDARD(cuda, "cuda",
diff --git a/include/clang/Frontend/LogDiagnosticPrinter.h b/include/clang/Frontend/LogDiagnosticPrinter.h
index 0130319870..98adf655fc 100644
--- a/include/clang/Frontend/LogDiagnosticPrinter.h
+++ b/include/clang/Frontend/LogDiagnosticPrinter.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_LOG_DIAGNOSTIC_PRINTER_H_
-#define LLVM_CLANG_FRONTEND_LOG_DIAGNOSTIC_PRINTER_H_
+#ifndef LLVM_CLANG_FRONTEND_LOGDIAGNOSTICPRINTER_H
+#define LLVM_CLANG_FRONTEND_LOGDIAGNOSTICPRINTER_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
@@ -35,6 +35,9 @@ class LogDiagnosticPrinter : public DiagnosticConsumer {
/// The ID of the diagnostic.
unsigned DiagnosticID;
+
+ /// The Option Flag for the diagnostic
+ std::string WarningOption;
/// The level of the diagnostic.
DiagnosticsEngine::Level DiagnosticLevel;
@@ -43,13 +46,16 @@ class LogDiagnosticPrinter : public DiagnosticConsumer {
void EmitDiagEntry(llvm::raw_ostream &OS,
const LogDiagnosticPrinter::DiagEntry &DE);
+ // Conditional ownership (when StreamOwner is non-null, it's keeping OS
+ // alive). We might want to replace this with a wrapper for conditional
+ // ownership eventually - it seems to pop up often enough.
raw_ostream &OS;
+ std::unique_ptr<raw_ostream> StreamOwner;
const LangOptions *LangOpts;
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
SourceLocation LastWarningLoc;
FullSourceLoc LastLoc;
- unsigned OwnsOutputStream : 1;
SmallVector<DiagEntry, 8> Entries;
@@ -58,8 +64,7 @@ class LogDiagnosticPrinter : public DiagnosticConsumer {
public:
LogDiagnosticPrinter(raw_ostream &OS, DiagnosticOptions *Diags,
- bool OwnsOutputStream = false);
- virtual ~LogDiagnosticPrinter();
+ std::unique_ptr<raw_ostream> StreamOwner);
void setDwarfDebugFlags(StringRef Value) {
DwarfDebugFlags = Value;
diff --git a/include/clang/Frontend/MigratorOptions.h b/include/clang/Frontend/MigratorOptions.h
index f9554e4a61..8eb71b13f8 100644
--- a/include/clang/Frontend/MigratorOptions.h
+++ b/include/clang/Frontend/MigratorOptions.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_MIGRATOROPTIONS
-#define LLVM_CLANG_FRONTEND_MIGRATOROPTIONS
+#ifndef LLVM_CLANG_FRONTEND_MIGRATOROPTIONS_H
+#define LLVM_CLANG_FRONTEND_MIGRATOROPTIONS_H
namespace clang {
diff --git a/include/clang/Frontend/MultiplexConsumer.h b/include/clang/Frontend/MultiplexConsumer.h
index a7e0444885..c9122dacb8 100644
--- a/include/clang/Frontend/MultiplexConsumer.h
+++ b/include/clang/Frontend/MultiplexConsumer.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_FRONTEND_MULTIPLEXCONSUMER_H
-#define CLANG_FRONTEND_MULTIPLEXCONSUMER_H
+#ifndef LLVM_CLANG_FRONTEND_MULTIPLEXCONSUMER_H
+#define LLVM_CLANG_FRONTEND_MULTIPLEXCONSUMER_H
#include "clang/Basic/LLVM.h"
#include "clang/Sema/SemaConsumer.h"
@@ -29,7 +29,7 @@ class MultiplexASTDeserializationListener;
class MultiplexConsumer : public SemaConsumer {
public:
// Takes ownership of the pointers in C.
- MultiplexConsumer(ArrayRef<ASTConsumer*> C);
+ MultiplexConsumer(std::vector<std::unique_ptr<ASTConsumer>> C);
~MultiplexConsumer();
// ASTConsumer
@@ -40,8 +40,14 @@ public:
void HandleInterestingDecl(DeclGroupRef D) override;
void HandleTranslationUnit(ASTContext &Ctx) override;
void HandleTagDeclDefinition(TagDecl *D) override;
+ void HandleTagDeclRequiredDefinition(const TagDecl *D) override;
void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override;
void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override;
+ void HandleImplicitImportDecl(ImportDecl *D) override;
+ void HandleLinkerOptionPragma(llvm::StringRef Opts) override;
+ void HandleDetectMismatch(llvm::StringRef Name,
+ llvm::StringRef Value) override;
+ void HandleDependentLibrary(llvm::StringRef Lib) override;
void CompleteTentativeDefinition(VarDecl *D) override;
void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) override;
ASTMutationListener *GetASTMutationListener() override;
@@ -53,7 +59,7 @@ public:
void ForgetSema() override;
private:
- std::vector<ASTConsumer*> Consumers; // Owns these.
+ std::vector<std::unique_ptr<ASTConsumer>> Consumers; // Owns these.
std::unique_ptr<MultiplexASTMutationListener> MutationListener;
std::unique_ptr<MultiplexASTDeserializationListener> DeserializationListener;
};
diff --git a/include/clang/Frontend/SerializedDiagnosticPrinter.h b/include/clang/Frontend/SerializedDiagnosticPrinter.h
index 4dda1fa4b6..4c57e9d404 100644
--- a/include/clang/Frontend/SerializedDiagnosticPrinter.h
+++ b/include/clang/Frontend/SerializedDiagnosticPrinter.h
@@ -7,10 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTIC_PRINTER_H_
-#define LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTIC_PRINTER_H_
+#ifndef LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICPRINTER_H
+#define LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICPRINTER_H
#include "clang/Basic/LLVM.h"
+#include "clang/Frontend/SerializedDiagnostics.h"
#include "llvm/Bitcode/BitstreamWriter.h"
namespace llvm {
@@ -23,41 +24,6 @@ class DiagnosticsEngine;
class DiagnosticOptions;
namespace serialized_diags {
-
-enum BlockIDs {
- /// \brief A top-level block which represents any meta data associated
- /// with the diagostics, including versioning of the format.
- BLOCK_META = llvm::bitc::FIRST_APPLICATION_BLOCKID,
-
- /// \brief The this block acts as a container for all the information
- /// for a specific diagnostic.
- BLOCK_DIAG
-};
-
-enum RecordIDs {
- RECORD_VERSION = 1,
- RECORD_DIAG,
- RECORD_SOURCE_RANGE,
- RECORD_DIAG_FLAG,
- RECORD_CATEGORY,
- RECORD_FILENAME,
- RECORD_FIXIT,
- RECORD_FIRST = RECORD_VERSION,
- RECORD_LAST = RECORD_FIXIT
-};
-
-/// A stable version of DiagnosticIDs::Level.
-///
-/// Do not change the order of values in this enum, and please increment the
-/// serialized diagnostics version number when you add to it.
-enum Level {
- Ignored = 0,
- Note,
- Warning,
- Error,
- Fatal,
- Remark
-};
/// \brief Returns a DiagnosticConsumer that serializes diagnostics to
/// a bitcode file.
@@ -67,8 +33,9 @@ enum Level {
/// This allows wrapper tools for Clang to get diagnostics from Clang
/// (via libclang) without needing to parse Clang's command line output.
///
-DiagnosticConsumer *create(raw_ostream *OS,
- DiagnosticOptions *diags);
+std::unique_ptr<DiagnosticConsumer> create(StringRef OutputFile,
+ DiagnosticOptions *Diags,
+ bool MergeChildRecords = false);
} // end serialized_diags namespace
} // end clang namespace
diff --git a/include/clang/Frontend/SerializedDiagnosticReader.h b/include/clang/Frontend/SerializedDiagnosticReader.h
new file mode 100644
index 0000000000..92e99d305d
--- /dev/null
+++ b/include/clang/Frontend/SerializedDiagnosticReader.h
@@ -0,0 +1,131 @@
+//===--- SerializedDiagnosticReader.h - Reads diagnostics -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_SERIALIZED_DIAGNOSTIC_READER_H_
+#define LLVM_CLANG_FRONTEND_SERIALIZED_DIAGNOSTIC_READER_H_
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/ErrorOr.h"
+
+namespace clang {
+namespace serialized_diags {
+
+enum class SDError {
+ CouldNotLoad = 1,
+ InvalidSignature,
+ InvalidDiagnostics,
+ MalformedTopLevelBlock,
+ MalformedSubBlock,
+ MalformedBlockInfoBlock,
+ MalformedMetadataBlock,
+ MalformedDiagnosticBlock,
+ MalformedDiagnosticRecord,
+ MissingVersion,
+ VersionMismatch,
+ UnsupportedConstruct,
+ /// A generic error for subclass handlers that don't want or need to define
+ /// their own error_category.
+ HandlerFailed
+};
+
+const std::error_category &SDErrorCategory();
+
+inline std::error_code make_error_code(SDError E) {
+ return std::error_code(static_cast<int>(E), SDErrorCategory());
+}
+
+/// \brief A location that is represented in the serialized diagnostics.
+struct Location {
+ unsigned FileID;
+ unsigned Line;
+ unsigned Col;
+ unsigned Offset;
+ Location(unsigned FileID, unsigned Line, unsigned Col, unsigned Offset)
+ : FileID(FileID), Line(Line), Col(Col), Offset(Offset) {}
+};
+
+/// \brief A base class that handles reading serialized diagnostics from a file.
+///
+/// Subclasses should override the visit* methods with their logic for handling
+/// the various constructs that are found in serialized diagnostics.
+class SerializedDiagnosticReader {
+public:
+ SerializedDiagnosticReader() {}
+ virtual ~SerializedDiagnosticReader() {}
+
+ /// \brief Read the diagnostics in \c File
+ std::error_code readDiagnostics(StringRef File);
+
+private:
+ enum class Cursor;
+
+ /// \brief Read to the next record or block to process.
+ llvm::ErrorOr<Cursor> skipUntilRecordOrBlock(llvm::BitstreamCursor &Stream,
+ unsigned &BlockOrRecordId);
+
+ /// \brief Read a metadata block from \c Stream.
+ std::error_code readMetaBlock(llvm::BitstreamCursor &Stream);
+
+ /// \brief Read a diagnostic block from \c Stream.
+ std::error_code readDiagnosticBlock(llvm::BitstreamCursor &Stream);
+
+protected:
+ /// \brief Visit the start of a diagnostic block.
+ virtual std::error_code visitStartOfDiagnostic() {
+ return std::error_code();
+ };
+ /// \brief Visit the end of a diagnostic block.
+ virtual std::error_code visitEndOfDiagnostic() { return std::error_code(); };
+ /// \brief Visit a category. This associates the category \c ID to a \c Name.
+ virtual std::error_code visitCategoryRecord(unsigned ID, StringRef Name) {
+ return std::error_code();
+ };
+ /// \brief Visit a flag. This associates the flag's \c ID to a \c Name.
+ virtual std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) {
+ return std::error_code();
+ };
+ /// \brief Visit a diagnostic.
+ virtual std::error_code
+ visitDiagnosticRecord(unsigned Severity, const Location &Location,
+ unsigned Category, unsigned Flag, StringRef Message) {
+ return std::error_code();
+ };
+ /// \brief Visit a filename. This associates the file's \c ID to a \c Name.
+ virtual std::error_code visitFilenameRecord(unsigned ID, unsigned Size,
+ unsigned Timestamp,
+ StringRef Name) {
+ return std::error_code();
+ };
+ /// \brief Visit a fixit hint.
+ virtual std::error_code
+ visitFixitRecord(const Location &Start, const Location &End, StringRef Text) {
+ return std::error_code();
+ };
+ /// \brief Visit a source range.
+ virtual std::error_code visitSourceRangeRecord(const Location &Start,
+ const Location &End) {
+ return std::error_code();
+ };
+ /// \brief Visit the version of the set of diagnostics.
+ virtual std::error_code visitVersionRecord(unsigned Version) {
+ return std::error_code();
+ };
+};
+
+} // end serialized_diags namespace
+} // end clang namespace
+
+namespace std {
+template <>
+struct is_error_code_enum<clang::serialized_diags::SDError> : std::true_type {};
+}
+
+#endif
diff --git a/include/clang/Frontend/SerializedDiagnostics.h b/include/clang/Frontend/SerializedDiagnostics.h
new file mode 100644
index 0000000000..2032cd3988
--- /dev/null
+++ b/include/clang/Frontend/SerializedDiagnostics.h
@@ -0,0 +1,59 @@
+//===--- SerializedDiagnostics.h - Common data for serialized diagnostics -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTICS_H_
+#define LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTICS_H_
+
+#include "llvm/Bitcode/BitCodes.h"
+
+namespace clang {
+namespace serialized_diags {
+
+enum BlockIDs {
+ /// \brief A top-level block which represents any meta data associated
+ /// with the diagostics, including versioning of the format.
+ BLOCK_META = llvm::bitc::FIRST_APPLICATION_BLOCKID,
+
+ /// \brief The this block acts as a container for all the information
+ /// for a specific diagnostic.
+ BLOCK_DIAG
+};
+
+enum RecordIDs {
+ RECORD_VERSION = 1,
+ RECORD_DIAG,
+ RECORD_SOURCE_RANGE,
+ RECORD_DIAG_FLAG,
+ RECORD_CATEGORY,
+ RECORD_FILENAME,
+ RECORD_FIXIT,
+ RECORD_FIRST = RECORD_VERSION,
+ RECORD_LAST = RECORD_FIXIT
+};
+
+/// \brief A stable version of DiagnosticIDs::Level.
+///
+/// Do not change the order of values in this enum, and please increment the
+/// serialized diagnostics version number when you add to it.
+enum Level {
+ Ignored = 0,
+ Note,
+ Warning,
+ Error,
+ Fatal,
+ Remark
+};
+
+/// \brief The serialized diagnostics version number.
+enum { VersionNumber = 2 };
+
+} // end serialized_diags namespace
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Frontend/TextDiagnostic.h b/include/clang/Frontend/TextDiagnostic.h
index acebb90b70..42c78af1d2 100644
--- a/include/clang/Frontend/TextDiagnostic.h
+++ b/include/clang/Frontend/TextDiagnostic.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_H_
-#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_H_
+#ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
+#define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
#include "clang/Frontend/DiagnosticRenderer.h"
diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h
index fe5aa3e91d..3bcf824455 100644
--- a/include/clang/Frontend/TextDiagnosticBuffer.h
+++ b/include/clang/Frontend/TextDiagnosticBuffer.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_BUFFER_H_
-#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_BUFFER_H_
+#ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICBUFFER_H
+#define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICBUFFER_H
#include "clang/Basic/Diagnostic.h"
#include <vector>
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index 9f6d5ff9dd..f8a71fe5e0 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_PRINTER_H_
-#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_PRINTER_H_
+#ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICPRINTER_H
+#define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICPRINTER_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index 4c0a7b7a9c..4cd93b994f 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -125,7 +125,7 @@ class ModuleDependencyCollector {
public:
StringRef getDest() { return DestDir; }
- bool insertSeen(StringRef Filename) { return Seen.insert(Filename); }
+ bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; }
void setHasErrors() { HasErrors = true; }
void addFileMapping(StringRef VPath, StringRef RPath) {
VFSWriter.addFileMapping(VPath, RPath);
@@ -206,6 +206,9 @@ inline uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
// global objects, but we don't want LeakDetectors to complain, so we bury them
// in a globally visible array.
void BuryPointer(const void *Ptr);
+template <typename T> void BuryPointer(std::unique_ptr<T> Ptr) {
+ BuryPointer(Ptr.release());
+}
} // end namespace clang
diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h
index 9273fac509..80e140bc50 100644
--- a/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
-#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
+#ifndef LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H
+#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Lex/Preprocessor.h"
@@ -145,9 +145,12 @@ public:
///
class Directive {
public:
- static Directive *create(bool RegexKind, SourceLocation DirectiveLoc,
- SourceLocation DiagnosticLoc, bool MatchAnyLine,
- StringRef Text, unsigned Min, unsigned Max);
+ static std::unique_ptr<Directive> create(bool RegexKind,
+ SourceLocation DirectiveLoc,
+ SourceLocation DiagnosticLoc,
+ bool MatchAnyLine, StringRef Text,
+ unsigned Min, unsigned Max);
+
public:
/// Constant representing n or more matches.
static const unsigned MaxCount = UINT_MAX;
@@ -181,7 +184,7 @@ public:
void operator=(const Directive &) LLVM_DELETED_FUNCTION;
};
- typedef std::vector<Directive*> DirectiveList;
+ typedef std::vector<std::unique_ptr<Directive>> DirectiveList;
/// ExpectedData - owns directive objects and deletes on destructor.
///
@@ -192,13 +195,11 @@ public:
DirectiveList Notes;
void Reset() {
- llvm::DeleteContainerPointers(Errors);
- llvm::DeleteContainerPointers(Warnings);
- llvm::DeleteContainerPointers(Remarks);
- llvm::DeleteContainerPointers(Notes);
+ Errors.clear();
+ Warnings.clear();
+ Remarks.clear();
+ Notes.clear();
}
-
- ~ExpectedData() { Reset(); }
};
enum DirectiveStatus {
@@ -211,7 +212,7 @@ public:
private:
DiagnosticsEngine &Diags;
DiagnosticConsumer *PrimaryClient;
- bool OwnsPrimaryClient;
+ std::unique_ptr<DiagnosticConsumer> PrimaryClientOwner;
std::unique_ptr<TextDiagnosticBuffer> Buffer;
const Preprocessor *CurrentPreprocessor;
const LangOptions *LangOpts;
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
index d9a4de4d99..2f9231dc9f 100644
--- a/include/clang/Lex/ExternalPreprocessorSource.h
+++ b/include/clang/Lex/ExternalPreprocessorSource.h
@@ -11,8 +11,8 @@
// construction of macro definitions from some external source.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
-#define LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
+#ifndef LLVM_CLANG_LEX_EXTERNALPREPROCESSORSOURCE_H
+#define LLVM_CLANG_LEX_EXTERNALPREPROCESSORSOURCE_H
namespace clang {
@@ -36,4 +36,4 @@ public:
}
-#endif // LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
+#endif
diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h
index 8e78b5ac98..5dac9b7c35 100644
--- a/include/clang/Lex/HeaderMap.h
+++ b/include/clang/Lex/HeaderMap.h
@@ -17,6 +17,8 @@
#include "clang/Basic/LLVM.h"
#include "llvm/Support/Compiler.h"
+#include <memory>
+
namespace llvm {
class MemoryBuffer;
}
@@ -34,15 +36,12 @@ class HeaderMap {
HeaderMap(const HeaderMap &) LLVM_DELETED_FUNCTION;
void operator=(const HeaderMap &) LLVM_DELETED_FUNCTION;
- const llvm::MemoryBuffer *FileBuffer;
+ std::unique_ptr<const llvm::MemoryBuffer> FileBuffer;
bool NeedsBSwap;
- HeaderMap(const llvm::MemoryBuffer *File, bool BSwap)
- : FileBuffer(File), NeedsBSwap(BSwap) {
- }
+ HeaderMap(std::unique_ptr<const llvm::MemoryBuffer> File, bool BSwap)
+ : FileBuffer(std::move(File)), NeedsBSwap(BSwap) {}
public:
- ~HeaderMap();
-
/// HeaderMap::Create - This attempts to load the specified file as a header
/// map. If it doesn't look like a HeaderMap, it gives up and returns null.
static const HeaderMap *Create(const FileEntry *FE, FileManager &FM);
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 0342629827..47e3313320 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -231,7 +231,11 @@ class HeaderSearch {
/// \brief Describes whether a given directory has a module map in it.
llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
-
+
+ /// \brief Set of module map files we've already loaded, and a flag indicating
+ /// whether they were valid or not.
+ llvm::DenseMap<const FileEntry *, bool> LoadedModuleMaps;
+
/// \brief Uniqued set of framework names, which is used to track which
/// headers were included as framework headers.
llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
@@ -384,14 +388,12 @@ public:
/// \param SuggestedModule If non-null, and the file found is semantically
/// part of a known module, this will be set to the module that should
/// be imported instead of preprocessing/parsing the file found.
- const FileEntry *LookupFile(StringRef Filename, SourceLocation IncludeLoc,
- bool isAngled, const DirectoryLookup *FromDir,
- const DirectoryLookup *&CurDir,
- ArrayRef<const FileEntry *> Includers,
- SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath,
- ModuleMap::KnownHeader *SuggestedModule,
- bool SkipCache = false);
+ const FileEntry *LookupFile(
+ StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
+ const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir,
+ ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
+ SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
+ ModuleMap::KnownHeader *SuggestedModule, bool SkipCache = false);
/// \brief Look up a subframework for the specified \#include file.
///
@@ -409,7 +411,7 @@ public:
/// \brief Look up the specified framework name in our framework cache.
/// \returns The DirectoryEntry it is in if we know, null otherwise.
FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) {
- return FrameworkMap.GetOrCreateValue(FWName).getValue();
+ return FrameworkMap[FWName];
}
/// \brief Mark the specified file as a target of of a \#include,
diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h
index 85424aa8a1..5d724c0de8 100644
--- a/include/clang/Lex/LexDiagnostic.h
+++ b/include/clang/Lex/LexDiagnostic.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_DIAGNOSTICLEX_H
-#define LLVM_CLANG_DIAGNOSTICLEX_H
+#ifndef LLVM_CLANG_LEX_LEXDIAGNOSTIC_H
+#define LLVM_CLANG_LEX_LEXDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index edcf883ece..c1f968be55 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LEXER_H
-#define LLVM_CLANG_LEXER_H
+#ifndef LLVM_CLANG_LEX_LEXER_H
+#define LLVM_CLANG_LEX_LEXER_H
#include "clang/Basic/LangOptions.h"
#include "clang/Lex/PreprocessorLexer.h"
@@ -405,9 +405,9 @@ public:
/// \returns The offset into the file where the preamble ends and the rest
/// of the file begins along with a boolean value indicating whether
/// the preamble ends at the beginning of a new line.
- static std::pair<unsigned, bool>
- ComputePreamble(const llvm::MemoryBuffer *Buffer, const LangOptions &LangOpts,
- unsigned MaxLines = 0);
+ static std::pair<unsigned, bool> ComputePreamble(StringRef Buffer,
+ const LangOptions &LangOpts,
+ unsigned MaxLines = 0);
/// \brief Checks that the given token is the first token that occurs after
/// the given location (this excludes comments and whitespace). Returns the
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index b7fcc5d34d..f60a152a0a 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_LITERALSUPPORT_H
-#define CLANG_LITERALSUPPORT_H
+#ifndef LLVM_CLANG_LEX_LITERALSUPPORT_H
+#define LLVM_CLANG_LEX_LITERALSUPPORT_H
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/LLVM.h"
diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h
index 4c0120c77f..d858ec2b42 100644
--- a/include/clang/Lex/MacroArgs.h
+++ b/include/clang/Lex/MacroArgs.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_MACROARGS_H
-#define LLVM_CLANG_MACROARGS_H
+#ifndef LLVM_CLANG_LEX_MACROARGS_H
+#define LLVM_CLANG_LEX_MACROARGS_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index 7c04031570..ca5d497048 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -12,10 +12,11 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_MACROINFO_H
-#define LLVM_CLANG_MACROINFO_H
+#ifndef LLVM_CLANG_LEX_MACROINFO_H
+#define LLVM_CLANG_LEX_MACROINFO_H
#include "clang/Lex/Token.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include <cassert>
@@ -45,7 +46,7 @@ class MacroInfo {
/// \see ArgumentList
unsigned NumArguments;
-
+
/// \brief This is the list of tokens that the macro is defined to.
SmallVector<Token, 8> ReplacementTokens;
@@ -78,8 +79,7 @@ class MacroInfo {
/// \brief Whether this macro contains the sequence ", ## __VA_ARGS__"
bool HasCommaPasting : 1;
-
-private:
+
//===--------------------------------------------------------------------===//
// State that changes as the macro is used.
@@ -107,28 +107,11 @@ private:
/// \brief Whether this macro was used as header guard.
bool UsedForHeaderGuard : 1;
- ~MacroInfo() {
- assert(!ArgumentList && "Didn't call destroy before dtor!");
- }
-
-public:
+ // Only the Preprocessor gets to create and destroy these.
MacroInfo(SourceLocation DefLoc);
-
- /// \brief Free the argument list of the macro.
- ///
- /// This restores this MacroInfo to a state where it can be reused for other
- /// devious purposes.
- void FreeArgumentList() {
- ArgumentList = nullptr;
- NumArguments = 0;
- }
-
- /// \brief Destroy this MacroInfo object.
- void Destroy() {
- FreeArgumentList();
- this->~MacroInfo();
- }
+ ~MacroInfo() {}
+public:
/// \brief Return the location that the macro was defined at.
SourceLocation getDefinitionLoc() const { return Location; }
@@ -299,6 +282,8 @@ public:
return 0;
}
+ void dump() const;
+
private:
unsigned getDefinitionLengthSlow(SourceManager &SM) const;
@@ -348,9 +333,6 @@ protected:
// Used by DefMacroDirective -----------------------------------------------//
- /// \brief True if this macro was imported from a module.
- bool IsImported : 1;
-
/// \brief Whether the definition of this macro is ambiguous, due to
/// multiple definitions coming in from multiple modules.
bool IsAmbiguous : 1;
@@ -361,11 +343,35 @@ protected:
/// module).
bool IsPublic : 1;
- MacroDirective(Kind K, SourceLocation Loc)
- : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
- IsImported(false), IsAmbiguous(false),
- IsPublic(true) {
- }
+ // Used by DefMacroDirective and UndefMacroDirective -----------------------//
+
+ /// \brief True if this macro was imported from a module.
+ bool IsImported : 1;
+
+ /// \brief For an imported directive, the number of modules whose macros are
+ /// overridden by this directive. Only used if IsImported.
+ unsigned NumOverrides : 26;
+
+ unsigned *getModuleDataStart();
+ const unsigned *getModuleDataStart() const {
+ return const_cast<MacroDirective*>(this)->getModuleDataStart();
+ }
+
+ MacroDirective(Kind K, SourceLocation Loc,
+ unsigned ImportedFromModuleID = 0,
+ ArrayRef<unsigned> Overrides = None)
+ : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
+ IsAmbiguous(false), IsPublic(true), IsImported(ImportedFromModuleID),
+ NumOverrides(Overrides.size()) {
+ assert(NumOverrides == Overrides.size() && "too many overrides");
+ assert((IsImported || !NumOverrides) && "overrides for non-module macro");
+
+ if (IsImported) {
+ unsigned *Extra = getModuleDataStart();
+ *Extra++ = ImportedFromModuleID;
+ std::copy(Overrides.begin(), Overrides.end(), Extra);
+ }
+ }
public:
Kind getKind() const { return Kind(MDKind); }
@@ -388,6 +394,27 @@ public:
void setIsFromPCH() { IsFromPCH = true; }
+ /// \brief True if this macro was imported from a module.
+ /// Note that this is never the case for a VisibilityMacroDirective.
+ bool isImported() const { return IsImported; }
+
+ /// \brief If this directive was imported from a module, get the submodule
+ /// whose directive this is. Note that this may be different from the module
+ /// that owns the MacroInfo for a DefMacroDirective due to #pragma pop_macro
+ /// and similar effects.
+ unsigned getOwningModuleID() const {
+ if (isImported())
+ return *getModuleDataStart();
+ return 0;
+ }
+
+ /// \brief Get the module IDs of modules whose macros are overridden by this
+ /// directive. Only valid if this is an imported directive.
+ ArrayRef<unsigned> getOverriddenModules() const {
+ assert(IsImported && "can only get overridden modules for imported macro");
+ return llvm::makeArrayRef(getModuleDataStart() + 1, NumOverrides);
+ }
+
class DefInfo {
DefMacroDirective *DefDirective;
SourceLocation UndefLoc;
@@ -450,6 +477,8 @@ public:
/// this macro was not defined there, return NULL.
const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const;
+ void dump() const;
+
static bool classof(const MacroDirective *) { return true; }
};
@@ -459,23 +488,22 @@ class DefMacroDirective : public MacroDirective {
public:
explicit DefMacroDirective(MacroInfo *MI)
- : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) {
+ : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) {
assert(MI && "MacroInfo is null");
}
- DefMacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported)
- : MacroDirective(MD_Define, Loc), Info(MI) {
+ DefMacroDirective(MacroInfo *MI, SourceLocation Loc,
+ unsigned ImportedFromModuleID = 0,
+ ArrayRef<unsigned> Overrides = None)
+ : MacroDirective(MD_Define, Loc, ImportedFromModuleID, Overrides),
+ Info(MI) {
assert(MI && "MacroInfo is null");
- IsImported = isImported;
}
/// \brief The data for the macro definition.
const MacroInfo *getInfo() const { return Info; }
MacroInfo *getInfo() { return Info; }
- /// \brief True if this macro was imported from a module.
- bool isImported() const { return IsImported; }
-
/// \brief Determine whether this macro definition is ambiguous with
/// other macro definitions.
bool isAmbiguous() const { return IsAmbiguous; }
@@ -492,9 +520,11 @@ public:
/// \brief A directive for an undefined macro.
class UndefMacroDirective : public MacroDirective {
public:
- explicit UndefMacroDirective(SourceLocation UndefLoc)
- : MacroDirective(MD_Undefine, UndefLoc) {
- assert(UndefLoc.isValid() && "Invalid UndefLoc!");
+ explicit UndefMacroDirective(SourceLocation UndefLoc,
+ unsigned ImportedFromModuleID = 0,
+ ArrayRef<unsigned> Overrides = None)
+ : MacroDirective(MD_Undefine, UndefLoc, ImportedFromModuleID, Overrides) {
+ assert((UndefLoc.isValid() || ImportedFromModuleID) && "Invalid UndefLoc!");
}
static bool classof(const MacroDirective *MD) {
@@ -521,6 +551,13 @@ public:
static bool classof(const VisibilityMacroDirective *) { return true; }
};
+inline unsigned *MacroDirective::getModuleDataStart() {
+ if (auto *Def = dyn_cast<DefMacroDirective>(this))
+ return reinterpret_cast<unsigned*>(Def + 1);
+ else
+ return reinterpret_cast<unsigned*>(cast<UndefMacroDirective>(this) + 1);
+}
+
inline SourceLocation MacroDirective::DefInfo::getLocation() const {
if (isInvalid())
return SourceLocation();
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
index 7869799c2c..36605c9c18 100644
--- a/include/clang/Lex/ModuleLoader.h
+++ b/include/clang/Lex/ModuleLoader.h
@@ -11,8 +11,8 @@
// loading named modules.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LEX_MODULE_LOADER_H
-#define LLVM_CLANG_LEX_MODULE_LOADER_H
+#ifndef LLVM_CLANG_LEX_MODULELOADER_H
+#define LLVM_CLANG_LEX_MODULELOADER_H
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index a86a927499..553716b8f6 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -65,19 +65,21 @@ private:
llvm::StringMap<Module *> Modules;
public:
- /// \brief Describes the role of a module header.
+ /// \brief Flags describing the role of a module header.
enum ModuleHeaderRole {
/// \brief This header is normally included in the module.
- NormalHeader,
+ NormalHeader = 0x0,
/// \brief This header is included but private.
- PrivateHeader,
- /// \brief This header is explicitly excluded from the module.
- ExcludedHeader
+ PrivateHeader = 0x1,
+ /// \brief This header is part of the module (for layering purposes) but
+ /// should be textually included.
+ TextualHeader = 0x2,
// Caution: Adding an enumerator needs other changes.
// Adjust the number of bits for KnownHeader::Storage.
// Adjust the bitfield HeaderFileInfo::HeaderRole size.
// Adjust the HeaderFileInfoTrait::ReadData streaming.
// Adjust the HeaderFileInfoTrait::EmitData streaming.
+ // Adjust ModuleMap::addHeader.
};
/// \brief A header that is known to reside within a given module,
@@ -96,8 +98,8 @@ public:
ModuleHeaderRole getRole() const { return Storage.getInt(); }
/// \brief Whether this header is available in the module.
- bool isAvailable() const {
- return getRole() != ExcludedHeader && getModule()->isAvailable();
+ bool isAvailable() const {
+ return getModule()->isAvailable();
}
// \brief Whether this known header is valid (i.e., it has an
@@ -107,6 +109,8 @@ public:
}
};
+ typedef llvm::SmallPtrSet<const FileEntry *, 1> AdditionalModMapsSet;
+
private:
typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1> >
HeadersMap;
@@ -146,6 +150,12 @@ private:
/// framework modules from within those directories.
llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories;
+ /// A mapping from an inferred module to the module map that allowed the
+ /// inference.
+ llvm::DenseMap<const Module *, const FileEntry *> InferredModuleAllowedBy;
+
+ llvm::DenseMap<const Module *, AdditionalModMapsSet> AdditionalModMaps;
+
/// \brief Describes whether we haved parsed a particular file as a module
/// map.
llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap;
@@ -241,11 +251,16 @@ public:
/// used from. Used to disambiguate if a header is present in multiple
/// modules.
///
+ /// \param IncludeTextualHeaders If \c true, also find textual headers. By
+ /// default, these are treated like excluded headers and result in no known
+ /// header being found.
+ ///
/// \returns The module KnownHeader, which provides the module that owns the
/// given header file. The KnownHeader is default constructed to indicate
/// that no module owns this header file.
KnownHeader findModuleForHeader(const FileEntry *File,
- Module *RequestingModule = nullptr);
+ Module *RequestingModule = nullptr,
+ bool IncludeTextualHeaders = false);
/// \brief Reports errors if a module must not include a specific file.
///
@@ -306,9 +321,6 @@ public:
/// \param Parent The module that will act as the parent of this submodule,
/// or NULL to indicate that this is a top-level module.
///
- /// \param ModuleMap The module map that defines or allows the inference of
- /// this module.
- ///
/// \param IsFramework Whether this is a framework module.
///
/// \param IsExplicit Whether this is an explicit submodule.
@@ -316,7 +328,6 @@ public:
/// \returns The found or newly-created module, along with a boolean value
/// that will be true if the module is newly-created.
std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent,
- const FileEntry *ModuleMap,
bool IsFramework,
bool IsExplicit);
@@ -349,7 +360,35 @@ public:
///
/// \returns The file entry for the module map file containing the given
/// module, or NULL if the module definition was inferred.
- const FileEntry *getContainingModuleMapFile(Module *Module) const;
+ const FileEntry *getContainingModuleMapFile(const Module *Module) const;
+
+ /// \brief Get the module map file that (along with the module name) uniquely
+ /// identifies this module.
+ ///
+ /// The particular module that \c Name refers to may depend on how the module
+ /// was found in header search. However, the combination of \c Name and
+ /// this module map will be globally unique for top-level modules. In the case
+ /// of inferred modules, returns the module map that allowed the inference
+ /// (e.g. contained 'module *'). Otherwise, returns
+ /// getContainingModuleMapFile().
+ const FileEntry *getModuleMapFileForUniquing(const Module *M) const;
+
+ void setInferredModuleAllowedBy(Module *M, const FileEntry *ModuleMap);
+
+ /// \brief Get any module map files other than getModuleMapFileForUniquing(M)
+ /// that define submodules of a top-level module \p M. This is cheaper than
+ /// getting the module map file for each submodule individually, since the
+ /// expected number of results is very small.
+ AdditionalModMapsSet *getAdditionalModuleMapFiles(const Module *M) {
+ auto I = AdditionalModMaps.find(M);
+ if (I == AdditionalModMaps.end())
+ return nullptr;
+ return &I->second;
+ }
+
+ void addAdditionalModuleMapFile(const Module *M, const FileEntry *ModuleMap) {
+ AdditionalModMaps[M].insert(ModuleMap);
+ }
/// \brief Resolve all of the unresolved exports in the given module.
///
@@ -404,6 +443,9 @@ public:
void addHeader(Module *Mod, const FileEntry *Header,
ModuleHeaderRole Role);
+ /// \brief Marks this header as being excluded from the given module.
+ void excludeHeader(Module *Mod, const FileEntry *Header);
+
/// \brief Parse the given module map file, and record any modules we
/// encounter.
///
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h
index e3c6de555b..83e6f99078 100644
--- a/include/clang/Lex/MultipleIncludeOpt.h
+++ b/include/clang/Lex/MultipleIncludeOpt.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_MULTIPLEINCLUDEOPT_H
-#define LLVM_CLANG_MULTIPLEINCLUDEOPT_H
+#ifndef LLVM_CLANG_LEX_MULTIPLEINCLUDEOPT_H
+#define LLVM_CLANG_LEX_MULTIPLEINCLUDEOPT_H
#include "clang/Basic/SourceLocation.h"
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 7f1ea34a46..056c58aa33 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -322,15 +322,12 @@ public:
/// \brief Simple wrapper class for chaining callbacks.
class PPChainedCallbacks : public PPCallbacks {
virtual void anchor();
- PPCallbacks *First, *Second;
+ std::unique_ptr<PPCallbacks> First, Second;
public:
- PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
- : First(_First), Second(_Second) {}
- ~PPChainedCallbacks() {
- delete Second;
- delete First;
- }
+ PPChainedCallbacks(std::unique_ptr<PPCallbacks> _First,
+ std::unique_ptr<PPCallbacks> _Second)
+ : First(std::move(_First)), Second(std::move(_Second)) {}
void FileChanged(SourceLocation Loc, FileChangeReason Reason,
SrcMgr::CharacteristicKind FileType,
diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
index 2352ccea18..54c91f6b08 100644
--- a/include/clang/Lex/PTHLexer.h
+++ b/include/clang/Lex/PTHLexer.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_PTHLEXER_H
-#define LLVM_CLANG_PTHLEXER_H
+#ifndef LLVM_CLANG_LEX_PTHLEXER_H
+#define LLVM_CLANG_LEX_PTHLEXER_H
#include "clang/Lex/PreprocessorLexer.h"
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index 11b5ceaad1..64ecf5f575 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_PTHMANAGER_H
-#define LLVM_CLANG_PTHMANAGER_H
+#ifndef LLVM_CLANG_LEX_PTHMANAGER_H
+#define LLVM_CLANG_LEX_PTHMANAGER_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
@@ -20,6 +20,7 @@
#include "clang/Lex/PTHLexer.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/OnDiskHashTable.h"
#include <string>
namespace llvm {
@@ -36,19 +37,26 @@ class FileSystemStatCache;
class PTHManager : public IdentifierInfoLookup {
friend class PTHLexer;
+ friend class PTHStatCache;
+
+ class PTHStringLookupTrait;
+ class PTHFileLookupTrait;
+ typedef llvm::OnDiskChainedHashTable<PTHStringLookupTrait> PTHStringIdLookup;
+ typedef llvm::OnDiskChainedHashTable<PTHFileLookupTrait> PTHFileLookup;
+
/// The memory mapped PTH file.
- const llvm::MemoryBuffer* Buf;
+ std::unique_ptr<const llvm::MemoryBuffer> Buf;
/// Alloc - Allocator used for IdentifierInfo objects.
llvm::BumpPtrAllocator Alloc;
/// IdMap - A lazily generated cache mapping from persistent identifiers to
/// IdentifierInfo*.
- IdentifierInfo** PerIDCache;
+ std::unique_ptr<IdentifierInfo *[], llvm::FreeDeleter> PerIDCache;
/// FileLookup - Abstract data structure used for mapping between files
/// and token data in the PTH file.
- void* FileLookup;
+ std::unique_ptr<PTHFileLookup> FileLookup;
/// IdDataTable - Array representing the mapping from persistent IDs to the
/// data offset within the PTH file containing the information to
@@ -57,7 +65,7 @@ class PTHManager : public IdentifierInfoLookup {
/// SortedIdTable - Abstract data structure mapping from strings to
/// persistent IDs. This is used by get().
- void* StringIdLookup;
+ std::unique_ptr<PTHStringIdLookup> StringIdLookup;
/// NumIds - The number of identifiers in the PTH file.
const unsigned NumIds;
@@ -76,10 +84,12 @@ class PTHManager : public IdentifierInfoLookup {
/// This constructor is intended to only be called by the static 'Create'
/// method.
- PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup,
- const unsigned char* idDataTable, IdentifierInfo** perIDCache,
- void* stringIdLookup, unsigned numIds,
- const unsigned char* spellingBase, const char *originalSourceFile);
+ PTHManager(std::unique_ptr<const llvm::MemoryBuffer> buf,
+ std::unique_ptr<PTHFileLookup> fileLookup,
+ const unsigned char *idDataTable,
+ std::unique_ptr<IdentifierInfo *[], llvm::FreeDeleter> perIDCache,
+ std::unique_ptr<PTHStringIdLookup> stringIdLookup, unsigned numIds,
+ const unsigned char *spellingBase, const char *originalSourceFile);
PTHManager(const PTHManager &) LLVM_DELETED_FUNCTION;
void operator=(const PTHManager &) LLVM_DELETED_FUNCTION;
@@ -131,7 +141,7 @@ public:
/// FileManager objects. These objects use the PTH data to speed up
/// calls to stat by memoizing their results from when the PTH file
/// was generated.
- FileSystemStatCache *createStatCache();
+ std::unique_ptr<FileSystemStatCache> createStatCache();
};
} // end namespace clang
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index 4a695a0e90..4123bae2ea 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_PRAGMA_H
-#define LLVM_CLANG_PRAGMA_H
+#ifndef LLVM_CLANG_LEX_PRAGMA_H
+#define LLVM_CLANG_LEX_PRAGMA_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringMap.h"
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index d4b4ba2469..d16f212816 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -79,6 +79,13 @@ public:
}
};
+/// \brief Context in which macro name is used.
+enum MacroUse {
+ MU_Other = 0, // other than #define or #undef
+ MU_Define = 1, // macro name specified in #define
+ MU_Undef = 2 // macro name specified in #undef
+};
+
/// \brief Engages in a tight little dance with the lexer to efficiently
/// preprocess tokens.
///
@@ -92,7 +99,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
const TargetInfo *Target;
FileManager &FileMgr;
SourceManager &SourceMgr;
- ScratchBuffer *ScratchBuf;
+ std::unique_ptr<ScratchBuffer> ScratchBuf;
HeaderSearch &HeaderInfo;
ModuleLoader &TheModuleLoader;
@@ -128,6 +135,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
IdentifierInfo *Ident__is_identifier; // __is_identifier
IdentifierInfo *Ident__building_module; // __building_module
IdentifierInfo *Ident__MODULE__; // __MODULE__
+ IdentifierInfo *Ident__has_cpp_attribute; // __has_cpp_attribute
SourceLocation DATELoc, TIMELoc;
unsigned CounterValue; // Next __COUNTER__ value.
@@ -192,7 +200,11 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// \brief Tracks all of the pragmas that the client registered
/// with this preprocessor.
- PragmaNamespace *PragmaHandlers;
+ std::unique_ptr<PragmaNamespace> PragmaHandlers;
+
+ /// \brief Pragma handlers of the original source is stored here during the
+ /// parsing of a model file.
+ std::unique_ptr<PragmaNamespace> PragmaHandlersBackup;
/// \brief Tracks all of the comment handlers that the client registered
/// with this preprocessor.
@@ -250,7 +262,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// of bytes will place the lexer at the start of a line.
///
/// This is used when loading a precompiled preamble.
- std::pair<unsigned, bool> SkipMainFilePreamble;
+ std::pair<int, bool> SkipMainFilePreamble;
/// \brief The current top of the stack that we're lexing from if
/// not expanding a macro and we are lexing directly from source code.
@@ -334,7 +346,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// \brief Actions invoked when some preprocessor activity is
/// encountered (e.g. a file is \#included, etc).
- PPCallbacks *Callbacks;
+ std::unique_ptr<PPCallbacks> Callbacks;
struct MacroExpandsInfo {
Token Tok;
@@ -391,7 +403,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// \brief Cache of macro expanders to reduce malloc traffic.
enum { TokenLexerCacheSize = 8 };
unsigned NumCachedTokenLexers;
- TokenLexer *TokenLexerCache[TokenLexerCacheSize];
+ std::unique_ptr<TokenLexer> TokenLexerCache[TokenLexerCacheSize];
/// \}
/// \brief Keeps macro expanded tokens for TokenLexers.
@@ -433,17 +445,12 @@ private: // Cached tokens state.
struct MacroInfoChain {
MacroInfo MI;
MacroInfoChain *Next;
- MacroInfoChain *Prev;
};
/// MacroInfos are managed as a chain for easy disposal. This is the head
/// of that list.
MacroInfoChain *MIChainHead;
- /// A "freelist" of MacroInfo objects that can be reused for quick
- /// allocation.
- MacroInfoChain *MICache;
-
struct DeserializedMacroInfoChain {
MacroInfo MI;
unsigned OwningModuleID; // MUST be immediately after the MacroInfo object
@@ -469,6 +476,17 @@ public:
/// lifetime of the preprocessor.
void Initialize(const TargetInfo &Target);
+ /// \brief Initialize the preprocessor to parse a model file
+ ///
+ /// To parse model files the preprocessor of the original source is reused to
+ /// preserver the identifier table. However to avoid some duplicate
+ /// information in the preprocessor some cleanup is needed before it is used
+ /// to parse model files. This method does that cleanup.
+ void InitializeForModelFile();
+
+ /// \brief Cleanup after model file parsing
+ void FinalizeForModelFile();
+
/// \brief Retrieve the preprocessor options used to initialize this
/// preprocessor.
PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; }
@@ -557,6 +575,9 @@ public:
/// expansions going on at the time.
PreprocessorLexer *getCurrentFileLexer() const;
+ /// \brief Return the submodule owning the file being lexed.
+ Module *getCurrentSubmodule() const { return CurSubmodule; }
+
/// \brief Returns the FileID for the preprocessor predefines.
FileID getPredefinesFileID() const { return PredefinesFileID; }
@@ -565,11 +586,12 @@ public:
///
/// Note that this class takes ownership of any PPCallbacks object given to
/// it.
- PPCallbacks *getPPCallbacks() const { return Callbacks; }
- void addPPCallbacks(PPCallbacks *C) {
+ PPCallbacks *getPPCallbacks() const { return Callbacks.get(); }
+ void addPPCallbacks(std::unique_ptr<PPCallbacks> C) {
if (Callbacks)
- C = new PPChainedCallbacks(C, Callbacks);
- Callbacks = C;
+ C = llvm::make_unique<PPChainedCallbacks>(std::move(C),
+ std::move(Callbacks));
+ Callbacks = std::move(C);
}
/// \}
@@ -605,13 +627,15 @@ public:
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD);
DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI,
SourceLocation Loc,
- bool isImported) {
- DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc, isImported);
+ unsigned ImportedFromModuleID,
+ ArrayRef<unsigned> Overrides) {
+ DefMacroDirective *MD =
+ AllocateDefMacroDirective(MI, Loc, ImportedFromModuleID, Overrides);
appendMacroDirective(II, MD);
return MD;
}
DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI){
- return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), false);
+ return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), 0, None);
}
/// \brief Set a MacroDirective that was loaded from a PCH file.
void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
@@ -1307,6 +1331,7 @@ public:
/// reference is for system \#include's or not (i.e. using <> instead of "").
const FileEntry *LookupFile(SourceLocation FilenameLoc, StringRef Filename,
bool isAngled, const DirectoryLookup *FromDir,
+ const FileEntry *FromFile,
const DirectoryLookup *&CurDir,
SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath,
@@ -1343,11 +1368,12 @@ public:
/// followed by EOD. Return true if the token is not a valid on-off-switch.
bool LexOnOffSwitch(tok::OnOffSwitch &OOS);
- bool CheckMacroName(Token &MacroNameTok, char isDefineUndef);
+ bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef);
private:
void PushIncludeMacroStack() {
+ assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer");
IncludeMacroStack.push_back(IncludeStackInfo(
CurLexerKind, CurSubmodule, std::move(CurLexer), std::move(CurPTHLexer),
CurPPLexer, std::move(CurTokenLexer), CurDirLookup));
@@ -1370,24 +1396,23 @@ private:
/// \brief Allocate a new MacroInfo object.
MacroInfo *AllocateMacroInfo();
- DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI,
- SourceLocation Loc,
- bool isImported);
- UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc);
+ DefMacroDirective *
+ AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc,
+ unsigned ImportedFromModuleID = 0,
+ ArrayRef<unsigned> Overrides = None);
+ UndefMacroDirective *
+ AllocateUndefMacroDirective(SourceLocation UndefLoc,
+ unsigned ImportedFromModuleID = 0,
+ ArrayRef<unsigned> Overrides = None);
VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc,
bool isPublic);
- /// \brief Release the specified MacroInfo for re-use.
- ///
- /// This memory will be reused for allocating new MacroInfo objects.
- void ReleaseMacroInfo(MacroInfo* MI);
-
/// \brief Lex and validate a macro name, which occurs after a
/// \#define or \#undef.
///
/// This emits a diagnostic, sets the token kind to eod,
/// and discards the rest of the macro line if the macro name is invalid.
- void ReadMacroName(Token &MacroNameTok, char isDefineUndef = 0);
+ void ReadMacroName(Token &MacroNameTok, MacroUse isDefineUndef = MU_Other);
/// The ( starting an argument list of a macro definition has just been read.
/// Lex the rest of the arguments and the closing ), updating \p MI with
@@ -1521,6 +1546,7 @@ private:
void HandleIncludeDirective(SourceLocation HashLoc,
Token &Tok,
const DirectoryLookup *LookupFrom = nullptr,
+ const FileEntry *LookupFromFile = nullptr,
bool isImport = false);
void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok);
void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok);
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
index ed226ae9a3..3a91fa72f2 100644
--- a/include/clang/Lex/PreprocessorLexer.h
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_PreprocessorLexer_H
-#define LLVM_CLANG_PreprocessorLexer_H
+#ifndef LLVM_CLANG_LEX_PREPROCESSORLEXER_H
+#define LLVM_CLANG_LEX_PREPROCESSORLEXER_H
#include "clang/Lex/MultipleIncludeOpt.h"
#include "clang/Lex/Token.h"
diff --git a/include/clang/Lex/ScratchBuffer.h b/include/clang/Lex/ScratchBuffer.h
index f03515ffc1..a3d6096821 100644
--- a/include/clang/Lex/ScratchBuffer.h
+++ b/include/clang/Lex/ScratchBuffer.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SCRATCHBUFFER_H
-#define LLVM_CLANG_SCRATCHBUFFER_H
+#ifndef LLVM_CLANG_LEX_SCRATCHBUFFER_H
+#define LLVM_CLANG_LEX_SCRATCHBUFFER_H
#include "clang/Basic/SourceLocation.h"
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index c8b77d1174..a58c0c583f 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOKEN_H
-#define LLVM_CLANG_TOKEN_H
+#ifndef LLVM_CLANG_LEX_TOKEN_H
+#define LLVM_CLANG_LEX_TOKEN_H
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/SourceLocation.h"
diff --git a/include/clang/Lex/TokenConcatenation.h b/include/clang/Lex/TokenConcatenation.h
index 551300f402..a2d98b0d47 100644
--- a/include/clang/Lex/TokenConcatenation.h
+++ b/include/clang/Lex/TokenConcatenation.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_LEX_TOKEN_CONCATENATION_H
-#define CLANG_LEX_TOKEN_CONCATENATION_H
+#ifndef LLVM_CLANG_LEX_TOKENCONCATENATION_H
+#define LLVM_CLANG_LEX_TOKENCONCATENATION_H
#include "clang/Basic/TokenKinds.h"
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
index a873a2e275..306f98e260 100644
--- a/include/clang/Lex/TokenLexer.h
+++ b/include/clang/Lex/TokenLexer.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOKENLEXER_H
-#define LLVM_CLANG_TOKENLEXER_H
+#ifndef LLVM_CLANG_LEX_TOKENLEXER_H
+#define LLVM_CLANG_LEX_TOKENLEXER_H
#include "clang/Basic/SourceLocation.h"
diff --git a/include/clang/Parse/ParseDiagnostic.h b/include/clang/Parse/ParseDiagnostic.h
index b593806ff3..f3a7f3b7a8 100644
--- a/include/clang/Parse/ParseDiagnostic.h
+++ b/include/clang/Parse/ParseDiagnostic.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_DIAGNOSTICPARSE_H
-#define LLVM_CLANG_DIAGNOSTICPARSE_H
+#ifndef LLVM_CLANG_PARSE_PARSEDIAGNOSTIC_H
+#define LLVM_CLANG_PARSE_PARSEDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 6f4b64d2a6..38073c37c7 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -135,10 +135,9 @@ class Parser : public CodeCompletionHandler {
mutable IdentifierInfo *Ident_final;
mutable IdentifierInfo *Ident_override;
- // Some token kinds such as C++ type traits can be reverted to identifiers and
- // still get used as keywords depending on context.
- llvm::SmallDenseMap<const IdentifierInfo *, tok::TokenKind>
- ContextualKeywords;
+ // C++ type trait keywords that can be reverted to identifiers and still be
+ // used as type traits.
+ llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertibleTypeTraits;
std::unique_ptr<PragmaHandler> AlignHandler;
std::unique_ptr<PragmaHandler> GCCVisibilityHandler;
@@ -163,6 +162,8 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> MSSection;
std::unique_ptr<PragmaHandler> OptimizeHandler;
std::unique_ptr<PragmaHandler> LoopHintHandler;
+ std::unique_ptr<PragmaHandler> UnrollHintHandler;
+ std::unique_ptr<PragmaHandler> NoUnrollHintHandler;
std::unique_ptr<CommentHandler> CommentSemaHandler;
@@ -257,24 +258,8 @@ public:
typedef SmallVector<TemplateParameterList *, 4> TemplateParameterLists;
- typedef clang::ExprResult ExprResult;
- typedef clang::StmtResult StmtResult;
- typedef clang::BaseResult BaseResult;
- typedef clang::MemInitResult MemInitResult;
- typedef clang::TypeResult TypeResult;
-
- typedef Expr *ExprArg;
- typedef MutableArrayRef<Stmt*> MultiStmtArg;
typedef Sema::FullExprArg FullExprArg;
- ExprResult ExprError() { return ExprResult(true); }
- StmtResult StmtError() { return StmtResult(true); }
-
- ExprResult ExprError(const DiagnosticBuilder &) { return ExprError(); }
- StmtResult StmtError(const DiagnosticBuilder &) { return StmtError(); }
-
- ExprResult ExprEmpty() { return ExprResult(false); }
-
// Parsing methods.
/// Initialize - Warm up the parser.
@@ -349,6 +334,15 @@ private:
/// For typos, give a fixit to '='
bool isTokenEqualOrEqualTypo();
+ /// \brief Return the current token to the token stream and make the given
+ /// token the current token.
+ void UnconsumeToken(Token &Consumed) {
+ Token Next = Tok;
+ PP.EnterToken(Consumed);
+ ConsumeToken();
+ PP.EnterToken(Next);
+ }
+
/// ConsumeAnyToken - Dispatch to the right Consume* method based on the
/// current token type. This should only be used in cases where the type of
/// the token really isn't known, e.g. in error recovery.
@@ -486,12 +480,12 @@ private:
void HandlePragmaMSVtorDisp();
void HandlePragmaMSPragma();
- unsigned HandlePragmaMSSection(llvm::StringRef PragmaName,
- SourceLocation PragmaLocation);
- unsigned HandlePragmaMSSegment(llvm::StringRef PragmaName,
- SourceLocation PragmaLocation);
- unsigned HandlePragmaMSInitSeg(llvm::StringRef PragmaName,
- SourceLocation PragmaLocation);
+ bool HandlePragmaMSSection(StringRef PragmaName,
+ SourceLocation PragmaLocation);
+ bool HandlePragmaMSSegment(StringRef PragmaName,
+ SourceLocation PragmaLocation);
+ bool HandlePragmaMSInitSeg(StringRef PragmaName,
+ SourceLocation PragmaLocation);
/// \brief Handle the annotation token produced for
/// #pragma align...
@@ -522,8 +516,8 @@ private:
StmtResult HandlePragmaCaptured();
/// \brief Handle the annotation token produced for
- /// #pragma vectorize...
- LoopHint HandlePragmaLoopHint();
+ /// #pragma clang loop and #pragma unroll.
+ bool HandlePragmaLoopHint(LoopHint &Hint);
/// GetLookAheadToken - This peeks ahead N tokens and returns that token
/// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)
@@ -590,8 +584,9 @@ private:
/// Annotation was successful.
ANK_Success
};
- AnnotatedNameKind TryAnnotateName(bool IsAddressOfOperand,
- CorrectionCandidateCallback *CCC = nullptr);
+ AnnotatedNameKind
+ TryAnnotateName(bool IsAddressOfOperand,
+ std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr);
/// Push a tok::annot_cxxscope token onto the token stream.
void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation);
@@ -632,12 +627,6 @@ private:
/// otherwise emits a diagnostic and returns true.
bool TryKeywordIdentFallback(bool DisableKeyword);
- /// TryIdentKeywordUpgrade - Convert the current identifier token back to
- /// its original kind and return true if it was disabled by
- /// TryKeywordIdentFallback(), otherwise return false. Use this to
- /// contextually enable keywords.
- bool TryIdentKeywordUpgrade();
-
/// \brief Get the TemplateIdAnnotation from the token.
TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok);
@@ -724,7 +713,7 @@ private:
/// returned.
bool ExpectAndConsume(tok::TokenKind ExpectedTok,
unsigned Diag = diag::err_expected,
- const char *DiagMsg = "");
+ StringRef DiagMsg = "");
/// \brief The parser expects a semicolon and, if present, will consume it.
///
@@ -1160,6 +1149,7 @@ private:
void ParseLateTemplatedFuncDef(LateParsedTemplate &LPT);
static void LateTemplateParserCallback(void *P, LateParsedTemplate &LPT);
+ static void LateTemplateParserCleanupCallback(void *P);
Sema::ParsingClassState
PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface);
@@ -1411,8 +1401,12 @@ private:
ExprResult ParseObjCBoolLiteral();
+ ExprResult ParseFoldExpression(ExprResult LHS, BalancedDelimiterTracker &T);
+
//===--------------------------------------------------------------------===//
// C++ Expressions
+ ExprResult tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOperand,
+ Token &Replacement);
ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
bool areTokensAdjacent(const Token &A, const Token &B);
@@ -1456,7 +1450,7 @@ private:
//===--------------------------------------------------------------------===//
// C++ 5.2.4: C++ Pseudo-Destructor Expressions
- ExprResult ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
+ ExprResult ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
tok::TokenKind OpKind,
CXXScopeSpec &SS,
ParsedType ObjectType);
@@ -1470,10 +1464,12 @@ private:
ExprResult ParseThrowExpression();
ExceptionSpecificationType tryParseExceptionSpecification(
+ bool Delayed,
SourceRange &SpecificationRange,
SmallVectorImpl<ParsedType> &DynamicExceptions,
SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
- ExprResult &NoexceptExpr);
+ ExprResult &NoexceptExpr,
+ CachedTokens *&ExceptionSpecTokens);
// EndLoc is filled with the location of the last token of the specification.
ExceptionSpecificationType ParseDynamicExceptionSpecification(
@@ -1556,10 +1552,10 @@ private:
ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
SourceLocation SuperLoc,
ParsedType ReceiverType,
- ExprArg ReceiverExpr);
+ Expr *ReceiverExpr);
ExprResult ParseAssignmentExprWithObjCMessageExprStart(
SourceLocation LBracloc, SourceLocation SuperLoc,
- ParsedType ReceiverType, ExprArg ReceiverExpr);
+ ParsedType ReceiverType, Expr *ReceiverExpr);
bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr);
//===--------------------------------------------------------------------===//
@@ -1723,11 +1719,9 @@ private:
bool ParsedForRangeDecl() { return !ColonLoc.isInvalid(); }
};
- DeclGroupPtrTy ParseDeclaration(StmtVector &Stmts,
- unsigned Context, SourceLocation &DeclEnd,
+ DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd,
ParsedAttributesWithRange &attrs);
- DeclGroupPtrTy ParseSimpleDeclaration(StmtVector &Stmts,
- unsigned Context,
+ DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
SourceLocation &DeclEnd,
ParsedAttributesWithRange &attrs,
bool RequireSemi,
@@ -1780,16 +1774,9 @@ private:
void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
Decl *TagDecl);
- struct FieldCallback {
- virtual void invoke(ParsingFieldDeclarator &Field) = 0;
- virtual ~FieldCallback() {}
-
- private:
- virtual void _anchor();
- };
- struct ObjCPropertyCallback;
-
- void ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Callback);
+ void ParseStructDeclaration(
+ ParsingDeclSpec &DS,
+ llvm::function_ref<void(ParsingFieldDeclarator &)> FieldsCallback);
bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
bool isTypeSpecifierQualifier();
@@ -2116,22 +2103,34 @@ private:
void ParseAvailabilityAttribute(IdentifierInfo &Availability,
SourceLocation AvailabilityLoc,
ParsedAttributes &attrs,
- SourceLocation *endLoc);
-
+ SourceLocation *endLoc,
+ IdentifierInfo *ScopeName,
+ SourceLocation ScopeLoc,
+ AttributeList::Syntax Syntax);
+
void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
SourceLocation ObjCBridgeRelatedLoc,
ParsedAttributes &attrs,
- SourceLocation *endLoc);
+ SourceLocation *endLoc,
+ IdentifierInfo *ScopeName,
+ SourceLocation ScopeLoc,
+ AttributeList::Syntax Syntax);
void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
SourceLocation AttrNameLoc,
ParsedAttributes &Attrs,
- SourceLocation *EndLoc);
+ SourceLocation *EndLoc,
+ IdentifierInfo *ScopeName,
+ SourceLocation ScopeLoc,
+ AttributeList::Syntax Syntax);
void ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
SourceLocation AttrNameLoc,
ParsedAttributes &Attrs,
- SourceLocation *EndLoc);
+ SourceLocation *EndLoc,
+ IdentifierInfo *ScopeName,
+ SourceLocation ScopeLoc,
+ AttributeList::Syntax Syntax);
void ParseTypeofSpecifier(DeclSpec &DS);
SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
@@ -2150,7 +2149,8 @@ private:
VirtSpecifiers::Specifier isCXX11VirtSpecifier() const {
return isCXX11VirtSpecifier(Tok);
}
- void ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS, bool IsInterface);
+ void ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS, bool IsInterface,
+ SourceLocation FriendLoc);
bool isCXX11FinalKeyword() const;
@@ -2194,8 +2194,21 @@ private:
void ParseDeclaratorInternal(Declarator &D,
DirectDeclParseFunction DirectDeclParser);
- void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true,
- bool CXX11AttributesAllowed = true,
+ enum AttrRequirements {
+ AR_NoAttributesParsed = 0, ///< No attributes are diagnosed.
+ AR_GNUAttributesParsedAndRejected = 1 << 0, ///< Diagnose GNU attributes.
+ AR_GNUAttributesParsed = 1 << 1,
+ AR_CXX11AttributesParsed = 1 << 2,
+ AR_DeclspecAttributesParsed = 1 << 3,
+ AR_AllAttributesParsed = AR_GNUAttributesParsed |
+ AR_CXX11AttributesParsed |
+ AR_DeclspecAttributesParsed,
+ AR_VendorAttributesParsed = AR_GNUAttributesParsed |
+ AR_DeclspecAttributesParsed
+ };
+
+ void ParseTypeQualifierListOpt(DeclSpec &DS,
+ unsigned AttrReqs = AR_AllAttributesParsed,
bool AtomicAllowed = true,
bool IdentifierRequired = false);
void ParseDirectDeclarator(Declarator &D);
@@ -2327,7 +2340,12 @@ private:
SmallVectorImpl<Expr *> &VarList,
bool AllowScopeSpecifier);
/// \brief Parses declarative or executable directive.
- StmtResult ParseOpenMPDeclarativeOrExecutableDirective();
+ ///
+ /// \param StandAloneAllowed true if allowed stand-alone directives,
+ /// false - otherwise
+ ///
+ StmtResult
+ ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed);
/// \brief Parses clause of kind \a CKind for directive of a kind \a Kind.
///
/// \param DKind Kind of current directive.
diff --git a/include/clang/Rewrite/Core/DeltaTree.h b/include/clang/Rewrite/Core/DeltaTree.h
index a6109bf901..248f2a07ea 100644
--- a/include/clang/Rewrite/Core/DeltaTree.h
+++ b/include/clang/Rewrite/Core/DeltaTree.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_REWRITE_DELTATREE_H
-#define CLANG_REWRITE_DELTATREE_H
+#ifndef LLVM_CLANG_REWRITE_CORE_DELTATREE_H
+#define LLVM_CLANG_REWRITE_CORE_DELTATREE_H
#include "llvm/Support/Compiler.h"
diff --git a/include/clang/Rewrite/Core/HTMLRewrite.h b/include/clang/Rewrite/Core/HTMLRewrite.h
index ec061dc7db..dafdf51ce6 100644
--- a/include/clang/Rewrite/Core/HTMLRewrite.h
+++ b/include/clang/Rewrite/Core/HTMLRewrite.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_HTMLREWRITER_H
-#define LLVM_CLANG_HTMLREWRITER_H
+#ifndef LLVM_CLANG_REWRITE_CORE_HTMLREWRITE_H
+#define LLVM_CLANG_REWRITE_CORE_HTMLREWRITE_H
#include "clang/Basic/SourceLocation.h"
#include <string>
diff --git a/include/clang/Rewrite/Core/RewriteRope.h b/include/clang/Rewrite/Core/RewriteRope.h
index f312aedc08..1c6f3eb952 100644
--- a/include/clang/Rewrite/Core/RewriteRope.h
+++ b/include/clang/Rewrite/Core/RewriteRope.h
@@ -11,9 +11,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_REWRITEROPE_H
-#define LLVM_CLANG_REWRITEROPE_H
+#ifndef LLVM_CLANG_REWRITE_CORE_REWRITEROPE_H
+#define LLVM_CLANG_REWRITE_CORE_REWRITEROPE_H
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
@@ -34,11 +35,10 @@ namespace clang {
unsigned RefCount;
char Data[1]; // Variable sized.
- void addRef() {
- ++RefCount;
- }
+ void Retain() { ++RefCount; }
- void dropRef() {
+ void Release() {
+ assert(RefCount > 0 && "Reference count is already zero.");
if (--RefCount == 0)
delete [] (char*)this;
}
@@ -57,39 +57,15 @@ namespace clang {
/// that both refer to the same underlying RopeRefCountString (just with
/// different offsets) which is a nice constant time operation.
struct RopePiece {
- RopeRefCountString *StrData;
+ llvm::IntrusiveRefCntPtr<RopeRefCountString> StrData;
unsigned StartOffs;
unsigned EndOffs;
RopePiece() : StrData(nullptr), StartOffs(0), EndOffs(0) {}
- RopePiece(RopeRefCountString *Str, unsigned Start, unsigned End)
- : StrData(Str), StartOffs(Start), EndOffs(End) {
- if (StrData)
- StrData->addRef();
- }
- RopePiece(const RopePiece &RP)
- : StrData(RP.StrData), StartOffs(RP.StartOffs), EndOffs(RP.EndOffs) {
- if (StrData)
- StrData->addRef();
- }
-
- ~RopePiece() {
- if (StrData)
- StrData->dropRef();
- }
-
- void operator=(const RopePiece &RHS) {
- if (StrData != RHS.StrData) {
- if (StrData)
- StrData->dropRef();
- StrData = RHS.StrData;
- if (StrData)
- StrData->addRef();
- }
- StartOffs = RHS.StartOffs;
- EndOffs = RHS.EndOffs;
- }
+ RopePiece(llvm::IntrusiveRefCntPtr<RopeRefCountString> Str, unsigned Start,
+ unsigned End)
+ : StrData(std::move(Str)), StartOffs(Start), EndOffs(End) {}
const char &operator[](unsigned Offset) const {
return StrData->Data[Offset+StartOffs];
@@ -191,7 +167,7 @@ class RewriteRope {
/// We allocate space for string data out of a buffer of size AllocChunkSize.
/// This keeps track of how much space is left.
- RopeRefCountString *AllocBuffer;
+ llvm::IntrusiveRefCntPtr<RopeRefCountString> AllocBuffer;
unsigned AllocOffs;
enum { AllocChunkSize = 4080 };
@@ -201,12 +177,6 @@ public:
: Chunks(RHS.Chunks), AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {
}
- ~RewriteRope() {
- // If we had an allocation buffer, drop our reference to it.
- if (AllocBuffer)
- AllocBuffer->dropRef();
- }
-
typedef RopePieceBTree::iterator iterator;
typedef RopePieceBTree::iterator const_iterator;
iterator begin() const { return Chunks.begin(); }
diff --git a/include/clang/Rewrite/Core/Rewriter.h b/include/clang/Rewrite/Core/Rewriter.h
index 7b22fb49bc..1ab7be6c53 100644
--- a/include/clang/Rewrite/Core/Rewriter.h
+++ b/include/clang/Rewrite/Core/Rewriter.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_REWRITER_H
-#define LLVM_CLANG_REWRITER_H
+#ifndef LLVM_CLANG_REWRITE_CORE_REWRITER_H
+#define LLVM_CLANG_REWRITE_CORE_REWRITER_H
#include "clang/Basic/SourceLocation.h"
#include "clang/Rewrite/Core/DeltaTree.h"
@@ -27,7 +27,6 @@ namespace clang {
class LangOptions;
class Rewriter;
class SourceManager;
- class Stmt;
/// RewriteBuffer - As code is rewritten, SourceBuffer's from the original
/// input with modifications get a new RewriteBuffer associated with them. The
@@ -245,11 +244,6 @@ public:
/// operation.
bool ReplaceText(SourceRange range, SourceRange replacementRange);
- /// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
- /// printer to generate the replacement code. This returns true if the input
- /// could not be rewritten, or false if successful.
- bool ReplaceStmt(Stmt *From, Stmt *To);
-
/// \brief Increase indentation for the lines between the given source range.
/// To determine what the indentation should be, 'parentIndent' is used
/// that should be at a source location with an indentation one degree
@@ -260,10 +254,6 @@ public:
parentIndent);
}
- /// ConvertToString converts statement 'From' to a string using the
- /// pretty printer.
- std::string ConvertToString(Stmt *From);
-
/// getEditBuffer - This is like getRewriteBufferFor, but always returns a
/// buffer, and allows you to write on it directly. This is useful if you
/// want efficient low-level access to apis for scribbling on one specific
diff --git a/include/clang/Rewrite/Core/TokenRewriter.h b/include/clang/Rewrite/Core/TokenRewriter.h
index c313b453d9..598477f318 100644
--- a/include/clang/Rewrite/Core/TokenRewriter.h
+++ b/include/clang/Rewrite/Core/TokenRewriter.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOKENREWRITER_H
-#define LLVM_CLANG_TOKENREWRITER_H
+#ifndef LLVM_CLANG_REWRITE_CORE_TOKENREWRITER_H
+#define LLVM_CLANG_REWRITE_CORE_TOKENREWRITER_H
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/Token.h"
diff --git a/include/clang/Rewrite/Frontend/ASTConsumers.h b/include/clang/Rewrite/Frontend/ASTConsumers.h
index 584af3fa18..8a822edfb7 100644
--- a/include/clang/Rewrite/Frontend/ASTConsumers.h
+++ b/include/clang/Rewrite/Frontend/ASTConsumers.h
@@ -11,10 +11,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef REWRITE_ASTCONSUMERS_H
-#define REWRITE_ASTCONSUMERS_H
+#ifndef LLVM_CLANG_REWRITE_FRONTEND_ASTCONSUMERS_H
+#define LLVM_CLANG_REWRITE_FRONTEND_ASTCONSUMERS_H
#include "clang/Basic/LLVM.h"
+
+#include <memory>
#include <string>
namespace clang {
@@ -26,23 +28,21 @@ class Preprocessor;
// ObjC rewriter: attempts to rewrite ObjC constructs into pure C code.
// This is considered experimental, and only works with Apple's ObjC runtime.
-ASTConsumer *CreateObjCRewriter(const std::string &InFile,
- raw_ostream *OS,
- DiagnosticsEngine &Diags,
- const LangOptions &LOpts,
- bool SilenceRewriteMacroWarning);
-ASTConsumer *CreateModernObjCRewriter(const std::string &InFile,
- raw_ostream *OS,
- DiagnosticsEngine &Diags,
- const LangOptions &LOpts,
- bool SilenceRewriteMacroWarning,
- bool LineInfo);
+std::unique_ptr<ASTConsumer>
+CreateObjCRewriter(const std::string &InFile, raw_ostream *OS,
+ DiagnosticsEngine &Diags, const LangOptions &LOpts,
+ bool SilenceRewriteMacroWarning);
+std::unique_ptr<ASTConsumer>
+CreateModernObjCRewriter(const std::string &InFile, raw_ostream *OS,
+ DiagnosticsEngine &Diags, const LangOptions &LOpts,
+ bool SilenceRewriteMacroWarning, bool LineInfo);
/// CreateHTMLPrinter - Create an AST consumer which rewrites source code to
/// HTML with syntax highlighting suitable for viewing in a web-browser.
-ASTConsumer *CreateHTMLPrinter(raw_ostream *OS, Preprocessor &PP,
- bool SyntaxHighlight = true,
- bool HighlightMacros = true);
+std::unique_ptr<ASTConsumer> CreateHTMLPrinter(raw_ostream *OS,
+ Preprocessor &PP,
+ bool SyntaxHighlight = true,
+ bool HighlightMacros = true);
} // end clang namespace
diff --git a/include/clang/Rewrite/Frontend/FixItRewriter.h b/include/clang/Rewrite/Frontend/FixItRewriter.h
index 3ad8f408af..5994172354 100644
--- a/include/clang/Rewrite/Frontend/FixItRewriter.h
+++ b/include/clang/Rewrite/Frontend/FixItRewriter.h
@@ -12,8 +12,8 @@
// then forwards any diagnostics to the adapted diagnostic client.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
-#define LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
+#ifndef LLVM_CLANG_REWRITE_FRONTEND_FIXITREWRITER_H
+#define LLVM_CLANG_REWRITE_FRONTEND_FIXITREWRITER_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
@@ -66,7 +66,7 @@ class FixItRewriter : public DiagnosticConsumer {
/// \brief The diagnostic client that performs the actual formatting
/// of error messages.
DiagnosticConsumer *Client;
- bool OwnsClient;
+ std::unique_ptr<DiagnosticConsumer> Owner;
/// \brief Turn an input path into an output path. NULL implies overwriting
/// the original.
@@ -125,4 +125,4 @@ public:
}
-#endif // LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
+#endif
diff --git a/include/clang/Rewrite/Frontend/FrontendActions.h b/include/clang/Rewrite/Frontend/FrontendActions.h
index fc79270748..c8ea8b2dd8 100644
--- a/include/clang/Rewrite/Frontend/FrontendActions.h
+++ b/include/clang/Rewrite/Frontend/FrontendActions.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_REWRITE_FRONTENDACTIONS_H
-#define LLVM_CLANG_REWRITE_FRONTENDACTIONS_H
+#ifndef LLVM_CLANG_REWRITE_FRONTEND_FRONTENDACTIONS_H
+#define LLVM_CLANG_REWRITE_FRONTEND_FRONTENDACTIONS_H
#include "clang/Frontend/FrontendAction.h"
@@ -22,8 +22,8 @@ class FixItOptions;
class HTMLPrintAction : public ASTFrontendAction {
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class FixItAction : public ASTFrontendAction {
@@ -31,8 +31,8 @@ protected:
std::unique_ptr<FixItRewriter> Rewriter;
std::unique_ptr<FixItOptions> FixItOpts;
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
bool BeginSourceFileAction(CompilerInstance &CI,
StringRef Filename) override;
@@ -59,8 +59,8 @@ protected:
class RewriteObjCAction : public ASTFrontendAction {
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class RewriteMacrosAction : public PreprocessorFrontendAction {
diff --git a/include/clang/Rewrite/Frontend/Rewriters.h b/include/clang/Rewrite/Frontend/Rewriters.h
index f5ade5ad35..3ad76dff82 100644
--- a/include/clang/Rewrite/Frontend/Rewriters.h
+++ b/include/clang/Rewrite/Frontend/Rewriters.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_REWRITE_REWRITERS_H
-#define LLVM_CLANG_REWRITE_REWRITERS_H
+#ifndef LLVM_CLANG_REWRITE_FRONTEND_REWRITERS_H
+#define LLVM_CLANG_REWRITE_FRONTEND_REWRITERS_H
#include "clang/Basic/LLVM.h"
diff --git a/include/clang/Sema/AnalysisBasedWarnings.h b/include/clang/Sema/AnalysisBasedWarnings.h
index 432c4e23a9..64dd2d36be 100644
--- a/include/clang/Sema/AnalysisBasedWarnings.h
+++ b/include/clang/Sema/AnalysisBasedWarnings.h
@@ -11,8 +11,8 @@
// that issues warnings based on dataflow-analysis.
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H
-#define LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H
+#ifndef LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H
+#define LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H
#include "llvm/ADT/DenseMap.h"
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 24e4cd41f9..c8e8625b0c 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_ATTRLIST_H
-#define LLVM_CLANG_SEMA_ATTRLIST_H
+#ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H
+#define LLVM_CLANG_SEMA_ATTRIBUTELIST_H
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/VersionTuple.h"
@@ -94,10 +94,10 @@ private:
/// The number of expression arguments this attribute has.
/// The expressions themselves are stored after the object.
- unsigned NumArgs : 16;
+ unsigned NumArgs : 15;
/// Corresponds to the Syntax enum.
- unsigned SyntaxUsed : 2;
+ unsigned SyntaxUsed : 3;
/// True if already diagnosed as invalid.
mutable unsigned Invalid : 1;
@@ -455,6 +455,7 @@ public:
bool hasCustomParsing() const;
unsigned getMinArgs() const;
unsigned getMaxArgs() const;
+ bool hasVariadicArg() const;
bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
bool diagnoseLangOpts(class Sema &S) const;
bool existsInTarget(const llvm::Triple &T) const;
@@ -826,7 +827,7 @@ enum AttributeDeclKind {
ExpectedVariableFunctionOrLabel,
ExpectedFieldOrGlobalVar,
ExpectedStruct,
- ExpectedVariableFunctionOrTag,
+ ExpectedVariableOrTypedef,
ExpectedTLSVar,
ExpectedVariableOrField,
ExpectedVariableFieldOrTag,
@@ -841,7 +842,8 @@ enum AttributeDeclKind {
ExpectedFunctionVariableOrClass,
ExpectedObjectiveCProtocol,
ExpectedFunctionGlobalVarMethodOrProperty,
- ExpectedStructOrTypedef
+ ExpectedStructOrTypedef,
+ ExpectedObjectiveCInterfaceOrProtocol
};
} // end namespace clang
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 8364dfc4b0..43fcde1abf 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -37,6 +37,7 @@
namespace clang {
class ASTContext;
+ class CXXRecordDecl;
class TypeLoc;
class LangOptions;
class DiagnosticsEngine;
@@ -141,6 +142,22 @@ public:
/// nested-name-specifier '::'.
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
+ /// \brief Turns this (empty) nested-name-specifier into '__super'
+ /// nested-name-specifier.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param RD The declaration of the class in which nested-name-specifier
+ /// appeared.
+ ///
+ /// \param SuperLoc The location of the '__super' keyword.
+ /// name.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
+ SourceLocation SuperLoc, SourceLocation ColonColonLoc);
+
/// \brief Make a new nested-name-specifier from incomplete source-location
/// information.
///
@@ -1159,7 +1176,7 @@ struct DeclaratorChunk {
unsigned TypeQuals : 3;
/// ExceptionSpecType - An ExceptionSpecificationType value.
- unsigned ExceptionSpecType : 3;
+ unsigned ExceptionSpecType : 4;
/// DeleteParams - If this is true, we need to delete[] Params.
unsigned DeleteParams : 1;
@@ -1200,6 +1217,11 @@ struct DeclaratorChunk {
/// If this is an invalid location, there is no volatile-qualifier.
unsigned VolatileQualifierLoc;
+ /// \brief The location of the restrict-qualifier, if any.
+ ///
+ /// If this is an invalid location, there is no restrict-qualifier.
+ unsigned RestrictQualifierLoc;
+
/// \brief The location of the 'mutable' qualifer in a lambda-declarator, if
/// any.
unsigned MutableLoc;
@@ -1221,6 +1243,10 @@ struct DeclaratorChunk {
/// \brief Pointer to the expression in the noexcept-specifier of this
/// function, if it has one.
Expr *NoexceptExpr;
+
+ /// \brief Pointer to the cached tokens for an exception-specification
+ /// that has not yet been parsed.
+ CachedTokens *ExceptionSpecTokens;
};
/// \brief If HasTrailingReturnType is true, this is the trailing return
@@ -1247,6 +1273,8 @@ struct DeclaratorChunk {
delete[] Params;
if (getExceptionSpecType() == EST_Dynamic)
delete[] Exceptions;
+ else if (getExceptionSpecType() == EST_Unparsed)
+ delete ExceptionSpecTokens;
}
/// isKNRPrototype - Return true if this is a K&R style identifier list,
@@ -1275,16 +1303,21 @@ struct DeclaratorChunk {
return SourceLocation::getFromRawEncoding(RefQualifierLoc);
}
- /// \brief Retrieve the location of the ref-qualifier, if any.
+ /// \brief Retrieve the location of the 'const' qualifier, if any.
SourceLocation getConstQualifierLoc() const {
return SourceLocation::getFromRawEncoding(ConstQualifierLoc);
}
- /// \brief Retrieve the location of the ref-qualifier, if any.
+ /// \brief Retrieve the location of the 'volatile' qualifier, if any.
SourceLocation getVolatileQualifierLoc() const {
return SourceLocation::getFromRawEncoding(VolatileQualifierLoc);
}
+ /// \brief Retrieve the location of the 'restrict' qualifier, if any.
+ SourceLocation getRestrictQualifierLoc() const {
+ return SourceLocation::getFromRawEncoding(RestrictQualifierLoc);
+ }
+
/// \brief Retrieve the location of the 'mutable' qualifier, if any.
SourceLocation getMutableLoc() const {
return SourceLocation::getFromRawEncoding(MutableLoc);
@@ -1429,6 +1462,7 @@ struct DeclaratorChunk {
SourceLocation RefQualifierLoc,
SourceLocation ConstQualifierLoc,
SourceLocation VolatileQualifierLoc,
+ SourceLocation RestrictQualifierLoc,
SourceLocation MutableLoc,
ExceptionSpecificationType ESpecType,
SourceLocation ESpecLoc,
@@ -1436,6 +1470,7 @@ struct DeclaratorChunk {
SourceRange *ExceptionRanges,
unsigned NumExceptions,
Expr *NoexceptExpr,
+ CachedTokens *ExceptionSpecTokens,
SourceLocation LocalRangeBegin,
SourceLocation LocalRangeEnd,
Declarator &TheDeclarator,
diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h
index 85551f8db0..7fd6779f34 100644
--- a/include/clang/Sema/DelayedDiagnostic.h
+++ b/include/clang/Sema/DelayedDiagnostic.h
@@ -19,8 +19,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H
-#define LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H
+#ifndef LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H
+#define LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H
#include "clang/Sema/Sema.h"
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h
index 325abdf8e5..c0ef7121a6 100644
--- a/include/clang/Sema/ExternalSemaSource.h
+++ b/include/clang/Sema/ExternalSemaSource.h
@@ -10,8 +10,8 @@
// This file defines the ExternalSemaSource interface.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H
-#define LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H
+#ifndef LLVM_CLANG_SEMA_EXTERNALSEMASOURCE_H
+#define LLVM_CLANG_SEMA_EXTERNALSEMASOURCE_H
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/Type.h"
@@ -20,6 +20,10 @@
#include "llvm/ADT/MapVector.h"
#include <utility>
+namespace llvm {
+template <class T, unsigned n> class SmallSetVector;
+}
+
namespace clang {
class CXXConstructorDecl;
@@ -132,6 +136,15 @@ public:
/// introduce the same declarations repeatedly.
virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {}
+ /// \brief Read the set of potentially unused typedefs known to the source.
+ ///
+ /// The external source should append its own potentially unused local
+ /// typedefs to the given vector of declarations. Note that this routine may
+ /// be invoked multiple times; the external source should take care not to
+ /// introduce the same declarations repeatedly.
+ virtual void ReadUnusedLocalTypedefNameCandidates(
+ llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {};
+
/// \brief Read the set of locally-scoped external declarations known to the
/// external Sema source.
///
diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h
index b2404bc14b..a07834f956 100644
--- a/include/clang/Sema/IdentifierResolver.h
+++ b/include/clang/Sema/IdentifierResolver.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
-#define LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
+#ifndef LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
+#define LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/SmallVector.h"
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index 1b59d2d921..9f342b2407 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -663,22 +663,25 @@ public:
SK_QualificationConversionXValue,
/// \brief Perform a qualification conversion, producing an lvalue.
SK_QualificationConversionLValue,
+ /// \brief Perform a conversion adding _Atomic to a type.
+ SK_AtomicConversion,
/// \brief Perform a load from a glvalue, producing an rvalue.
SK_LValueToRValue,
/// \brief Perform an implicit conversion sequence.
SK_ConversionSequence,
/// \brief Perform an implicit conversion sequence without narrowing.
SK_ConversionSequenceNoNarrowing,
- /// \brief Perform list-initialization without a constructor
+ /// \brief Perform list-initialization without a constructor.
SK_ListInitialization,
- /// \brief Perform list-initialization with a constructor.
- SK_ListConstructorCall,
/// \brief Unwrap the single-element initializer list for a reference.
SK_UnwrapInitList,
/// \brief Rewrap the single-element initializer list for a reference.
SK_RewrapInitList,
/// \brief Perform initialization via a constructor.
SK_ConstructorInitialization,
+ /// \brief Perform initialization via a constructor, taking arguments from
+ /// a single InitListExpr.
+ SK_ConstructorInitializationFromList,
/// \brief Zero-initialize the object
SK_ZeroInitialization,
/// \brief C assignment
@@ -702,6 +705,9 @@ public:
SK_ProduceObjCObject,
/// \brief Construct a std::initializer_list from an initializer list.
SK_StdInitializerList,
+ /// \brief Perform initialization via a constructor taking a single
+ /// std::initializer_list argument.
+ SK_StdInitializerListConstructorCall,
/// \brief Initialize an OpenCL sampler from an integer.
SK_OCLSamplerInit,
/// \brief Passing zero to a function where OpenCL event_t is expected.
@@ -995,7 +1001,11 @@ public:
/// given type.
void AddQualificationConversionStep(QualType Ty,
ExprValueKind Category);
-
+
+ /// \brief Add a new step that performs conversion from non-atomic to atomic
+ /// type.
+ void AddAtomicConversionStep(QualType Ty);
+
/// \brief Add a new step that performs a load of the given type.
///
/// Although the term "LValueToRValue" is conventional, this applies to both
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
index 00cc164d96..1c6c7bbbd9 100644
--- a/include/clang/Sema/Lookup.h
+++ b/include/clang/Sema/Lookup.h
@@ -132,7 +132,7 @@ public:
: ResultKind(NotFound),
Paths(nullptr),
NamingClass(nullptr),
- SemaRef(SemaRef),
+ SemaPtr(&SemaRef),
NameInfo(NameInfo),
LookupKind(LookupKind),
IDNS(0),
@@ -154,7 +154,7 @@ public:
: ResultKind(NotFound),
Paths(nullptr),
NamingClass(nullptr),
- SemaRef(SemaRef),
+ SemaPtr(&SemaRef),
NameInfo(Name, NameLoc),
LookupKind(LookupKind),
IDNS(0),
@@ -174,7 +174,7 @@ public:
: ResultKind(NotFound),
Paths(nullptr),
NamingClass(nullptr),
- SemaRef(Other.SemaRef),
+ SemaPtr(Other.SemaPtr),
NameInfo(Other.NameInfo),
LookupKind(Other.LookupKind),
IDNS(Other.IDNS),
@@ -305,7 +305,7 @@ public:
if (!D->isInIdentifierNamespace(IDNS))
return nullptr;
- if (isHiddenDeclarationVisible() || isVisible(SemaRef, D))
+ if (isHiddenDeclarationVisible() || isVisible(getSema(), D))
return D;
return getAcceptableDeclSlow(D);
@@ -424,13 +424,20 @@ public:
Paths = nullptr;
}
} else {
- AmbiguityKind SavedAK = Ambiguity;
+ AmbiguityKind SavedAK;
+ bool WasAmbiguous = false;
+ if (ResultKind == Ambiguous) {
+ SavedAK = Ambiguity;
+ WasAmbiguous = true;
+ }
ResultKind = Found;
resolveKind();
// If we didn't make the lookup unambiguous, restore the old
// ambiguity kind.
if (ResultKind == Ambiguous) {
+ (void)WasAmbiguous;
+ assert(WasAmbiguous);
Ambiguity = SavedAK;
} else if (Paths) {
deletePaths(Paths);
@@ -544,7 +551,7 @@ public:
/// \brief Get the Sema object that this lookup result is searching
/// with.
- Sema &getSema() const { return SemaRef; }
+ Sema &getSema() const { return *SemaPtr; }
/// A class for iterating through a result set and possibly
/// filtering out results. The results returned are possibly
@@ -623,9 +630,9 @@ public:
private:
void diagnose() {
if (isAmbiguous())
- SemaRef.DiagnoseAmbiguousLookup(*this);
- else if (isClassLookup() && SemaRef.getLangOpts().AccessControl)
- SemaRef.CheckLookupAccess(*this);
+ getSema().DiagnoseAmbiguousLookup(*this);
+ else if (isClassLookup() && getSema().getLangOpts().AccessControl)
+ getSema().CheckLookupAccess(*this);
}
void setAmbiguous(AmbiguityKind AK) {
@@ -657,7 +664,7 @@ private:
QualType BaseObjectType;
// Parameters.
- Sema &SemaRef;
+ Sema *SemaPtr;
DeclarationNameInfo NameInfo;
SourceRange NameContextRange;
Sema::LookupNameKind LookupKind;
diff --git a/include/clang/Sema/LoopHint.h b/include/clang/Sema/LoopHint.h
index 928cfb1ee8..c8b2ee845e 100644
--- a/include/clang/Sema/LoopHint.h
+++ b/include/clang/Sema/LoopHint.h
@@ -17,13 +17,27 @@
namespace clang {
-/// \brief Loop hint specified by a pragma loop directive.
+/// \brief Loop optimization hint for loop and unroll pragmas.
struct LoopHint {
+ // Source range of the directive.
SourceRange Range;
- Expr *ValueExpr;
- IdentifierLoc *LoopLoc;
- IdentifierLoc *ValueLoc;
+ // Identifier corresponding to the name of the pragma. "loop" for
+ // "#pragma clang loop" directives and "unroll" for "#pragma unroll"
+ // hints.
+ IdentifierLoc *PragmaNameLoc;
+ // Name of the loop hint. Examples: "unroll", "vectorize". In the
+ // "#pragma unroll" and "#pragma nounroll" cases, this is identical to
+ // PragmaNameLoc.
IdentifierLoc *OptionLoc;
+ // Identifier for the hint state argument. If null, then the state is
+ // default value such as for "#pragma unroll".
+ IdentifierLoc *StateLoc;
+ // Expression for the hint argument if it exists, null otherwise.
+ Expr *ValueExpr;
+
+ LoopHint()
+ : PragmaNameLoc(nullptr), OptionLoc(nullptr), StateLoc(nullptr),
+ ValueExpr(nullptr) {}
};
} // end namespace clang
diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h
index 7860b6da06..f06d19629a 100644
--- a/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -10,8 +10,8 @@
// This file defines ExternalSemaSource interface, dispatching to all clients
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
-#define LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
+#ifndef LLVM_CLANG_SEMA_MULTIPLEXEXTERNALSEMASOURCE_H
+#define LLVM_CLANG_SEMA_MULTIPLEXEXTERNALSEMASOURCE_H
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/Sema/Weak.h"
@@ -282,6 +282,15 @@ public:
/// introduce the same declarations repeatedly.
void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl*> &Decls) override;
+ /// \brief Read the set of potentially unused typedefs known to the source.
+ ///
+ /// The external source should append its own potentially unused local
+ /// typedefs to the given vector of declarations. Note that this routine may
+ /// be invoked multiple times; the external source should take care not to
+ /// introduce the same declarations repeatedly.
+ void ReadUnusedLocalTypedefNameCandidates(
+ llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override;
+
/// \brief Read the set of locally-scoped extern "C" declarations known to the
/// external Sema source.
///
@@ -368,4 +377,4 @@ public:
} // end namespace clang
-#endif // LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
+#endif
diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h
index 20033567df..956e0882c5 100644
--- a/include/clang/Sema/ObjCMethodList.h
+++ b/include/clang/Sema/ObjCMethodList.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_OBJC_METHOD_LIST_H
-#define LLVM_CLANG_SEMA_OBJC_METHOD_LIST_H
+#ifndef LLVM_CLANG_SEMA_OBJCMETHODLIST_H
+#define LLVM_CLANG_SEMA_OBJCMETHODLIST_H
#include "llvm/ADT/PointerIntPair.h"
@@ -23,12 +23,14 @@ class ObjCMethodDecl;
/// ObjCMethodList - a linked list of methods with different signatures.
struct ObjCMethodList {
ObjCMethodDecl *Method;
+ /// \brief count of methods with same signature.
+ unsigned Count;
/// \brief The next list object and 2 bits for extra info.
llvm::PointerIntPair<ObjCMethodList *, 2> NextAndExtraBits;
- ObjCMethodList() : Method(nullptr) { }
- ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C)
- : Method(M), NextAndExtraBits(C, 0) { }
+ ObjCMethodList() : Method(nullptr), Count(0) { }
+ ObjCMethodList(ObjCMethodDecl *M, unsigned count, ObjCMethodList *C)
+ : Method(M), Count(count), NextAndExtraBits(C, 0) { }
ObjCMethodList *getNext() const { return NextAndExtraBits.getPointer(); }
unsigned getBits() const { return NextAndExtraBits.getInt(); }
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 7b9f95d635..41dcf974e5 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -25,6 +25,7 @@
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Allocator.h"
namespace clang {
@@ -85,21 +86,6 @@ namespace clang {
ICK_Num_Conversion_Kinds ///< The number of conversion kinds
};
- /// ImplicitConversionCategory - The category of an implicit
- /// conversion kind. The enumerator values match with Table 9 of
- /// (C++ 13.3.3.1.1) and are listed such that better conversion
- /// categories have smaller values.
- enum ImplicitConversionCategory {
- ICC_Identity = 0, ///< Identity
- ICC_Lvalue_Transformation, ///< Lvalue transformation
- ICC_Qualification_Adjustment, ///< Qualification adjustment
- ICC_Promotion, ///< Promotion
- ICC_Conversion ///< Conversion
- };
-
- ImplicitConversionCategory
- GetConversionCategory(ImplicitConversionKind Kind);
-
/// ImplicitConversionRank - The rank of an implicit conversion
/// kind. The enumerator values match with Table 9 of (C++
/// 13.3.3.1.1) and are listed such that better conversion ranks
@@ -339,7 +325,6 @@ namespace clang {
enum FailureKind {
no_conversion,
unrelated_class,
- suppressed_user,
bad_qualifiers,
lvalue_ref_to_rvalue,
rvalue_ref_to_lvalue
@@ -719,7 +704,8 @@ namespace clang {
CandidateSetKind Kind;
unsigned NumInlineSequences;
- char InlineSpace[16 * sizeof(ImplicitConversionSequence)];
+ llvm::AlignedCharArray<llvm::AlignOf<ImplicitConversionSequence>::Alignment,
+ 16 * sizeof(ImplicitConversionSequence)> InlineSpace;
OverloadCandidateSet(const OverloadCandidateSet &) LLVM_DELETED_FUNCTION;
void operator=(const OverloadCandidateSet &) LLVM_DELETED_FUNCTION;
@@ -736,8 +722,8 @@ namespace clang {
/// \brief Determine when this overload candidate will be new to the
/// overload set.
- bool isNewCandidate(Decl *F) {
- return Functions.insert(F->getCanonicalDecl());
+ bool isNewCandidate(Decl *F) {
+ return Functions.insert(F->getCanonicalDecl()).second;
}
/// \brief Clear out all of the candidates.
@@ -760,7 +746,7 @@ namespace clang {
// available.
if (NumConversions + NumInlineSequences <= 16) {
ImplicitConversionSequence *I =
- (ImplicitConversionSequence*)InlineSpace;
+ (ImplicitConversionSequence *)InlineSpace.buffer;
C.Conversions = &I[NumInlineSequences];
NumInlineSequences += NumConversions;
} else {
diff --git a/include/clang/Sema/PrettyDeclStackTrace.h b/include/clang/Sema/PrettyDeclStackTrace.h
index c0c772dc59..ca22e640de 100644
--- a/include/clang/Sema/PrettyDeclStackTrace.h
+++ b/include/clang/Sema/PrettyDeclStackTrace.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_PRETTY_DECL_STACK_TRACE_H
-#define LLVM_CLANG_SEMA_PRETTY_DECL_STACK_TRACE_H
+#ifndef LLVM_CLANG_SEMA_PRETTYDECLSTACKTRACE_H
+#define LLVM_CLANG_SEMA_PRETTYDECLSTACKTRACE_H
#include "clang/Basic/SourceLocation.h"
#include "llvm/Support/PrettyStackTrace.h"
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
index 27067a1119..97e447d1fd 100644
--- a/include/clang/Sema/Scope.h
+++ b/include/clang/Sema/Scope.h
@@ -300,6 +300,9 @@ public:
return ErrorTrap.hasUnrecoverableErrorOccurred();
}
+ /// isFunctionScope() - Return true if this scope is a function scope.
+ bool isFunctionScope() const { return (getFlags() & Scope::FnScope); }
+
/// isClassScope - Return true if this scope is a class/struct/union scope.
bool isClassScope() const {
return (getFlags() & Scope::ClassScope);
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index 63427aaa4a..d63b734a8d 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -12,9 +12,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H
-#define LLVM_CLANG_SEMA_SCOPE_INFO_H
+#ifndef LLVM_CLANG_SEMA_SCOPEINFO_H
+#define LLVM_CLANG_SEMA_SCOPEINFO_H
+#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Basic/CapturedStmt.h"
#include "clang/Basic/PartialDiagnostic.h"
@@ -41,8 +42,6 @@ class SwitchStmt;
class TemplateTypeParmDecl;
class TemplateParameterList;
class VarDecl;
-class DeclRefExpr;
-class MemberExpr;
class ObjCIvarRefExpr;
class ObjCPropertyRefExpr;
class ObjCMessageExpr;
@@ -145,6 +144,10 @@ public:
/// current function scope. These diagnostics are vetted for reachability
/// prior to being emitted.
SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
+
+ /// \brief A list of parameters which have the nonnull attribute and are
+ /// modified in the function.
+ llvm::SmallPtrSet<const ParmVarDecl*, 8> ModifiedNonNullParams;
public:
/// Represents a simple identification of a weak object.
@@ -187,8 +190,6 @@ public:
/// Used to find the proper base profile for a given base expression.
static BaseInfoTy getBaseInfo(const Expr *BaseE);
- // For use in DenseMap.
- friend class DenseMapInfo;
inline WeakObjectProfileTy();
static inline WeakObjectProfileTy getSentinel();
@@ -381,7 +382,7 @@ public:
/// capture (if this is a capture and not an init-capture). The expression
/// is only required if we are capturing ByVal and the variable's type has
/// a non-trivial copy constructor.
- llvm::PointerIntPair<Expr*, 2, CaptureKind> InitExprAndCaptureKind;
+ llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind;
/// \brief The source location at which the first capture occurred.
SourceLocation Loc;
@@ -413,10 +414,11 @@ public:
return InitExprAndCaptureKind.getInt() == Cap_This;
}
bool isVariableCapture() const {
- return InitExprAndCaptureKind.getInt() != Cap_This;
+ return InitExprAndCaptureKind.getInt() != Cap_This && !isVLATypeCapture();
}
bool isCopyCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
+ return InitExprAndCaptureKind.getInt() == Cap_ByCopy &&
+ !isVLATypeCapture();
}
bool isReferenceCapture() const {
return InitExprAndCaptureKind.getInt() == Cap_ByRef;
@@ -424,7 +426,11 @@ public:
bool isBlockCapture() const {
return InitExprAndCaptureKind.getInt() == Cap_Block;
}
- bool isNested() { return VarAndNested.getInt(); }
+ bool isVLATypeCapture() const {
+ return InitExprAndCaptureKind.getInt() == Cap_ByCopy &&
+ getVariable() == nullptr;
+ }
+ bool isNested() const { return VarAndNested.getInt(); }
VarDecl *getVariable() const {
return VarAndNested.getPointer();
@@ -443,7 +449,8 @@ public:
QualType getCaptureType() const { return CaptureType; }
Expr *getInitExpr() const {
- return InitExprAndCaptureKind.getPointer();
+ assert(!isVLATypeCapture() && "no init expression for type capture");
+ return static_cast<Expr *>(InitExprAndCaptureKind.getPointer());
}
};
@@ -478,6 +485,13 @@ public:
CaptureMap[Var] = Captures.size();
}
+ void addVLATypeCapture(SourceLocation Loc, QualType CaptureType) {
+ Captures.push_back(Capture(/*Var*/ nullptr, /*isBlock*/ false,
+ /*isByref*/ false, /*isNested*/ false, Loc,
+ /*EllipsisLoc*/ SourceLocation(), CaptureType,
+ /*Cpy*/ nullptr));
+ }
+
void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
Expr *Cpy);
@@ -494,7 +508,10 @@ public:
bool isCaptured(VarDecl *Var) const {
return CaptureMap.count(Var);
}
-
+
+ /// \brief Determine whether the given variable-array type has been captured.
+ bool isVLATypeCaptured(const VariableArrayType *VAT) const;
+
/// \brief Retrieve the capture of the given variable, if it has been
/// captured already.
Capture &getCapture(VarDecl *Var) {
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index c771ff9388..8b13b9d32a 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -129,7 +129,6 @@ namespace clang {
class ModuleLoader;
class MultiLevelTemplateArgumentList;
class NamedDecl;
- class NonNullAttr;
class ObjCCategoryDecl;
class ObjCCategoryImplDecl;
class ObjCCompatibleAliasDecl;
@@ -169,6 +168,7 @@ namespace clang {
class TypedefDecl;
class TypedefNameDecl;
class TypeLoc;
+ class TypoCorrectionConsumer;
class UnqualifiedId;
class UnresolvedLookupExpr;
class UnresolvedMemberExpr;
@@ -330,6 +330,10 @@ public:
PragmaStack<StringLiteral *> ConstSegStack;
PragmaStack<StringLiteral *> CodeSegStack;
+ /// Last section used with #pragma init_seg.
+ StringLiteral *CurInitSeg;
+ SourceLocation CurInitSegLoc;
+
/// VisContext - Manages the stack for \#pragma GCC visibility.
void *VisContext; // Really a "PragmaVisStack*"
@@ -386,6 +390,10 @@ public:
/// \brief Set containing all declared private fields that are not used.
NamedDeclSetType UnusedPrivateFields;
+ /// \brief Set containing all typedefs that are likely unused.
+ llvm::SmallSetVector<const TypedefNameDecl *, 4>
+ UnusedLocalTypedefNameCandidates;
+
typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy;
/// PureVirtualClassDiagSet - a set of class declarations which we have
@@ -473,11 +481,16 @@ public:
/// \brief Callback to the parser to parse templated functions when needed.
typedef void LateTemplateParserCB(void *P, LateParsedTemplate &LPT);
+ typedef void LateTemplateParserCleanupCB(void *P);
LateTemplateParserCB *LateTemplateParser;
+ LateTemplateParserCleanupCB *LateTemplateParserCleanup;
void *OpaqueParser;
- void SetLateTemplateParser(LateTemplateParserCB *LTP, void *P) {
+ void SetLateTemplateParser(LateTemplateParserCB *LTP,
+ LateTemplateParserCleanupCB *LTPCleanup,
+ void *P) {
LateTemplateParser = LTP;
+ LateTemplateParserCleanup = LTPCleanup;
OpaqueParser = P;
}
@@ -680,7 +693,10 @@ public:
/// \brief will hold 'respondsToSelector:'
Selector RespondsToSelectorSel;
-
+
+ /// \brief counter for internal MS Asm label names.
+ unsigned MSAsmLabelNameCounter;
+
/// A flag to remember whether the implicit forms of operator new and delete
/// have been declared.
bool GlobalNewDeleteDeclared;
@@ -741,6 +757,10 @@ public:
/// this expression evaluation context.
unsigned NumCleanupObjects;
+ /// \brief The number of typos encountered during this expression evaluation
+ /// context (i.e. the number of TypoExprs created).
+ unsigned NumTypos;
+
llvm::SmallPtrSet<Expr*, 2> SavedMaybeODRUseExprs;
/// \brief The lambdas that are present within this context, if it
@@ -774,6 +794,7 @@ public:
bool IsDecltype)
: Context(Context), ParentNeedsCleanups(ParentNeedsCleanups),
IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects),
+ NumTypos(0),
ManglingContextDecl(ManglingContextDecl), MangleNumbering() { }
/// \brief Retrieve the mangling numbering context, used to consistently
@@ -1033,6 +1054,8 @@ public:
/// \brief Retrieve the module loader associated with the preprocessor.
ModuleLoader &getModuleLoader() const;
+ void emitAndClearUnusedLocalTypedefWarnings();
+
void ActOnEndOfTranslationUnit();
void CheckDelegatingCtorCycles();
@@ -1177,7 +1200,7 @@ public:
const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc,
const FunctionProtoType *FPT);
void UpdateExceptionSpec(FunctionDecl *FD,
- const FunctionProtoType::ExtProtoInfo &EPI);
+ const FunctionProtoType::ExceptionSpecInfo &ESI);
bool CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range);
bool CheckDistantExceptionSpec(QualType T);
bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New);
@@ -1539,13 +1562,11 @@ public:
/// expression.
///
/// \param CCC The correction callback, if typo correction is desired.
- NameClassification ClassifyName(Scope *S,
- CXXScopeSpec &SS,
- IdentifierInfo *&Name,
- SourceLocation NameLoc,
- const Token &NextToken,
- bool IsAddressOfOperand,
- CorrectionCandidateCallback *CCC = nullptr);
+ NameClassification
+ ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name,
+ SourceLocation NameLoc, const Token &NextToken,
+ bool IsAddressOfOperand,
+ std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr);
Decl *ActOnDeclarator(Scope *S, Declarator &D);
@@ -1621,7 +1642,7 @@ public:
void ActOnParamUnparsedDefaultArgument(Decl *param,
SourceLocation EqualLoc,
SourceLocation ArgLoc);
- void ActOnParamDefaultArgumentError(Decl *param);
+ void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc);
bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
SourceLocation EqualLoc);
@@ -2558,9 +2579,30 @@ public:
bool ConstThis,
bool VolatileThis);
+ typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator;
+ typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)>
+ TypoRecoveryCallback;
+
private:
bool CppLookupName(LookupResult &R, Scope *S);
+ struct TypoExprState {
+ std::unique_ptr<TypoCorrectionConsumer> Consumer;
+ TypoDiagnosticGenerator DiagHandler;
+ TypoRecoveryCallback RecoveryHandler;
+ TypoExprState();
+ TypoExprState(TypoExprState&& other) LLVM_NOEXCEPT;
+ TypoExprState& operator=(TypoExprState&& other) LLVM_NOEXCEPT;
+ };
+
+ /// \brief The set of unhandled TypoExprs and their associated state.
+ llvm::MapVector<TypoExpr *, TypoExprState> DelayedTypos;
+
+ /// \brief Creates a new TypoExpr AST node.
+ TypoExpr *createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC,
+ TypoDiagnosticGenerator TDG,
+ TypoRecoveryCallback TRC);
+
// \brief The set of known/encountered (unique, canonicalized) NamespaceDecls.
//
// The boolean value will be true to indicate that the namespace was loaded
@@ -2571,7 +2613,24 @@ private:
/// source.
bool LoadedExternalKnownNamespaces;
+ /// \brief Helper for CorrectTypo and CorrectTypoDelayed used to create and
+ /// populate a new TypoCorrectionConsumer. Returns nullptr if typo correction
+ /// should be skipped entirely.
+ std::unique_ptr<TypoCorrectionConsumer>
+ makeTypoCorrectionConsumer(const DeclarationNameInfo &Typo,
+ Sema::LookupNameKind LookupKind, Scope *S,
+ CXXScopeSpec *SS,
+ std::unique_ptr<CorrectionCandidateCallback> CCC,
+ DeclContext *MemberContext, bool EnteringContext,
+ const ObjCObjectPointerType *OPT,
+ bool ErrorRecovery, bool &IsUnqualifiedLookup);
+
public:
+ const TypoExprState &getTypoExprState(TypoExpr *TE) const;
+
+ /// \brief Clears the state of the given TypoExpr.
+ void clearDelayedTypo(TypoExpr *TE);
+
/// \brief Look up a name, looking for a single declaration. Return
/// null if the results were absent, ambiguous, or overloaded.
///
@@ -2592,6 +2651,7 @@ public:
ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc,
RedeclarationKind Redecl
= NotForRedeclaration);
+ bool LookupInSuper(LookupResult &R, CXXRecordDecl *Class);
void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
QualType T1, QualType T2,
@@ -2641,13 +2701,35 @@ public:
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
Sema::LookupNameKind LookupKind,
Scope *S, CXXScopeSpec *SS,
- CorrectionCandidateCallback &CCC,
+ std::unique_ptr<CorrectionCandidateCallback> CCC,
CorrectTypoKind Mode,
DeclContext *MemberContext = nullptr,
bool EnteringContext = false,
const ObjCObjectPointerType *OPT = nullptr,
bool RecordFailure = true);
+ TypoExpr *CorrectTypoDelayed(const DeclarationNameInfo &Typo,
+ Sema::LookupNameKind LookupKind, Scope *S,
+ CXXScopeSpec *SS,
+ std::unique_ptr<CorrectionCandidateCallback> CCC,
+ TypoDiagnosticGenerator TDG,
+ TypoRecoveryCallback TRC, CorrectTypoKind Mode,
+ DeclContext *MemberContext = nullptr,
+ bool EnteringContext = false,
+ const ObjCObjectPointerType *OPT = nullptr);
+
+ ExprResult
+ CorrectDelayedTyposInExpr(Expr *E,
+ llvm::function_ref<ExprResult(Expr *)> Filter =
+ [](Expr *E) -> ExprResult { return E; });
+
+ ExprResult
+ CorrectDelayedTyposInExpr(ExprResult ER,
+ llvm::function_ref<ExprResult(Expr *)> Filter =
+ [](Expr *E) -> ExprResult { return E; }) {
+ return ER.isInvalid() ? ER : CorrectDelayedTyposInExpr(ER.get(), Filter);
+ }
+
void diagnoseTypo(const TypoCorrection &Correction,
const PartialDiagnostic &TypoDiag,
bool ErrorRecovery = true);
@@ -2690,6 +2772,12 @@ public:
void checkUnusedDeclAttributes(Declarator &D);
+ /// Determine if type T is a valid subject for a nonnull and similar
+ /// attributes. By default, we look through references (the behavior used by
+ /// nonnull), but if the second parameter is true, then we treat a reference
+ /// type as valid.
+ bool isValidPointerAttrType(QualType T, bool RefOkay = false);
+
bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
const FunctionDecl *FD = nullptr);
@@ -2868,6 +2956,24 @@ private:
bool receiverIdOrClass,
bool warn, bool instance);
+public:
+ /// \brief - Returns instance or factory methods in global method pool for
+ /// given selector. If no such method or only one method found, function returns
+ /// false; otherwise, it returns true
+ bool CollectMultipleMethodsInGlobalPool(Selector Sel,
+ SmallVectorImpl<ObjCMethodDecl*>& Methods,
+ bool instance);
+
+ bool AreMultipleMethodsInGlobalPool(Selector Sel,
+ bool instance);
+
+private:
+ /// \brief - Returns a selector which best matches given argument list or
+ /// nullptr if none could be found
+ ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args,
+ bool IsInstance);
+
+
/// \brief Record the typo correction failure and return an empty correction.
TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc,
bool RecordFailure = true,
@@ -2933,11 +3039,6 @@ public:
public:
FullExprArg(Sema &actions) : E(nullptr) { }
- // FIXME: The const_cast here is ugly. RValue references would make this
- // much nicer (or we could duplicate a bunch of the move semantics
- // emulation code from Ownership.h).
- FullExprArg(const FullExprArg& Other) : E(Other.E) {}
-
ExprResult release() {
return E;
}
@@ -3124,6 +3225,9 @@ public:
ArrayRef<StringRef> Clobbers,
ArrayRef<Expr*> Exprs,
SourceLocation EndLoc);
+ LabelDecl *GetOrCreateMSAsmLabel(StringRef ExternalLabelName,
+ SourceLocation Location,
+ bool AlwaysCreate);
VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType,
SourceLocation StartLoc,
@@ -3183,6 +3287,7 @@ public:
/// DiagnoseUnusedExprResult - If the statement passed in is an expression
/// whose result is unused, warn.
void DiagnoseUnusedExprResult(const Stmt *S);
+ void DiagnoseUnusedNestedTypedefs(const RecordDecl *D);
void DiagnoseUnusedDecl(const NamedDecl *ND);
/// Emit \p DiagID if statement located on \p StmtLoc has a suspicious null
@@ -3224,8 +3329,6 @@ public:
const ObjCPropertyDecl *ObjCProperty,
bool ObjCPropertyAccess);
- void HandleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
-
bool makeUnavailableInSystemHeader(SourceLocation loc,
StringRef message);
@@ -3267,7 +3370,8 @@ public:
// needs to be delayed for some constant variables when we build one of the
// named expressions.
void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse);
- void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func);
+ void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
+ bool OdrUse = true);
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var);
void MarkDeclRefReferenced(DeclRefExpr *E);
void MarkMemberReferenced(MemberExpr *E);
@@ -3355,12 +3459,11 @@ public:
// Primary Expressions.
SourceRange getExprRange(Expr *E) const;
- ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- UnqualifiedId &Id,
- bool HasTrailingLParen, bool IsAddressOfOperand,
- CorrectionCandidateCallback *CCC = nullptr,
- bool IsInlineAsmIdentifier = false);
+ ExprResult ActOnIdExpression(
+ Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
+ UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand,
+ std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr,
+ bool IsInlineAsmIdentifier = false, Token *KeywordReplacement = nullptr);
void DecomposeUnqualifiedId(const UnqualifiedId &Id,
TemplateArgumentListInfo &Buffer,
@@ -3369,9 +3472,9 @@ public:
bool
DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
- CorrectionCandidateCallback &CCC,
+ std::unique_ptr<CorrectionCandidateCallback> CCC,
TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr,
- ArrayRef<Expr *> Args = None);
+ ArrayRef<Expr *> Args = None, TypoExpr **Out = nullptr);
ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S,
IdentifierInfo *II,
@@ -3426,11 +3529,13 @@ public:
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
LookupResult &R,
- bool NeedsADL);
+ bool NeedsADL,
+ bool AcceptInvalidDecl = false);
ExprResult BuildDeclarationNameExpr(
const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D,
NamedDecl *FoundD = nullptr,
- const TemplateArgumentListInfo *TemplateArgs = nullptr);
+ const TemplateArgumentListInfo *TemplateArgs = nullptr,
+ bool AcceptInvalidDecl = false);
ExprResult BuildLiteralOperatorCall(LookupResult &R,
DeclarationNameInfo &SuffixInfo,
@@ -3442,6 +3547,9 @@ public:
PredefinedExpr::IdentType IT);
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
+
+ bool CheckLoopHintExpr(Expr *E, SourceLocation Loc);
+
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr);
ExprResult ActOnCharacterConstant(const Token &Tok,
Scope *UDLScope = nullptr);
@@ -3625,6 +3733,10 @@ public:
bool GNUSyntax,
ExprResult Init);
+private:
+ static BinaryOperatorKind ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind);
+
+public:
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr);
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc,
@@ -3858,18 +3970,22 @@ public:
BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor, MultiExprArg Exprs,
bool HadMultipleCandidates, bool IsListInitialization,
+ bool IsStdInitListInitialization,
bool RequiresZeroInit, unsigned ConstructKind,
SourceRange ParenRange);
- // FIXME: Can re remove this and have the above BuildCXXConstructExpr check if
+ // FIXME: Can we remove this and have the above BuildCXXConstructExpr check if
// the constructor can be elidable?
ExprResult
BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor, bool Elidable,
MultiExprArg Exprs, bool HadMultipleCandidates,
- bool IsListInitialization, bool RequiresZeroInit,
+ bool IsListInitialization,
+ bool IsStdInitListInitialization, bool RequiresZeroInit,
unsigned ConstructKind, SourceRange ParenRange);
+ ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field);
+
/// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
/// the default expr if needed.
ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
@@ -3928,24 +4044,20 @@ public:
/// \brief Overwrite an EPI's exception specification with this
/// computed exception specification.
- void getEPI(FunctionProtoType::ExtProtoInfo &EPI) const {
- EPI.ExceptionSpecType = getExceptionSpecType();
- if (EPI.ExceptionSpecType == EST_Dynamic) {
- EPI.NumExceptions = size();
- EPI.Exceptions = data();
- } else if (EPI.ExceptionSpecType == EST_None) {
+ FunctionProtoType::ExceptionSpecInfo getExceptionSpec() const {
+ FunctionProtoType::ExceptionSpecInfo ESI;
+ ESI.Type = getExceptionSpecType();
+ if (ESI.Type == EST_Dynamic) {
+ ESI.Exceptions = Exceptions;
+ } else if (ESI.Type == EST_None) {
/// C++11 [except.spec]p14:
/// The exception-specification is noexcept(false) if the set of
/// potential exceptions of the special member function contains "any"
- EPI.ExceptionSpecType = EST_ComputedNoexcept;
- EPI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(),
+ ESI.Type = EST_ComputedNoexcept;
+ ESI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(),
tok::kw_false).get();
}
- }
- FunctionProtoType::ExtProtoInfo getEPI() const {
- FunctionProtoType::ExtProtoInfo EPI;
- getEPI(EPI);
- return EPI;
+ return ESI;
}
};
@@ -3992,13 +4104,28 @@ public:
void EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD);
/// \brief Check the given exception-specification and update the
- /// extended prototype information with the results.
- void checkExceptionSpecification(ExceptionSpecificationType EST,
+ /// exception specification information with the results.
+ void checkExceptionSpecification(bool IsTopLevel,
+ ExceptionSpecificationType EST,
ArrayRef<ParsedType> DynamicExceptions,
ArrayRef<SourceRange> DynamicExceptionRanges,
Expr *NoexceptExpr,
SmallVectorImpl<QualType> &Exceptions,
- FunctionProtoType::ExtProtoInfo &EPI);
+ FunctionProtoType::ExceptionSpecInfo &ESI);
+
+ /// \brief Determine if we're in a case where we need to (incorrectly) eagerly
+ /// parse an exception specification to work around a libstdc++ bug.
+ bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D);
+
+ /// \brief Add an exception-specification to the given member function
+ /// (or member function template). The exception-specification was parsed
+ /// after the method itself was declared.
+ void actOnDelayedExceptionSpecification(Decl *Method,
+ ExceptionSpecificationType EST,
+ SourceRange SpecificationRange,
+ ArrayRef<ParsedType> DynamicExceptions,
+ ArrayRef<SourceRange> DynamicExceptionRanges,
+ Expr *NoexceptExpr);
/// \brief Determine if a special member function should have a deleted
/// definition when it is defaulted.
@@ -4200,6 +4327,17 @@ public:
void *TyOrExpr,
SourceLocation RParenLoc);
+ /// \brief Handle a C++1z fold-expression: ( expr op ... op expr ).
+ ExprResult ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
+ tok::TokenKind Operator,
+ SourceLocation EllipsisLoc, Expr *RHS,
+ SourceLocation RParenLoc);
+ ExprResult BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
+ BinaryOperatorKind Operator,
+ SourceLocation EllipsisLoc, Expr *RHS,
+ SourceLocation RParenLoc);
+ ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
+ BinaryOperatorKind Operator);
//// ActOnCXXThis - Parse 'this' pointer.
ExprResult ActOnCXXThis(SourceLocation loc);
@@ -4444,16 +4582,26 @@ public:
/// \brief The parser has parsed a global nested-name-specifier '::'.
///
- /// \param S The scope in which this nested-name-specifier occurs.
- ///
/// \param CCLoc The location of the '::'.
///
/// \param SS The nested-name-specifier, which will be updated in-place
/// to reflect the parsed nested-name-specifier.
///
/// \returns true if an error occurred, false otherwise.
- bool ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc,
- CXXScopeSpec &SS);
+ bool ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc, CXXScopeSpec &SS);
+
+ /// \brief The parser has parsed a '__super' nested-name-specifier.
+ ///
+ /// \param SuperLoc The location of the '__super' keyword.
+ ///
+ /// \param ColonColonLoc The location of the '::'.
+ ///
+ /// \param SS The nested-name-specifier, which will be updated in-place
+ /// to reflect the parsed nested-name-specifier.
+ ///
+ /// \returns true if an error occurred, false otherwise.
+ bool ActOnSuperScopeSpecifier(SourceLocation SuperLoc,
+ SourceLocation ColonColonLoc, CXXScopeSpec &SS);
bool isAcceptableNestedNameSpecifier(const NamedDecl *SD);
NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
@@ -5032,6 +5180,10 @@ public:
/// CheckOverrideControl - Check C++11 override control semantics.
void CheckOverrideControl(NamedDecl *D);
+
+ /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was
+ /// not used in the declaration of an overriding method.
+ void DiagnoseAbsenceOfOverrideControl(NamedDecl *D);
/// CheckForFunctionMarkedFinal - Checks whether a virtual member function
/// overrides a virtual member function marked 'final', according to
@@ -5254,6 +5406,7 @@ public:
TemplateParameterList *TemplateParams,
AccessSpecifier AS,
SourceLocation ModulePrivateLoc,
+ SourceLocation FriendLoc,
unsigned NumOuterTemplateParamLists,
TemplateParameterList **OuterTemplateParamLists);
@@ -5575,6 +5728,10 @@ public:
// C++ Variadic Templates (C++0x [temp.variadic])
//===--------------------------------------------------------------------===//
+ /// Determine whether an unexpanded parameter pack might be permitted in this
+ /// location. Useful for error recovery.
+ bool isUnexpandedParameterPackPermitted();
+
/// \brief The context in which an unexpanded parameter pack is
/// being diagnosed.
///
@@ -6046,6 +6203,8 @@ public:
bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
bool Diagnose = true);
+ TypeLoc getReturnTypeLoc(FunctionDecl *FD) const;
+
bool DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
SourceLocation ReturnLoc,
Expr *&RetExpr, AutoType *AT);
@@ -6541,6 +6700,31 @@ public:
/// but have not yet been performed.
std::deque<PendingImplicitInstantiation> PendingInstantiations;
+ class SavePendingInstantiationsAndVTableUsesRAII {
+ public:
+ SavePendingInstantiationsAndVTableUsesRAII(Sema &S): S(S) {
+ SavedPendingInstantiations.swap(S.PendingInstantiations);
+ SavedVTableUses.swap(S.VTableUses);
+ }
+
+ ~SavePendingInstantiationsAndVTableUsesRAII() {
+ // Restore the set of pending vtables.
+ assert(S.VTableUses.empty() &&
+ "VTableUses should be empty before it is discarded.");
+ S.VTableUses.swap(SavedVTableUses);
+
+ // Restore the set of pending implicit instantiations.
+ assert(S.PendingInstantiations.empty() &&
+ "PendingInstantiations should be empty before it is discarded.");
+ S.PendingInstantiations.swap(SavedPendingInstantiations);
+ }
+
+ private:
+ Sema &S;
+ SmallVector<VTableUse, 16> SavedVTableUses;
+ std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
+ };
+
/// \brief The queue of implicit template instantiations that are required
/// and must be performed within the current local scope.
///
@@ -6590,6 +6774,8 @@ public:
DeclarationName Entity,
CXXRecordDecl *ThisContext,
unsigned ThisTypeQuals);
+ void SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto,
+ const MultiLevelTemplateArgumentList &Args);
ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D,
const MultiLevelTemplateArgumentList &TemplateArgs,
int indexAdjustment,
@@ -6649,6 +6835,10 @@ public:
const MultiLevelTemplateArgumentList &TemplateArgs,
TemplateSpecializationKind TSK);
+ bool InstantiateInClassInitializer(
+ SourceLocation PointOfInstantiation, FieldDecl *Instantiation,
+ FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs);
+
struct LateInstantiatedAttribute {
const Attr *TmplAttr;
LocalInstantiationScope *Scope;
@@ -7135,33 +7325,10 @@ public:
PSK_CodeSeg,
};
- enum PragmaSectionFlag : unsigned {
- PSF_None = 0,
- PSF_Read = 0x1,
- PSF_Write = 0x2,
- PSF_Execute = 0x4,
- PSF_Implicit = 0x8,
- PSF_Invalid = 0x80000000U,
- };
-
- struct SectionInfo {
- DeclaratorDecl *Decl;
- SourceLocation PragmaSectionLocation;
- int SectionFlags;
- SectionInfo() {}
- SectionInfo(DeclaratorDecl *Decl,
- SourceLocation PragmaSectionLocation,
- int SectionFlags)
- : Decl(Decl),
- PragmaSectionLocation(PragmaSectionLocation),
- SectionFlags(SectionFlags) {}
- };
-
- llvm::StringMap<SectionInfo> SectionInfos;
- bool UnifySection(const StringRef &SectionName,
+ bool UnifySection(StringRef SectionName,
int SectionFlags,
DeclaratorDecl *TheDecl);
- bool UnifySection(const StringRef &SectionName,
+ bool UnifySection(StringRef SectionName,
int SectionFlags,
SourceLocation PragmaSectionLocation);
@@ -7176,6 +7343,10 @@ public:
void ActOnPragmaMSSection(SourceLocation PragmaLocation,
int SectionFlags, StringLiteral *SegmentName);
+ /// \brief Called on well-formed \#pragma init_seg().
+ void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
+ StringLiteral *SegmentName);
+
/// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value);
@@ -7272,6 +7443,16 @@ public:
void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T,
unsigned SpellingListIndex, bool IsPackExpansion);
+ /// AddAssumeAlignedAttr - Adds an assume_aligned attribute to a particular
+ /// declaration.
+ void AddAssumeAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, Expr *OE,
+ unsigned SpellingListIndex);
+
+ /// AddAlignValueAttr - Adds an align_value attribute to a particular
+ /// declaration.
+ void AddAlignValueAttr(SourceRange AttrRange, Decl *D, Expr *E,
+ unsigned SpellingListIndex);
+
// OpenMP directives and clauses.
private:
void *VarDataSharingAttributesStack;
@@ -7300,14 +7481,15 @@ public:
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(
SourceLocation Loc,
ArrayRef<Expr *> VarList);
- // \brief Builds a new OpenMPThreadPrivateDecl and checks its correctness.
+ /// \brief Builds a new OpenMPThreadPrivateDecl and checks its correctness.
OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(
SourceLocation Loc,
ArrayRef<Expr *> VarList);
- // brief Initialization of captured region for OpenMP region.
+ /// \brief Initialization of captured region for OpenMP region.
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope);
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
+ const DeclarationNameInfo &DirName,
ArrayRef<OMPClause *> Clauses,
Stmt *AStmt,
SourceLocation StartLoc,
@@ -7330,6 +7512,12 @@ public:
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc,
llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
+ /// \brief Called on well-formed '\#pragma omp for simd' after parsing
+ /// of the associated statement.
+ StmtResult ActOnOpenMPForSimdDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
/// \brief Called on well-formed '\#pragma omp sections' after parsing
/// of the associated statement.
StmtResult ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
@@ -7344,18 +7532,70 @@ public:
StmtResult ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp master' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp critical' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
/// \brief Called on well-formed '\#pragma omp parallel for' after parsing
/// of the associated statement.
StmtResult ActOnOpenMPParallelForDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc,
llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
+ /// \brief Called on well-formed '\#pragma omp parallel for simd' after
+ /// parsing of the associated statement.
+ StmtResult ActOnOpenMPParallelForSimdDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
/// \brief Called on well-formed '\#pragma omp parallel sections' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt,
SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp task' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp taskyield'.
+ StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp barrier'.
+ StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp taskwait'.
+ StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp flush'.
+ StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp ordered' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPOrderedDirective(Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp atomic' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp target' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp teams' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
Expr *Expr,
@@ -7366,6 +7606,10 @@ public:
OMPClause *ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed 'final' clause.
+ OMPClause *ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// \brief Called on well-formed 'num_threads' clause.
OMPClause *ActOnOpenMPNumThreadsClause(Expr *NumThreads,
SourceLocation StartLoc,
@@ -7424,6 +7668,27 @@ public:
/// \brief Called on well-formed 'nowait' clause.
OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed 'untied' clause.
+ OMPClause *ActOnOpenMPUntiedClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed 'mergeable' clause.
+ OMPClause *ActOnOpenMPMergeableClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed 'read' clause.
+ OMPClause *ActOnOpenMPReadClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed 'write' clause.
+ OMPClause *ActOnOpenMPWriteClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed 'update' clause.
+ OMPClause *ActOnOpenMPUpdateClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed 'capture' clause.
+ OMPClause *ActOnOpenMPCaptureClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed 'seq_cst' clause.
+ OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
OMPClause *
ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr *> Vars,
@@ -7483,6 +7748,11 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed 'flush' pseudo clause.
+ OMPClause *ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// \brief The kind of conversion being performed.
enum CheckedConversionKind {
@@ -7561,6 +7831,7 @@ public:
VAK_Valid,
VAK_ValidInCXX11,
VAK_Undefined,
+ VAK_MSVCUndefined,
VAK_Invalid
};
@@ -7922,6 +8193,7 @@ public:
ObjCMethodDecl *Method, bool isClassMessage,
bool isSuperMessage,
SourceLocation lbrac, SourceLocation rbrac,
+ SourceRange RecRange,
QualType &ReturnType, ExprValueKind &VK);
/// \brief Determine the result of a message send expression based on
@@ -8013,7 +8285,8 @@ public:
CFT_Device,
CFT_Global,
CFT_Host,
- CFT_HostDevice
+ CFT_HostDevice,
+ CFT_InvalidTarget
};
CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D);
@@ -8021,10 +8294,24 @@ public:
bool CheckCUDATarget(CUDAFunctionTarget CallerTarget,
CUDAFunctionTarget CalleeTarget);
- bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee) {
- return CheckCUDATarget(IdentifyCUDATarget(Caller),
- IdentifyCUDATarget(Callee));
- }
+ bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee);
+
+ /// Given a implicit special member, infer its CUDA target from the
+ /// calls it needs to make to underlying base/field special members.
+ /// \param ClassDecl the class for which the member is being created.
+ /// \param CSM the kind of special member.
+ /// \param MemberDecl the special member itself.
+ /// \param ConstRHS true if this is a copy operation with a const object on
+ /// its RHS.
+ /// \param Diagnose true if this call should emit diagnostics.
+ /// \return true if there was an error inferring.
+ /// The result of this call is implicit CUDA target attribute(s) attached to
+ /// the member declaration.
+ bool inferCUDATargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl,
+ CXXSpecialMember CSM,
+ CXXMethodDecl *MemberDecl,
+ bool ConstRHS,
+ bool Diagnose);
/// \name Code completion
//@{
@@ -8215,7 +8502,8 @@ private:
bool CheckObjCString(Expr *Arg);
- ExprResult CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+ ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl,
+ unsigned BuiltinID, CallExpr *TheCall);
bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall,
unsigned MaxWidth);
@@ -8227,6 +8515,7 @@ private:
bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool SemaBuiltinVAStart(CallExpr *TheCall);
+ bool SemaBuiltinVAStartARM(CallExpr *Call);
bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
@@ -8239,6 +8528,8 @@ public:
private:
bool SemaBuiltinPrefetch(CallExpr *TheCall);
+ bool SemaBuiltinAssume(CallExpr *TheCall);
+ bool SemaBuiltinAssumeAligned(CallExpr *TheCall);
bool SemaBuiltinLongjmp(CallExpr *TheCall);
ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,
@@ -8266,6 +8557,10 @@ public:
FormatStringType Type, bool inFunctionCall,
VariadicCallType CallType,
llvm::SmallBitVector &CheckedVarArgs);
+
+ bool FormatStringHasSArg(const StringLiteral *FExpr);
+
+ bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx);
private:
bool CheckFormatArguments(const FormatAttr *Format,
@@ -8303,6 +8598,7 @@ private:
void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
+ void CheckBoolLikeConversion(Expr *E, SourceLocation CC);
void CheckForIntOverflow(Expr *E);
void CheckUnsequencedOperations(Expr *E);
diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h
index fdf9593051..7740d5e29c 100644
--- a/include/clang/Sema/SemaDiagnostic.h
+++ b/include/clang/Sema/SemaDiagnostic.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_DIAGNOSTICSEMA_H
-#define LLVM_CLANG_DIAGNOSTICSEMA_H
+#ifndef LLVM_CLANG_SEMA_SEMADIAGNOSTIC_H
+#define LLVM_CLANG_SEMA_SEMADIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
diff --git a/include/clang/Sema/SemaFixItUtils.h b/include/clang/Sema/SemaFixItUtils.h
index fffca67914..343ccfb3d6 100644
--- a/include/clang/Sema/SemaFixItUtils.h
+++ b/include/clang/Sema/SemaFixItUtils.h
@@ -10,8 +10,8 @@
// This file defines helper classes for generation of Sema FixItHints.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_FIXITUTILS_H
-#define LLVM_CLANG_SEMA_FIXITUTILS_H
+#ifndef LLVM_CLANG_SEMA_SEMAFIXITUTILS_H
+#define LLVM_CLANG_SEMA_SEMAFIXITUTILS_H
#include "clang/AST/Expr.h"
@@ -88,4 +88,4 @@ struct ConversionFixItGenerator {
};
} // endof namespace clang
-#endif // LLVM_CLANG_SEMA_FIXITUTILS_H
+#endif
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
index 9199b0fba2..045bacf213 100644
--- a/include/clang/Sema/SemaInternal.h
+++ b/include/clang/Sema/SemaInternal.h
@@ -12,10 +12,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_SEMA_INTERNAL_H
-#define LLVM_CLANG_SEMA_SEMA_INTERNAL_H
+#ifndef LLVM_CLANG_SEMA_SEMAINTERNAL_H
+#define LLVM_CLANG_SEMA_SEMAINTERNAL_H
#include "clang/AST/ASTContext.h"
+#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"
@@ -86,6 +87,213 @@ inline InheritableAttr *getDLLAttr(Decl *D) {
return nullptr;
}
+class TypoCorrectionConsumer : public VisibleDeclConsumer {
+ typedef SmallVector<TypoCorrection, 1> TypoResultList;
+ typedef llvm::StringMap<TypoResultList> TypoResultsMap;
+ typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap;
+
+public:
+ TypoCorrectionConsumer(Sema &SemaRef,
+ const DeclarationNameInfo &TypoName,
+ Sema::LookupNameKind LookupKind,
+ Scope *S, CXXScopeSpec *SS,
+ std::unique_ptr<CorrectionCandidateCallback> CCC,
+ DeclContext *MemberContext,
+ bool EnteringContext)
+ : Typo(TypoName.getName().getAsIdentifierInfo()), CurrentTCIndex(0),
+ SemaRef(SemaRef), S(S),
+ SS(SS ? llvm::make_unique<CXXScopeSpec>(*SS) : nullptr),
+ CorrectionValidator(std::move(CCC)), MemberContext(MemberContext),
+ Result(SemaRef, TypoName, LookupKind),
+ Namespaces(SemaRef.Context, SemaRef.CurContext, SS),
+ EnteringContext(EnteringContext), SearchNamespaces(false) {
+ Result.suppressDiagnostics();
+ // Arrange for ValidatedCorrections[0] to always be an empty correction.
+ ValidatedCorrections.push_back(TypoCorrection());
+ }
+
+ bool includeHiddenDecls() const override { return true; }
+
+ // Methods for adding potential corrections to the consumer.
+ void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
+ bool InBaseClass) override;
+ void FoundName(StringRef Name);
+ void addKeywordResult(StringRef Keyword);
+ void addCorrection(TypoCorrection Correction);
+
+ bool empty() const {
+ return CorrectionResults.empty() && ValidatedCorrections.size() == 1;
+ }
+
+ /// \brief Return the list of TypoCorrections for the given identifier from
+ /// the set of corrections that have the closest edit distance, if any.
+ TypoResultList &operator[](StringRef Name) {
+ return CorrectionResults.begin()->second[Name];
+ }
+
+ /// \brief Return the edit distance of the corrections that have the
+ /// closest/best edit distance from the original typop.
+ unsigned getBestEditDistance(bool Normalized) {
+ if (CorrectionResults.empty())
+ return (std::numeric_limits<unsigned>::max)();
+
+ unsigned BestED = CorrectionResults.begin()->first;
+ return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED;
+ }
+
+ /// \brief Set-up method to add to the consumer the set of namespaces to use
+ /// in performing corrections to nested name specifiers. This method also
+ /// implicitly adds all of the known classes in the current AST context to the
+ /// to the consumer for correcting nested name specifiers.
+ void
+ addNamespaces(const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces);
+
+ /// \brief Return the next typo correction that passes all internal filters
+ /// and is deemed valid by the consumer's CorrectionCandidateCallback,
+ /// starting with the corrections that have the closest edit distance. An
+ /// empty TypoCorrection is returned once no more viable corrections remain
+ /// in the consumer.
+ const TypoCorrection &getNextCorrection();
+
+ /// \brief Get the last correction returned by getNextCorrection().
+ const TypoCorrection &getCurrentCorrection() {
+ return CurrentTCIndex < ValidatedCorrections.size()
+ ? ValidatedCorrections[CurrentTCIndex]
+ : ValidatedCorrections[0]; // The empty correction.
+ }
+
+ /// \brief Return the next typo correction like getNextCorrection, but keep
+ /// the internal state pointed to the current correction (i.e. the next time
+ /// getNextCorrection is called, it will return the same correction returned
+ /// by peekNextcorrection).
+ const TypoCorrection &peekNextCorrection() {
+ auto Current = CurrentTCIndex;
+ const TypoCorrection &TC = getNextCorrection();
+ CurrentTCIndex = Current;
+ return TC;
+ }
+
+ /// \brief Reset the consumer's position in the stream of viable corrections
+ /// (i.e. getNextCorrection() will return each of the previously returned
+ /// corrections in order before returning any new corrections).
+ void resetCorrectionStream() {
+ CurrentTCIndex = 0;
+ }
+
+ /// \brief Return whether the end of the stream of corrections has been
+ /// reached.
+ bool finished() {
+ return CorrectionResults.empty() &&
+ CurrentTCIndex >= ValidatedCorrections.size();
+ }
+
+ ASTContext &getContext() const { return SemaRef.Context; }
+ const LookupResult &getLookupResult() const { return Result; }
+
+ bool isAddressOfOperand() const { return CorrectionValidator->IsAddressOfOperand; }
+ const CXXScopeSpec *getSS() const { return SS.get(); }
+ Scope *getScope() const { return S; }
+
+private:
+ class NamespaceSpecifierSet {
+ struct SpecifierInfo {
+ DeclContext* DeclCtx;
+ NestedNameSpecifier* NameSpecifier;
+ unsigned EditDistance;
+ };
+
+ typedef SmallVector<DeclContext*, 4> DeclContextList;
+ typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList;
+
+ ASTContext &Context;
+ DeclContextList CurContextChain;
+ std::string CurNameSpecifier;
+ SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
+ SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
+ bool isSorted;
+
+ SpecifierInfoList Specifiers;
+ llvm::SmallSetVector<unsigned, 4> Distances;
+ llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap;
+
+ /// \brief Helper for building the list of DeclContexts between the current
+ /// context and the top of the translation unit
+ static DeclContextList buildContextChain(DeclContext *Start);
+
+ void sortNamespaces();
+
+ unsigned buildNestedNameSpecifier(DeclContextList &DeclChain,
+ NestedNameSpecifier *&NNS);
+
+ public:
+ NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
+ CXXScopeSpec *CurScopeSpec);
+
+ /// \brief Add the DeclContext (a namespace or record) to the set, computing
+ /// the corresponding NestedNameSpecifier and its distance in the process.
+ void addNameSpecifier(DeclContext *Ctx);
+
+ typedef SpecifierInfoList::iterator iterator;
+ iterator begin() {
+ if (!isSorted) sortNamespaces();
+ return Specifiers.begin();
+ }
+ iterator end() { return Specifiers.end(); }
+ };
+
+ void addName(StringRef Name, NamedDecl *ND,
+ NestedNameSpecifier *NNS = nullptr, bool isKeyword = false);
+
+ /// \brief Find any visible decls for the given typo correction candidate.
+ /// If none are found, it to the set of candidates for which qualified lookups
+ /// will be performed to find possible nested name specifier changes.
+ bool resolveCorrection(TypoCorrection &Candidate);
+
+ /// \brief Perform qualified lookups on the queued set of typo correction
+ /// candidates and add the nested name specifier changes to each candidate if
+ /// a lookup succeeds (at which point the candidate will be returned to the
+ /// main pool of potential corrections).
+ void performQualifiedLookups();
+
+ /// \brief The name written that is a typo in the source.
+ IdentifierInfo *Typo;
+
+ /// \brief The results found that have the smallest edit distance
+ /// found (so far) with the typo name.
+ ///
+ /// The pointer value being set to the current DeclContext indicates
+ /// whether there is a keyword with this name.
+ TypoEditDistanceMap CorrectionResults;
+
+ SmallVector<TypoCorrection, 4> ValidatedCorrections;
+ size_t CurrentTCIndex;
+
+ Sema &SemaRef;
+ Scope *S;
+ std::unique_ptr<CXXScopeSpec> SS;
+ std::unique_ptr<CorrectionCandidateCallback> CorrectionValidator;
+ DeclContext *MemberContext;
+ LookupResult Result;
+ NamespaceSpecifierSet Namespaces;
+ SmallVector<TypoCorrection, 2> QualifiedResults;
+ bool EnteringContext;
+ bool SearchNamespaces;
+};
+
+inline Sema::TypoExprState::TypoExprState() {}
+
+inline Sema::TypoExprState::TypoExprState(TypoExprState &&other) LLVM_NOEXCEPT {
+ *this = std::move(other);
}
+inline Sema::TypoExprState &Sema::TypoExprState::operator=(
+ Sema::TypoExprState &&other) LLVM_NOEXCEPT {
+ Consumer = std::move(other.Consumer);
+ DiagHandler = std::move(other.DiagHandler);
+ RecoveryHandler = std::move(other.RecoveryHandler);
+ return *this;
+}
+
+} // end namespace clang
+
#endif
diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h
index f6367505f8..d043e2c459 100644
--- a/include/clang/Sema/SemaLambda.h
+++ b/include/clang/Sema/SemaLambda.h
@@ -13,8 +13,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_LAMBDA_H
-#define LLVM_CLANG_SEMA_LAMBDA_H
+#ifndef LLVM_CLANG_SEMA_SEMALAMBDA_H
+#define LLVM_CLANG_SEMA_SEMALAMBDA_H
#include "clang/AST/ASTLambda.h"
#include "clang/Sema/ScopeInfo.h"
namespace clang {
@@ -33,4 +33,4 @@ Optional<unsigned> getStackIndexOfNearestEnclosingCaptureCapableLambda(
} // clang
-#endif // LLVM_CLANG_SEMA_LAMBDA_H
+#endif
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
index 2c2c36d30b..8338d97575 100644
--- a/include/clang/Sema/TemplateDeduction.h
+++ b/include/clang/Sema/TemplateDeduction.h
@@ -10,8 +10,8 @@
// routines.
//
//===----------------------------------------------------------------------===/
-#ifndef LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H
-#define LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H
+#ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
+#define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/PartialDiagnostic.h"
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
index 6cab59c93e..922d0ffa11 100644
--- a/include/clang/Sema/TypoCorrection.h
+++ b/include/clang/Sema/TypoCorrection.h
@@ -17,6 +17,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Ownership.h"
#include "llvm/ADT/SmallVector.h"
namespace clang {
@@ -198,10 +199,9 @@ public:
void setCorrectionRange(CXXScopeSpec *SS,
const DeclarationNameInfo &TypoName) {
- CorrectionRange.setBegin(ForceSpecifierReplacement && SS && !SS->isEmpty()
- ? SS->getBeginLoc()
- : TypoName.getLoc());
- CorrectionRange.setEnd(TypoName.getLoc());
+ CorrectionRange = TypoName.getSourceRange();
+ if (ForceSpecifierReplacement && SS && !SS->isEmpty())
+ CorrectionRange.setBegin(SS->getBeginLoc());
}
SourceRange getCorrectionRange() const {
@@ -247,11 +247,13 @@ class CorrectionCandidateCallback {
public:
static const unsigned InvalidDistance = TypoCorrection::InvalidDistance;
- CorrectionCandidateCallback()
+ explicit CorrectionCandidateCallback(IdentifierInfo *Typo = nullptr,
+ NestedNameSpecifier *TypoNNS = nullptr)
: WantTypeSpecifiers(true), WantExpressionKeywords(true),
- WantCXXNamedCasts(true), WantRemainingKeywords(true),
- WantObjCSuper(false), IsObjCIvarLookup(false),
- IsAddressOfOperand(false) {}
+ WantCXXNamedCasts(true), WantFunctionLikeCasts(true),
+ WantRemainingKeywords(true), WantObjCSuper(false),
+ IsObjCIvarLookup(false), IsAddressOfOperand(false), Typo(Typo),
+ TypoNNS(TypoNNS) {}
virtual ~CorrectionCandidateCallback() {}
@@ -274,20 +276,39 @@ public:
/// the default RankCandidate returns either 0 or InvalidDistance depending
/// whether ValidateCandidate returns true or false.
virtual unsigned RankCandidate(const TypoCorrection &candidate) {
- return ValidateCandidate(candidate) ? 0 : InvalidDistance;
+ return (!MatchesTypo(candidate) && ValidateCandidate(candidate))
+ ? 0
+ : InvalidDistance;
}
- // Flags for context-dependent keywords.
+ void setTypoName(IdentifierInfo *II) { Typo = II; }
+ void setTypoNNS(NestedNameSpecifier *NNS) { TypoNNS = NNS; }
+
+ // Flags for context-dependent keywords. WantFunctionLikeCasts is only
+ // used/meaningful when WantCXXNamedCasts is false.
// TODO: Expand these to apply to non-keywords or possibly remove them.
bool WantTypeSpecifiers;
bool WantExpressionKeywords;
bool WantCXXNamedCasts;
+ bool WantFunctionLikeCasts;
bool WantRemainingKeywords;
bool WantObjCSuper;
// Temporary hack for the one case where a CorrectTypoContext enum is used
// when looking up results.
bool IsObjCIvarLookup;
bool IsAddressOfOperand;
+
+protected:
+ bool MatchesTypo(const TypoCorrection &candidate) {
+ return Typo && candidate.isResolved() && !candidate.requiresImport() &&
+ candidate.getCorrectionAsIdentifierInfo() == Typo &&
+ // FIXME: This probably does not return true when both
+ // NestedNameSpecifiers have the same textual representation.
+ candidate.getCorrectionSpecifier() == TypoNNS;
+ }
+
+ IdentifierInfo *Typo;
+ NestedNameSpecifier *TypoNNS;
};
/// @brief Simple template class for restricting typo correction candidates
@@ -325,6 +346,7 @@ public:
WantTypeSpecifiers = false;
WantExpressionKeywords = false;
WantCXXNamedCasts = false;
+ WantFunctionLikeCasts = false;
WantRemainingKeywords = false;
}
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 8d9cb01835..85495839d3 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -14,8 +14,8 @@
// respective lists.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_PCHBITCODES_H
-#define LLVM_CLANG_FRONTEND_PCHBITCODES_H
+#ifndef LLVM_CLANG_SERIALIZATION_ASTBITCODES_H
+#define LLVM_CLANG_SERIALIZATION_ASTBITCODES_H
#include "clang/AST/Type.h"
#include "llvm/ADT/DenseMap.h"
@@ -288,7 +288,10 @@ namespace clang {
/// \brief Record code for the module map file that was used to build this
/// AST file.
- MODULE_MAP_FILE = 14
+ MODULE_MAP_FILE = 14,
+
+ /// \brief Record code for the signature that identifiers this AST file.
+ SIGNATURE = 15
};
/// \brief Record types that occur within the input-files block
@@ -545,7 +548,10 @@ namespace clang {
LATE_PARSED_TEMPLATE = 50,
/// \brief Record code for \#pragma optimize options.
- OPTIMIZE_PRAGMA_OPTIONS = 51
+ OPTIMIZE_PRAGMA_OPTIONS = 51,
+
+ /// \brief Record code for potentially unused local typedef names.
+ UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES = 52,
};
/// \brief Record types used within a source manager block.
@@ -635,7 +641,13 @@ namespace clang {
/// \brief Specifies a conflict with another module.
SUBMODULE_CONFLICT = 12,
/// \brief Specifies a header that is private to this submodule.
- SUBMODULE_PRIVATE_HEADER = 13
+ SUBMODULE_PRIVATE_HEADER = 13,
+ /// \brief Specifies a header that is part of the module but must be
+ /// textually included.
+ SUBMODULE_TEXTUAL_HEADER = 14,
+ /// \brief Specifies a header that is private to this submodule but
+ /// must be textually included.
+ SUBMODULE_PRIVATE_TEXTUAL_HEADER = 15,
};
/// \brief Record types used within a comments block.
@@ -759,9 +771,6 @@ namespace clang {
/// NUM_PREDEF_TYPE_IDs.
const unsigned NUM_PREDEF_TYPE_IDS = 100;
- /// \brief The number of allowed abbreviations in bits
- const unsigned NUM_ALLOWED_ABBREVS_SIZE = 4;
-
/// \brief Record codes for each kind of type.
///
/// These constants describe the type records that can occur within a
@@ -1323,7 +1332,8 @@ namespace clang {
EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK,// SubstNonTypeTemplateParmPackExpr
EXPR_FUNCTION_PARM_PACK, // FunctionParmPackExpr
EXPR_MATERIALIZE_TEMPORARY, // MaterializeTemporaryExpr
-
+ EXPR_CXX_FOLD, // CXXFoldExpr
+
// CUDA
EXPR_CUDA_KERNEL_CALL, // CUDAKernelCallExpr
@@ -1339,15 +1349,28 @@ namespace clang {
STMT_SEH_FINALLY, // SEHFinallyStmt
STMT_SEH_TRY, // SEHTryStmt
- // OpenMP drectives
+ // OpenMP directives
STMT_OMP_PARALLEL_DIRECTIVE,
STMT_OMP_SIMD_DIRECTIVE,
STMT_OMP_FOR_DIRECTIVE,
+ STMT_OMP_FOR_SIMD_DIRECTIVE,
STMT_OMP_SECTIONS_DIRECTIVE,
STMT_OMP_SECTION_DIRECTIVE,
STMT_OMP_SINGLE_DIRECTIVE,
+ STMT_OMP_MASTER_DIRECTIVE,
+ STMT_OMP_CRITICAL_DIRECTIVE,
STMT_OMP_PARALLEL_FOR_DIRECTIVE,
+ STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE,
STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE,
+ STMT_OMP_TASK_DIRECTIVE,
+ STMT_OMP_TASKYIELD_DIRECTIVE,
+ STMT_OMP_BARRIER_DIRECTIVE,
+ STMT_OMP_TASKWAIT_DIRECTIVE,
+ STMT_OMP_FLUSH_DIRECTIVE,
+ STMT_OMP_ORDERED_DIRECTIVE,
+ STMT_OMP_ATOMIC_DIRECTIVE,
+ STMT_OMP_TARGET_DIRECTIVE,
+ STMT_OMP_TEAMS_DIRECTIVE,
// ARC
EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr
diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h
index 180f554daf..c24ccdcd4f 100644
--- a/include/clang/Serialization/ASTDeserializationListener.h
+++ b/include/clang/Serialization/ASTDeserializationListener.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_AST_DESERIALIZATION_LISTENER_H
-#define LLVM_CLANG_FRONTEND_AST_DESERIALIZATION_LISTENER_H
+#ifndef LLVM_CLANG_SERIALIZATION_ASTDESERIALIZATIONLISTENER_H
+#define LLVM_CLANG_SERIALIZATION_ASTDESERIALIZATIONLISTENER_H
#include "clang/Basic/IdentifierTable.h"
#include "clang/Serialization/ASTBitCodes.h"
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 0698b98abb..1b0347e91f 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_AST_READER_H
-#define LLVM_CLANG_FRONTEND_AST_READER_H
+#ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_H
+#define LLVM_CLANG_SERIALIZATION_ASTREADER_H
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclarationName.h"
@@ -115,7 +115,8 @@ public:
///
/// \returns true to indicate the options are invalid or false otherwise.
virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
- bool Complain) {
+ bool Complain,
+ bool AllowCompatibleDifferences) {
return false;
}
@@ -193,6 +194,13 @@ public:
bool isOverridden) {
return true;
}
+
+ /// \brief Returns true if this \c ASTReaderListener wants to receive the
+ /// imports of the AST file via \c visitImport, false otherwise.
+ virtual bool needsImportVisitation() const { return false; }
+ /// \brief If needsImportVisitation returns \c true, this is called for each
+ /// AST file imported by this AST file.
+ virtual void visitImport(StringRef Filename) {}
};
/// \brief Simple wrapper class for chaining listeners.
@@ -202,13 +210,18 @@ class ChainedASTReaderListener : public ASTReaderListener {
public:
/// Takes ownership of \p First and \p Second.
- ChainedASTReaderListener(ASTReaderListener *First, ASTReaderListener *Second)
- : First(First), Second(Second) { }
+ ChainedASTReaderListener(std::unique_ptr<ASTReaderListener> First,
+ std::unique_ptr<ASTReaderListener> Second)
+ : First(std::move(First)), Second(std::move(Second)) {}
+
+ std::unique_ptr<ASTReaderListener> takeFirst() { return std::move(First); }
+ std::unique_ptr<ASTReaderListener> takeSecond() { return std::move(Second); }
bool ReadFullVersionInformation(StringRef FullVersion) override;
void ReadModuleName(StringRef ModuleName) override;
void ReadModuleMapFile(StringRef ModuleMapPath) override;
- bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain) override;
+ bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
+ bool AllowCompatibleDifferences) override;
bool ReadTargetOptions(const TargetOptions &TargetOpts,
bool Complain) override;
bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
@@ -240,8 +253,8 @@ public:
PCHValidator(Preprocessor &PP, ASTReader &Reader)
: PP(PP), Reader(Reader) {}
- bool ReadLanguageOptions(const LangOptions &LangOpts,
- bool Complain) override;
+ bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
+ bool AllowCompatibleDifferences) override;
bool ReadTargetOptions(const TargetOptions &TargetOpts,
bool Complain) override;
bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
@@ -437,6 +450,16 @@ private:
/// \brief Declarations that have been replaced in a later file in the chain.
DeclReplacementMap ReplacedDecls;
+ /// \brief Declarations that have been imported and have typedef names for
+ /// linkage purposes.
+ llvm::DenseMap<std::pair<DeclContext*, IdentifierInfo*>, NamedDecl*>
+ ImportedTypedefNamesForLinkage;
+
+ /// \brief Mergeable declaration contexts that have anonymous declarations
+ /// within them, and those anonymous declarations.
+ llvm::DenseMap<DeclContext*, llvm::SmallVector<NamedDecl*, 2>>
+ AnonymousDeclarationsForMerging;
+
struct FileDeclsInfo {
ModuleFile *Mod;
ArrayRef<serialization::LocalDeclID> Decls;
@@ -748,6 +771,11 @@ private:
/// at the end of the TU, in which case it directs CodeGen to emit the VTable.
SmallVector<uint64_t, 16> DynamicClasses;
+ /// \brief The IDs of all potentially unused typedef names in the chain.
+ ///
+ /// Sema tracks these to emit warnings.
+ SmallVector<uint64_t, 16> UnusedLocalTypedefNameCandidates;
+
/// \brief The IDs of the declarations Sema stores directly.
///
/// Sema tracks a few important decls, such as namespace std, directly.
@@ -1106,6 +1134,7 @@ private:
SourceLocation ImportLoc, ModuleFile *ImportedBy,
SmallVectorImpl<ImportedModule> &Loaded,
off_t ExpectedSize, time_t ExpectedModTime,
+ serialization::ASTFileSignature ExpectedSignature,
unsigned ClientLoadCapabilities);
ASTReadResult ReadControlBlock(ModuleFile &F,
SmallVectorImpl<ImportedModule> &Loaded,
@@ -1116,10 +1145,14 @@ private:
bool ReadSourceManagerBlock(ModuleFile &F);
llvm::BitstreamCursor &SLocCursorForID(int ID);
SourceLocation getImportLocation(ModuleFile *F);
+ ASTReadResult ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
+ const ModuleFile *ImportedBy,
+ unsigned ClientLoadCapabilities);
ASTReadResult ReadSubmoduleBlock(ModuleFile &F,
unsigned ClientLoadCapabilities);
static bool ParseLanguageOptions(const RecordData &Record, bool Complain,
- ASTReaderListener &Listener);
+ ASTReaderListener &Listener,
+ bool AllowCompatibleDifferences);
static bool ParseTargetOptions(const RecordData &Record, bool Complain,
ASTReaderListener &Listener);
static bool ParseDiagnosticOptions(const RecordData &Record, bool Complain,
@@ -1142,7 +1175,7 @@ private:
QualType readTypeRecord(unsigned Index);
void readExceptionSpec(ModuleFile &ModuleFile,
SmallVectorImpl<QualType> &ExceptionStorage,
- FunctionProtoType::ExtProtoInfo &EPI,
+ FunctionProtoType::ExceptionSpecInfo &ESI,
const RecordData &Record, unsigned &Index);
RecordLocation TypeCursorForIndex(unsigned Index);
void LoadedDecl(unsigned Index, Decl *D);
@@ -1245,6 +1278,7 @@ private:
void PassInterestingDeclToConsumer(Decl *D);
void finishPendingActions();
+ void diagnoseOdrViolations();
void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name);
@@ -1366,22 +1400,53 @@ public:
bool Complain);
/// \brief Make the names within this set of hidden names visible.
- void makeNamesVisible(const HiddenNames &Names, Module *Owner);
+ void makeNamesVisible(const HiddenNames &Names, Module *Owner,
+ bool FromFinalization);
+
+ /// \brief Take the AST callbacks listener.
+ std::unique_ptr<ASTReaderListener> takeListener() {
+ return std::move(Listener);
+ }
/// \brief Set the AST callbacks listener.
- void setListener(ASTReaderListener *listener) {
- Listener.reset(listener);
+ void setListener(std::unique_ptr<ASTReaderListener> Listener) {
+ this->Listener = std::move(Listener);
}
- /// \brief Add an AST callbak listener.
+ /// \brief Add an AST callback listener.
///
/// Takes ownership of \p L.
- void addListener(ASTReaderListener *L) {
+ void addListener(std::unique_ptr<ASTReaderListener> L) {
if (Listener)
- L = new ChainedASTReaderListener(L, Listener.release());
- Listener.reset(L);
+ L = llvm::make_unique<ChainedASTReaderListener>(std::move(L),
+ std::move(Listener));
+ Listener = std::move(L);
}
+ /// RAII object to temporarily add an AST callback listener.
+ class ListenerScope {
+ ASTReader &Reader;
+ bool Chained;
+
+ public:
+ ListenerScope(ASTReader &Reader, std::unique_ptr<ASTReaderListener> L)
+ : Reader(Reader), Chained(false) {
+ auto Old = Reader.takeListener();
+ if (Old) {
+ Chained = true;
+ L = llvm::make_unique<ChainedASTReaderListener>(std::move(L),
+ std::move(Old));
+ }
+ Reader.setListener(std::move(L));
+ }
+ ~ListenerScope() {
+ auto New = Reader.takeListener();
+ if (Chained)
+ Reader.setListener(static_cast<ChainedASTReaderListener *>(New.get())
+ ->takeSecond());
+ }
+ };
+
/// \brief Set the AST deserialization listener.
void setDeserializationListener(ASTDeserializationListener *Listener,
bool TakeOwnership = false);
@@ -1411,8 +1476,9 @@ public:
void UpdateSema();
/// \brief Add in-memory (virtual file) buffer.
- void addInMemoryBuffer(StringRef &FileName, llvm::MemoryBuffer *Buffer) {
- ModuleMgr.addInMemoryBuffer(FileName, Buffer);
+ void addInMemoryBuffer(StringRef &FileName,
+ std::unique_ptr<llvm::MemoryBuffer> Buffer) {
+ ModuleMgr.addInMemoryBuffer(FileName, std::move(Buffer));
}
/// \brief Finalizes the AST reader's state before writing an AST file to
@@ -1771,6 +1837,9 @@ public:
void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) override;
+ void ReadUnusedLocalTypedefNameCandidates(
+ llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override;
+
void ReadLocallyScopedExternCDecls(
SmallVectorImpl<NamedDecl *> &Decls) override;
@@ -1837,11 +1906,12 @@ public:
llvm::DenseMap<IdentifierInfo*, AmbiguousMacros> AmbiguousMacroDefs;
void
- removeOverriddenMacros(IdentifierInfo *II, AmbiguousMacros &Ambig,
+ removeOverriddenMacros(IdentifierInfo *II, SourceLocation Loc,
+ AmbiguousMacros &Ambig,
ArrayRef<serialization::SubmoduleID> Overrides);
AmbiguousMacros *
- removeOverriddenMacros(IdentifierInfo *II,
+ removeOverriddenMacros(IdentifierInfo *II, SourceLocation Loc,
ArrayRef<serialization::SubmoduleID> Overrides);
/// \brief Retrieve the macro with the given ID.
@@ -2049,9 +2119,9 @@ public:
/// \brief Retrieve the AST context that this AST reader supplements.
ASTContext &getContext() { return Context; }
- // \brief Contains declarations that were loaded before we have
+ // \brief Contains the IDs for declarations that were requested before we have
// access to a Sema object.
- SmallVector<NamedDecl *, 16> PreloadedDecls;
+ SmallVector<uint64_t, 16> PreloadedDeclIDs;
/// \brief Retrieve the semantic analysis object used to analyze the
/// translation unit in which the precompiled header is being
@@ -2077,6 +2147,10 @@ public:
//RIDErief Loads comments ranges.
void ReadComments() override;
+
+ /// Return all input files for the given module file.
+ void getInputFiles(ModuleFile &F,
+ SmallVectorImpl<serialization::InputFile> &Files);
};
/// \brief Helper class that saves the current stream position and
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index ad6ecdd351..20e9935c0c 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -11,8 +11,8 @@
// containing a serialized representation of a translation unit.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_AST_WRITER_H
-#define LLVM_CLANG_FRONTEND_AST_WRITER_H
+#ifndef LLVM_CLANG_SERIALIZATION_ASTWRITER_H
+#define LLVM_CLANG_SERIALIZATION_ASTWRITER_H
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/Decl.h"
@@ -283,6 +283,10 @@ private:
llvm::DenseMap<const MacroDefinition *, serialization::PreprocessedEntityID>
MacroDefinitions;
+ /// \brief Cache of indices of anonymous declarations within their lexical
+ /// contexts.
+ llvm::DenseMap<const Decl *, unsigned> AnonymousDeclarationNumbers;
+
/// An update to a Decl.
class DeclUpdate {
/// A DeclUpdateKind.
@@ -466,7 +470,12 @@ private:
void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
bool isModule);
void WriteCXXBaseSpecifiersOffsets();
+
+ unsigned TypeExtQualAbbrev;
+ unsigned TypeFunctionProtoAbbrev;
+ void WriteTypeAbbrevs();
void WriteType(QualType T);
+
uint32_t GenerateNameLookupTable(const DeclContext *DC,
llvm::SmallVectorImpl<char> &LookupTable);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
@@ -494,17 +503,20 @@ private:
unsigned DeclContextLexicalAbbrev;
unsigned DeclContextVisibleLookupAbbrev;
unsigned UpdateVisibleAbbrev;
- unsigned DeclRefExprAbbrev;
- unsigned CharacterLiteralAbbrev;
unsigned DeclRecordAbbrev;
- unsigned IntegerLiteralAbbrev;
unsigned DeclTypedefAbbrev;
unsigned DeclVarAbbrev;
unsigned DeclFieldAbbrev;
unsigned DeclEnumAbbrev;
unsigned DeclObjCIvarAbbrev;
+ unsigned DeclCXXMethodAbbrev;
+
+ unsigned DeclRefExprAbbrev;
+ unsigned CharacterLiteralAbbrev;
+ unsigned IntegerLiteralAbbrev;
+ unsigned ExprImplicitCastAbbrev;
- void WriteDeclsBlockAbbrevs();
+ void WriteDeclAbbrevs();
void WriteDecl(ASTContext &Context, Decl *D);
void AddFunctionDefinition(const FunctionDecl *FD, RecordData &Record);
@@ -631,6 +643,7 @@ public:
DeclarationName Name, RecordDataImpl &Record);
void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
RecordDataImpl &Record);
+ unsigned getAnonymousDeclarationNumber(const NamedDecl *D);
void AddQualifierInfo(const QualifierInfo &Info, RecordDataImpl &Record);
@@ -731,16 +744,26 @@ public:
void ClearSwitchCaseIDs();
+ unsigned getTypeExtQualAbbrev() const {
+ return TypeExtQualAbbrev;
+ }
+ unsigned getTypeFunctionProtoAbbrev() const {
+ return TypeFunctionProtoAbbrev;
+ }
+
unsigned getDeclParmVarAbbrev() const { return DeclParmVarAbbrev; }
- unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; }
- unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; }
unsigned getDeclRecordAbbrev() const { return DeclRecordAbbrev; }
- unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; }
unsigned getDeclTypedefAbbrev() const { return DeclTypedefAbbrev; }
unsigned getDeclVarAbbrev() const { return DeclVarAbbrev; }
unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; }
unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; }
unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; }
+ unsigned getDeclCXXMethodAbbrev() const { return DeclCXXMethodAbbrev; }
+
+ unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; }
+ unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; }
+ unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; }
+ unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; }
bool hasChain() const { return Chain; }
@@ -775,6 +798,7 @@ public:
const ObjCPropertyDecl *OrigProp,
const ObjCCategoryDecl *ClassExt) override;
void DeclarationMarkedUsed(const Decl *D) override;
+ void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override;
};
/// \brief AST and semantic-analysis consumer that generates a
diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h
index f8ef8a1a63..5f8ae1fe7b 100644
--- a/include/clang/Serialization/ContinuousRangeMap.h
+++ b/include/clang/Serialization/ContinuousRangeMap.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SERIALIZATION_CONTINUOUS_RANGE_MAP_H
-#define LLVM_CLANG_SERIALIZATION_CONTINUOUS_RANGE_MAP_H
+#ifndef LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H
+#define LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallVector.h"
@@ -117,6 +117,14 @@ public:
~Builder() {
std::sort(Self.Rep.begin(), Self.Rep.end(), Compare());
+ std::unique(Self.Rep.begin(), Self.Rep.end(),
+ [](const_reference A, const_reference B) {
+ // FIXME: we should not allow any duplicate keys, but there are a lot of
+ // duplicate 0 -> 0 mappings to remove first.
+ assert((A == B || A.first != B.first) &&
+ "ContinuousRangeMap::Builder given non-unique keys");
+ return A == B;
+ });
}
void insert(const value_type &Val) {
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
index 1f0d7523ec..d8a57be84a 100644
--- a/include/clang/Serialization/GlobalModuleIndex.h
+++ b/include/clang/Serialization/GlobalModuleIndex.h
@@ -13,8 +13,8 @@
// queries such as "do any modules know about this identifier?"
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SERIALIZATION_GLOBAL_MODULE_INDEX_H
-#define LLVM_CLANG_SERIALIZATION_GLOBAL_MODULE_INDEX_H
+#ifndef LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H
+#define LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -115,7 +115,7 @@ class GlobalModuleIndex {
unsigned NumIdentifierLookupHits;
/// \brief Internal constructor. Use \c readIndex() to read an index.
- explicit GlobalModuleIndex(llvm::MemoryBuffer *Buffer,
+ explicit GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer,
llvm::BitstreamCursor Cursor);
GlobalModuleIndex(const GlobalModuleIndex &) LLVM_DELETED_FUNCTION;
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 4952039055..f6889cfe8e 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -42,10 +42,11 @@ namespace reader {
/// \brief Specifies the kind of module that has been loaded.
enum ModuleKind {
- MK_Module, ///< File is a module proper.
- MK_PCH, ///< File is a PCH file treated as such.
- MK_Preamble, ///< File is a PCH file treated as the preamble.
- MK_MainFile ///< File is a PCH file treated as the actual main file.
+ MK_ImplicitModule, ///< File is an implicitly-loaded module.
+ MK_ExplicitModule, ///< File is an explicitly-loaded module.
+ MK_PCH, ///< File is a PCH file treated as such.
+ MK_Preamble, ///< File is a PCH file treated as the preamble.
+ MK_MainFile ///< File is a PCH file treated as the actual main file.
};
/// \brief Information about the contents of a DeclContext.
@@ -96,6 +97,8 @@ public:
bool isNotFound() const { return Val.getInt() == NotFound; }
};
+typedef unsigned ASTFileSignature;
+
/// \brief Information about a module that has been loaded by the ASTReader.
///
/// Each instance of the Module class corresponds to a single AST file, which
@@ -151,6 +154,10 @@ public:
/// \brief The file entry for the module file.
const FileEntry *File;
+ /// \brief The signature of the module file, which may be used along with size
+ /// and modification time to identify this particular file.
+ ASTFileSignature Signature;
+
/// \brief Whether this module has been directly imported by the
/// user.
bool DirectlyImported;
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index 3259902222..3d10fad0a1 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H
-#define LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H
+#ifndef LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
+#define LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
#include "clang/Basic/FileManager.h"
#include "clang/Serialization/Module.h"
@@ -41,7 +41,8 @@ class ModuleManager {
FileManager &FileMgr;
/// \brief A lookup of in-memory (virtual file) buffers
- llvm::DenseMap<const FileEntry *, llvm::MemoryBuffer *> InMemoryBuffers;
+ llvm::DenseMap<const FileEntry *, std::unique_ptr<llvm::MemoryBuffer>>
+ InMemoryBuffers;
/// \brief The visitation order.
SmallVector<ModuleFile *, 4> VisitOrder;
@@ -141,7 +142,7 @@ public:
ModuleFile *lookup(const FileEntry *File);
/// \brief Returns the in-memory (virtual file) buffer with the given name
- llvm::MemoryBuffer *lookupBuffer(StringRef Name);
+ std::unique_ptr<llvm::MemoryBuffer> lookupBuffer(StringRef Name);
/// \brief Number of modules loaded
unsigned size() const { return Chain.size(); }
@@ -178,6 +179,12 @@ public:
/// \param ExpectedModTime The expected modification time of the module
/// file, used for validation. This will be zero if unknown.
///
+ /// \param ExpectedSignature The expected signature of the module file, used
+ /// for validation. This will be zero if unknown.
+ ///
+ /// \param ReadSignature Reads the signature from an AST file without actually
+ /// loading it.
+ ///
/// \param Module A pointer to the module file if the module was successfully
/// loaded.
///
@@ -190,6 +197,9 @@ public:
SourceLocation ImportLoc,
ModuleFile *ImportedBy, unsigned Generation,
off_t ExpectedSize, time_t ExpectedModTime,
+ ASTFileSignature ExpectedSignature,
+ std::function<ASTFileSignature(llvm::BitstreamReader &)>
+ ReadSignature,
ModuleFile *&Module,
std::string &ErrorStr);
@@ -199,7 +209,8 @@ public:
ModuleMap *modMap);
/// \brief Add an in-memory buffer the list of known buffers
- void addInMemoryBuffer(StringRef FileName, llvm::MemoryBuffer *Buffer);
+ void addInMemoryBuffer(StringRef FileName,
+ std::unique_ptr<llvm::MemoryBuffer> Buffer);
/// \brief Set the global module index.
void setGlobalIndex(GlobalModuleIndex *Index);
@@ -232,7 +243,7 @@ public:
/// Any module that is known to both the global module index and the module
/// manager that is *not* in this set can be skipped.
void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData,
- llvm::SmallPtrSet<ModuleFile *, 4> *ModuleFilesHit = nullptr);
+ llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit = nullptr);
/// \brief Visit each of the modules with a depth-first traversal.
///
diff --git a/include/clang/Serialization/SerializationDiagnostic.h b/include/clang/Serialization/SerializationDiagnostic.h
index c28cfea25c..d50422aa46 100644
--- a/include/clang/Serialization/SerializationDiagnostic.h
+++ b/include/clang/Serialization/SerializationDiagnostic.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SERIALIZATIONDIAGNOSTIC_H
-#define LLVM_CLANG_SERIALIZATIONDIAGNOSTIC_H
+#ifndef LLVM_CLANG_SERIALIZATION_SERIALIZATIONDIAGNOSTIC_H
+#define LLVM_CLANG_SERIALIZATION_SERIALIZATIONDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
diff --git a/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h b/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
index eee38e9208..463f04a65a 100644
--- a/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
+++ b/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_LOCALCHECKERS_H
-#define LLVM_CLANG_GR_LOCALCHECKERS_H
+#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_LOCALCHECKERS_H
+#define LLVM_CLANG_STATICANALYZER_CHECKERS_LOCALCHECKERS_H
namespace clang {
namespace ento {
diff --git a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
index 26335bf68d..ab92a2465c 100644
--- a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
+++ b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
@@ -16,10 +16,18 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_OBJCRETAINCOUNT_H
-#define LLVM_CLANG_OBJCRETAINCOUNT_H
+#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H
+#define LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H
-namespace clang { namespace ento { namespace objc_retain {
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+class FunctionDecl;
+class ObjCMethodDecl;
+
+namespace ento { namespace objc_retain {
/// An ArgEffect summarizes the retain count behavior on an argument or receiver
/// to a function or method.
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 978c3e20ab..fc9fc5ee79 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYZEROPTIONS_H
-#define LLVM_CLANG_ANALYZEROPTIONS_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
+#define LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -137,6 +137,13 @@ public:
unsigned maxBlockVisitOnPath;
+ /// \brief Disable all analyzer checks.
+ ///
+ /// This flag allows one to disable analyzer checks on the code processed by
+ /// the given analysis consumer. Note, the code will get parsed and the
+ /// command-line options will get checked.
+ unsigned DisableAllChecks : 1;
+
unsigned ShowCheckerHelp : 1;
unsigned AnalyzeAll : 1;
unsigned AnalyzerDisplayProgress : 1;
@@ -420,6 +427,7 @@ public:
AnalysisConstraintsOpt(RangeConstraintsModel),
AnalysisDiagOpt(PD_HTML),
AnalysisPurgeOpt(PurgeStmt),
+ DisableAllChecks(0),
ShowCheckerHelp(0),
AnalyzeAll(0),
AnalyzerDisplayProgress(0),
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 5371231925..b03371ccee 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_BUGREPORTER
-#define LLVM_CLANG_GR_BUGREPORTER
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H
#include "clang/Basic/SourceLocation.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
@@ -63,7 +63,7 @@ public:
};
typedef const SourceRange *ranges_iterator;
- typedef SmallVector<BugReporterVisitor *, 8> VisitorList;
+ typedef SmallVector<std::unique_ptr<BugReporterVisitor>, 8> VisitorList;
typedef VisitorList::iterator visitor_iterator;
typedef SmallVector<StringRef, 2> ExtraTextList;
@@ -179,9 +179,9 @@ public:
const ExplodedNode *getErrorNode() const { return ErrorNode; }
- const StringRef getDescription() const { return Description; }
+ StringRef getDescription() const { return Description; }
- const StringRef getShortDescription(bool UseFallback = true) const {
+ StringRef getShortDescription(bool UseFallback = true) const {
if (ShortDescription.empty() && UseFallback)
return Description;
return ShortDescription;
@@ -299,9 +299,9 @@ public:
/// \sa registerConditionVisitor(), registerTrackNullOrUndefValue(),
/// registerFindLastStore(), registerNilReceiverVisitor(), and
/// registerVarDeclsLastStore().
- void addVisitor(BugReporterVisitor *visitor);
+ void addVisitor(std::unique_ptr<BugReporterVisitor> visitor);
- /// Iterators through the custom diagnostic visitors.
+ /// Iterators through the custom diagnostic visitors.
visitor_iterator visitor_begin() { return Callbacks.begin(); }
visitor_iterator visitor_end() { return Callbacks.end(); }
@@ -345,9 +345,12 @@ class BugReportEquivClass : public llvm::FoldingSetNode {
llvm::ilist<BugReport> Reports;
friend class BugReporter;
- void AddReport(BugReport* R) { Reports.push_back(R); }
+ void AddReport(std::unique_ptr<BugReport> R) {
+ Reports.push_back(R.release());
+ }
+
public:
- BugReportEquivClass(BugReport* R) { Reports.push_back(R); }
+ BugReportEquivClass(std::unique_ptr<BugReport> R) { AddReport(std::move(R)); }
~BugReportEquivClass();
void Profile(llvm::FoldingSetNodeID& ID) const {
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
index f352f806eb..83b05ecc52 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_BUGREPORTERVISITOR
-#define LLVM_CLANG_GR_BUGREPORTERVISITOR
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITOR_H
+#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITOR_H
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/ADT/FoldingSet.h"
@@ -48,7 +48,7 @@ public:
/// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
/// default implementation of clone() will NOT do the right thing, and you
/// will have to provide your own implementation.)
- virtual BugReporterVisitor *clone() const = 0;
+ virtual std::unique_ptr<BugReporterVisitor> clone() const = 0;
/// \brief Return a diagnostic piece which should be associated with the
/// given node.
@@ -66,17 +66,15 @@ public:
/// If returns NULL the default implementation will be used.
/// Also note that at most one visitor of a BugReport should generate a
/// non-NULL end of path diagnostic piece.
- virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
- const ExplodedNode *N,
- BugReport &BR);
+ virtual std::unique_ptr<PathDiagnosticPiece>
+ getEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR);
virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
/// \brief Generates the default final diagnostic piece.
- static PathDiagnosticPiece *getDefaultEndPath(BugReporterContext &BRC,
- const ExplodedNode *N,
- BugReport &BR);
-
+ static std::unique_ptr<PathDiagnosticPiece>
+ getDefaultEndPath(BugReporterContext &BRC, const ExplodedNode *N,
+ BugReport &BR);
};
/// This class provides a convenience implementation for clone() using the
@@ -89,8 +87,8 @@ public:
/// will have to provide your own implementation.)
template <class DERIVED>
class BugReporterVisitorImpl : public BugReporterVisitor {
- BugReporterVisitor *clone() const override {
- return new DERIVED(*static_cast<const DERIVED *>(this));
+ std::unique_ptr<BugReporterVisitor> clone() const override {
+ return llvm::make_unique<DERIVED>(*static_cast<const DERIVED *>(this));
}
};
@@ -268,9 +266,9 @@ public:
return nullptr;
}
- PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
- const ExplodedNode *N,
- BugReport &BR) override;
+ std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
+ const ExplodedNode *N,
+ BugReport &BR) override;
};
/// \brief When a region containing undefined value or '0' value is passed
@@ -364,4 +362,4 @@ bool isDeclRefExprToReference(const Expr *E);
} // end namespace bugreporter
-#endif //LLVM_CLANG_GR__BUGREPORTERVISITOR
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
index 24c778552e..16226e94df 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYSIS_BUGTYPE
-#define LLVM_CLANG_ANALYSIS_BUGTYPE
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGTYPE_H
+#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGTYPE_H
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
index 3f0fe968cc..8df2bc331b 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_STATIC_ANALYZER_BUG_CATEGORIES_H
-#define LLVM_CLANG_STATIC_ANALYZER_BUG_CATEGORIES_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_COMMONBUGCATEGORIES_H
+#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_COMMONBUGCATEGORIES_H
// Common strings used for the "category" of many static analyzer issues.
namespace clang {
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index 5a578d015e..b4ab1ea785 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_PATH_DIAGNOSTIC_H
-#define LLVM_CLANG_PATH_DIAGNOSTIC_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
+#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Basic/SourceLocation.h"
@@ -94,8 +94,8 @@ public:
FilesMade *filesMade) = 0;
virtual StringRef getName() const = 0;
-
- void HandlePathDiagnostic(PathDiagnostic *D);
+
+ void HandlePathDiagnostic(std::unique_ptr<PathDiagnostic> D);
enum PathGenerationScheme { None, Minimal, Extensive, AlternateExtensive };
virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
@@ -762,11 +762,11 @@ public:
bool isWithinCall() const { return !pathStack.empty(); }
- void setEndOfPath(PathDiagnosticPiece *EndPiece) {
+ void setEndOfPath(std::unique_ptr<PathDiagnosticPiece> EndPiece) {
assert(!Loc.isValid() && "End location already set!");
Loc = EndPiece->getLocation();
assert(Loc.isValid() && "Invalid location for end-of-path piece");
- getActivePath().push_back(EndPiece);
+ getActivePath().push_back(EndPiece.release());
}
void appendToDesc(StringRef S) {
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index b9a5b8a27f..8cc35148e0 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SA_CORE_CHECKER
-#define LLVM_CLANG_SA_CORE_CHECKER
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
#include "clang/Analysis/ProgramPoint.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index b364115c99..30b0480235 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
-#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Basic/LangOptions.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
index 43e9166b3c..ce512fd301 100644
--- a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
+++ b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_PATH_DIAGNOSTIC_CLIENTS_H
-#define LLVM_CLANG_GR_PATH_DIAGNOSTIC_CLIENTS_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHDIAGNOSTICCONSUMERS_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHDIAGNOSTICCONSUMERS_H
#include <string>
#include <vector>
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
index 37be69aaba..cc8a9b8ef0 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SA_CORE_APSINTTYPE_H
-#define LLVM_CLANG_SA_CORE_APSINTTYPE_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSINTTYPE_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSINTTYPE_H
#include "llvm/ADT/APSInt.h"
#include <tuple>
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index 1a398b8648..dbc59cfbd9 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_ANALYSISMANAGER_H
-#define LLVM_CLANG_GR_ANALYSISMANAGER_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H
#include "clang/Analysis/AnalysisContext.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
@@ -23,6 +23,8 @@
namespace clang {
+class CodeInjector;
+
namespace ento {
class CheckerManager;
@@ -50,7 +52,8 @@ public:
StoreManagerCreator storemgr,
ConstraintManagerCreator constraintmgr,
CheckerManager *checkerMgr,
- AnalyzerOptions &Options);
+ AnalyzerOptions &Options,
+ CodeInjector* injector = nullptr);
~AnalysisManager();
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index 08905fdf07..5b007f1531 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_BASICVALUEFACTORY_H
-#define LLVM_CLANG_GR_BASICVALUEFACTORY_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BASICVALUEFACTORY_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BASICVALUEFACTORY_H
#include "clang/AST/ASTContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
index 0408070e49..1d779e6cb6 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_BLOCKCOUNTER
-#define LLVM_CLANG_GR_BLOCKCOUNTER
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BLOCKCOUNTER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BLOCKCOUNTER_H
#include "llvm/Support/Allocator.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index 4a5426b274..00deaa6c19 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_CALL
-#define LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_CALL
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 5a33bdf01b..68274f52a6 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT
-#define LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERCONTEXT_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERCONTEXT_H
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
index 12547e0969..6a42df20d1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_PATHSENSITIVE_CHECKERHELPERS
-#define LLVM_CLANG_GR_PATHSENSITIVE_CHECKERHELPERS
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERHELPERS_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERHELPERS_H
#include "clang/AST/Stmt.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
index 51bb89b9e1..f8760964b7 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_CONSTRAINT_MANAGER_H
-#define LLVM_CLANG_GR_CONSTRAINT_MANAGER_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CONSTRAINTMANAGER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CONSTRAINTMANAGER_H
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
@@ -148,8 +148,9 @@ protected:
virtual ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym);
};
-ConstraintManager* CreateRangeConstraintManager(ProgramStateManager& statemgr,
- SubEngine *subengine);
+std::unique_ptr<ConstraintManager>
+CreateRangeConstraintManager(ProgramStateManager &statemgr,
+ SubEngine *subengine);
} // end GR namespace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 76ace6d7cc..0dafd5f3bd 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_COREENGINE
-#define LLVM_CLANG_GR_COREENGINE
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
#include "clang/AST/Expr.h"
#include "clang/Analysis/AnalysisContext.h"
@@ -60,7 +60,7 @@ private:
SubEngine& SubEng;
/// G - The simulation graph. Each node is a (location,state) pair.
- std::unique_ptr<ExplodedGraph> G;
+ mutable ExplodedGraph G;
/// WList - A set of queued nodes that need to be processed by the
/// worklist algorithm. It is up to the implementation of WList to decide
@@ -95,6 +95,8 @@ private:
void HandleBranch(const Stmt *Cond, const Stmt *Term, const CFGBlock *B,
ExplodedNode *Pred);
+ void HandleCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
+ const CFGBlock *B, ExplodedNode *Pred);
/// Handle conditional logic for running static initializers.
void HandleStaticInit(const DeclStmt *DS, const CFGBlock *B,
@@ -108,19 +110,12 @@ private:
public:
/// Construct a CoreEngine object to analyze the provided CFG.
- CoreEngine(SubEngine& subengine,
- FunctionSummariesTy *FS)
- : SubEng(subengine), G(new ExplodedGraph()),
- WList(WorkList::makeDFS()),
- BCounterFactory(G->getAllocator()),
- FunctionSummaries(FS){}
+ CoreEngine(SubEngine &subengine, FunctionSummariesTy *FS)
+ : SubEng(subengine), WList(WorkList::makeDFS()),
+ BCounterFactory(G.getAllocator()), FunctionSummaries(FS) {}
/// getGraph - Returns the exploded graph.
- ExplodedGraph& getGraph() { return *G.get(); }
-
- /// takeGraph - Returns the exploded graph. Ownership of the graph is
- /// transferred to the caller.
- ExplodedGraph *takeGraph() { return G.release(); }
+ ExplodedGraph &getGraph() { return G; }
/// ExecuteWorkList - Run the worklist algorithm for a maximum number of
/// steps. Returns true if there is still simulation state on the worklist.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
index 5ac97dbc31..e13c6410c7 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SA_CORE_DYNAMICTYPEINFO_H
-#define LLVM_CLANG_SA_CORE_DYNAMICTYPEINFO_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEINFO_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEINFO_H
#include "clang/AST/Type.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
index f3a582da04..ba9715b38f 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_ENVIRONMENT_H
-#define LLVM_CLANG_GR_ENVIRONMENT_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
#include "clang/Analysis/AnalysisContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index 98092ef00d..c4eabb8c2a 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -16,8 +16,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_EXPLODEDGRAPH
-#define LLVM_CLANG_GR_EXPLODEDGRAPH
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
#include "clang/AST/Decl.h"
#include "clang/Analysis/AnalysisContext.h"
@@ -297,8 +297,8 @@ public:
bool IsSink = false,
bool* IsNew = nullptr);
- ExplodedGraph* MakeEmptyGraph() const {
- return new ExplodedGraph();
+ std::unique_ptr<ExplodedGraph> MakeEmptyGraph() const {
+ return llvm::make_unique<ExplodedGraph>();
}
/// addRoot - Add an untyped node to the set of roots.
@@ -372,9 +372,10 @@ public:
/// \param[out] InverseMap An optional map from nodes in the returned graph to
/// nodes in this graph.
/// \returns The trimmed graph
- ExplodedGraph *trim(ArrayRef<const NodeTy *> Nodes,
- InterExplodedGraphMap *ForwardMap = nullptr,
- InterExplodedGraphMap *InverseMap = nullptr) const;
+ std::unique_ptr<ExplodedGraph>
+ trim(ArrayRef<const NodeTy *> Nodes,
+ InterExplodedGraphMap *ForwardMap = nullptr,
+ InterExplodedGraphMap *InverseMap = nullptr) const;
/// Enable tracking of recently allocated nodes for potential reclamation
/// when calling reclaimRecentlyAllocatedNodes().
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 0fb4a24591..247bf0c69d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_EXPRENGINE
-#define LLVM_CLANG_GR_EXPRENGINE
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
@@ -227,6 +227,15 @@ public:
const CFGBlock *DstT,
const CFGBlock *DstF) override;
+ /// Called by CoreEngine.
+ /// Used to generate successor nodes for temporary destructors depending
+ /// on whether the corresponding constructor was visited.
+ void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
+ NodeBuilderContext &BldCtx,
+ ExplodedNode *Pred, ExplodedNodeSet &Dst,
+ const CFGBlock *DstT,
+ const CFGBlock *DstF) override;
+
/// Called by CoreEngine. Used to processing branching behavior
/// at static initalizers.
void processStaticInitializer(const DeclStmt *DS,
@@ -408,7 +417,11 @@ public:
void VisitIncrementDecrementOperator(const UnaryOperator* U,
ExplodedNode *Pred,
ExplodedNodeSet &Dst);
-
+
+ void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
+ ExplodedNodeSet &PreVisit,
+ ExplodedNodeSet &Dst);
+
void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
index 169af939f0..faa3500045 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_FUNCTIONSUMMARY_H
-#define LLVM_CLANG_GR_FUNCTIONSUMMARY_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 92b082d521..1be7a26126 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_MEMREGION_H
-#define LLVM_CLANG_GR_MEMREGION_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/CharUnits.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 4902ef50c7..e819b88911 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_VALUESTATE_H
-#define LLVM_CLANG_GR_VALUESTATE_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_H
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
@@ -39,9 +39,10 @@ namespace ento {
class CallEvent;
class CallEventManager;
-typedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&,
- SubEngine*);
-typedef StoreManager* (*StoreManagerCreator)(ProgramStateManager&);
+typedef std::unique_ptr<ConstraintManager>(*ConstraintManagerCreator)(
+ ProgramStateManager &, SubEngine *);
+typedef std::unique_ptr<StoreManager>(*StoreManagerCreator)(
+ ProgramStateManager &);
//===----------------------------------------------------------------------===//
// ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
index 823bde798e..6b4da7db24 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
@@ -15,8 +15,8 @@
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
-#define LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATETRAIT_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATETRAIT_H
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h
index 371f3c582f..415bb7713d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_PROGRAMSTATE_FWD_H
-#define LLVM_CLANG_PROGRAMSTATE_FWD_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_FWD_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_FWD_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index 29fb413d1c..a68d3410a8 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_SVALBUILDER
-#define LLVM_CLANG_GR_SVALBUILDER
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALBUILDER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALBUILDER_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index d50c3be4bf..ef43fe0eea 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_RVALUE_H
-#define LLVM_CLANG_GR_RVALUE_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index 84c3166121..5500c3c9ef 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_STORE_H
-#define LLVM_CLANG_GR_STORE_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STORE_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STORE_H
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
@@ -276,8 +276,10 @@ inline StoreRef &StoreRef::operator=(StoreRef const &newStore) {
}
// FIXME: Do we need to pass ProgramStateManager anymore?
-StoreManager *CreateRegionStoreManager(ProgramStateManager& StMgr);
-StoreManager *CreateFieldsOnlyRegionStoreManager(ProgramStateManager& StMgr);
+std::unique_ptr<StoreManager>
+CreateRegionStoreManager(ProgramStateManager &StMgr);
+std::unique_ptr<StoreManager>
+CreateFieldsOnlyRegionStoreManager(ProgramStateManager &StMgr);
} // end GR namespace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
index d5ba003a69..958c8c377e 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_STOREREF_H
-#define LLVM_CLANG_GR_STOREREF_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STOREREF_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STOREREF_H
#include <cassert>
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index 3482e8d27d..741ba0e2f2 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -10,8 +10,8 @@
// This file defines the interface of a subengine of the CoreEngine.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_SUBENGINE_H
-#define LLVM_CLANG_GR_SUBENGINE_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SUBENGINE_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SUBENGINE_H
#include "clang/Analysis/ProgramPoint.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
@@ -72,6 +72,16 @@ public:
const CFGBlock *DstT,
const CFGBlock *DstF) = 0;
+ /// Called by CoreEngine.
+ /// Used to generate successor nodes for temporary destructors depending
+ /// on whether the corresponding constructor was visited.
+ virtual void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
+ NodeBuilderContext &BldCtx,
+ ExplodedNode *Pred,
+ ExplodedNodeSet &Dst,
+ const CFGBlock *DstT,
+ const CFGBlock *DstF) = 0;
+
/// Called by CoreEngine. Used to processing branching behavior
/// at static initalizers.
virtual void processStaticInitializer(const DeclStmt *DS,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index 2b5cc18c9a..fbeaae48dc 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_SYMMGR_H
-#define LLVM_CLANG_GR_SYMMGR_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMBOLMANAGER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMBOLMANAGER_H
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
index 4c58d4b1d2..d39b5017d3 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TAINTMANAGER_H
-#define LLVM_CLANG_TAINTMANAGER_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTMANAGER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTMANAGER_H
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
index 8ddc8b9d6f..0c56e7d8ea 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
@@ -11,8 +11,8 @@
// of taint.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TAINTTAG_H
-#define LLVM_CLANG_TAINTTAG_H
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H
namespace clang {
namespace ento {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
index 3ed145dbd2..4f1a60e675 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_WORKLIST
-#define LLVM_CLANG_GR_WORKLIST
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_WORKLIST_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_WORKLIST_H
#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
diff --git a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
index 30e5d3dd9a..37ea05fb99 100644
--- a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
+++ b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_ANALYSISCONSUMER_H
-#define LLVM_CLANG_GR_ANALYSISCONSUMER_H
+#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_ANALYSISCONSUMER_H
+#define LLVM_CLANG_STATICANALYZER_FRONTEND_ANALYSISCONSUMER_H
#include "clang/AST/ASTConsumer.h"
#include "clang/Basic/LLVM.h"
@@ -25,6 +25,8 @@ namespace clang {
class Preprocessor;
class DiagnosticsEngine;
+class CodeInjector;
+class CompilerInstance;
namespace ento {
class CheckerManager;
@@ -37,10 +39,8 @@ public:
/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
/// analysis passes. (The set of analyses run is controlled by command-line
/// options.)
-AnalysisASTConsumer *CreateAnalysisConsumer(const Preprocessor &pp,
- const std::string &output,
- AnalyzerOptionsRef opts,
- ArrayRef<std::string> plugins);
+std::unique_ptr<AnalysisASTConsumer>
+CreateAnalysisConsumer(CompilerInstance &CI);
} // end GR namespace
diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
index 1df8c098d9..2985b7c117 100644
--- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
+++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
@@ -7,10 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SA_FRONTEND_CHECKERREGISTRATION_H
-#define LLVM_CLANG_SA_FRONTEND_CHECKERREGISTRATION_H
+#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H
+#define LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H
#include "clang/Basic/LLVM.h"
+#include <memory>
#include <string>
namespace clang {
@@ -21,10 +22,9 @@ namespace clang {
namespace ento {
class CheckerManager;
-CheckerManager *createCheckerManager(AnalyzerOptions &opts,
- const LangOptions &langOpts,
- ArrayRef<std::string> plugins,
- DiagnosticsEngine &diags);
+ std::unique_ptr<CheckerManager>
+ createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts,
+ ArrayRef<std::string> plugins, DiagnosticsEngine &diags);
} // end ento namespace
diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
index 21ecfc234f..f18b8ccc8b 100644
--- a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
+++ b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
@@ -7,13 +7,17 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_GR_FRONTENDACTIONS_H
-#define LLVM_CLANG_GR_FRONTENDACTIONS_H
+#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_FRONTENDACTIONS_H
+#define LLVM_CLANG_STATICANALYZER_FRONTEND_FRONTENDACTIONS_H
#include "clang/Frontend/FrontendAction.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
namespace clang {
+class Stmt;
+
namespace ento {
//===----------------------------------------------------------------------===//
@@ -22,8 +26,29 @@ namespace ento {
class AnalysisAction : public ASTFrontendAction {
protected:
- ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+};
+
+/// \brief Frontend action to parse model files.
+///
+/// This frontend action is responsible for parsing model files. Model files can
+/// not be parsed on their own, they rely on type information that is available
+/// in another translation unit. The parsing of model files is done by a
+/// separate compiler instance that reuses the ASTContext and othen information
+/// from the main translation unit that is being compiled. After a model file is
+/// parsed, the function definitions will be collected into a StringMap.
+class ParseModelFileAction : public ASTFrontendAction {
+public:
+ ParseModelFileAction(llvm::StringMap<Stmt *> &Bodies);
+ bool isModelParsingAction() const override { return true; }
+
+protected:
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+
+private:
+ llvm::StringMap<Stmt *> &Bodies;
};
void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins);
diff --git a/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h b/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h
new file mode 100644
index 0000000000..24f8042587
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h
@@ -0,0 +1,44 @@
+//===-- ModelConsumer.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements clang::ento::ModelConsumer which is an
+/// ASTConsumer for model files.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_MODELCONSUMER_H
+#define LLVM_CLANG_GR_MODELCONSUMER_H
+
+#include "clang/AST/ASTConsumer.h"
+#include "llvm/ADT/StringMap.h"
+
+namespace clang {
+
+class Stmt;
+
+namespace ento {
+
+/// \brief ASTConsumer to consume model files' AST.
+///
+/// This consumer collects the bodies of function definitions into a StringMap
+/// from a model file.
+class ModelConsumer : public ASTConsumer {
+public:
+ ModelConsumer(llvm::StringMap<Stmt *> &Bodies);
+
+ bool HandleTopLevelDecl(DeclGroupRef D) override;
+
+private:
+ llvm::StringMap<Stmt *> &Bodies;
+};
+}
+}
+
+#endif
diff --git a/include/clang/Tooling/ArgumentsAdjusters.h b/include/clang/Tooling/ArgumentsAdjusters.h
index 765e7d2e05..30bca9bb41 100644
--- a/include/clang/Tooling/ArgumentsAdjusters.h
+++ b/include/clang/Tooling/ArgumentsAdjusters.h
@@ -40,8 +40,7 @@ public:
///
/// \returns Modified sequence of command line arguments.
virtual CommandLineArguments Adjust(const CommandLineArguments &Args) = 0;
- virtual ~ArgumentsAdjuster() {
- }
+ virtual ~ArgumentsAdjuster() {}
};
/// \brief Syntax check only command line adjuster.
@@ -58,6 +57,22 @@ class ClangStripOutputAdjuster : public ArgumentsAdjuster {
CommandLineArguments Adjust(const CommandLineArguments &Args) override;
};
+class InsertArgumentAdjuster : public ArgumentsAdjuster {
+public:
+ enum Position { BEGIN, END };
+
+ InsertArgumentAdjuster(const CommandLineArguments &Extra, Position Pos)
+ : Extra(Extra), Pos(Pos) {}
+
+ InsertArgumentAdjuster(const char *Extra, Position Pos)
+ : Extra(1, std::string(Extra)), Pos(Pos) {}
+
+ CommandLineArguments Adjust(const CommandLineArguments &Args) override;
+
+private:
+ const CommandLineArguments Extra;
+ const Position Pos;
+};
} // end namespace tooling
} // end namespace clang
diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h
index 815ede80c2..c23dc9211d 100644
--- a/include/clang/Tooling/CommonOptionsParser.h
+++ b/include/clang/Tooling/CommonOptionsParser.h
@@ -24,8 +24,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMONOPTIONSPARSER_H
-#define LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMONOPTIONSPARSER_H
+#ifndef LLVM_CLANG_TOOLING_COMMONOPTIONSPARSER_H
+#define LLVM_CLANG_TOOLING_COMMONOPTIONSPARSER_H
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/Support/CommandLine.h"
@@ -89,6 +89,8 @@ public:
private:
std::unique_ptr<CompilationDatabase> Compilations;
std::vector<std::string> SourcePathList;
+ std::vector<std::string> ExtraArgsBefore;
+ std::vector<std::string> ExtraArgsAfter;
};
} // namespace tooling
diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h
index d1e729a88b..27c16524e6 100644
--- a/include/clang/Tooling/CompilationDatabase.h
+++ b/include/clang/Tooling/CompilationDatabase.h
@@ -25,8 +25,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOOLING_COMPILATION_DATABASE_H
-#define LLVM_CLANG_TOOLING_COMPILATION_DATABASE_H
+#ifndef LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H
+#define LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
@@ -84,22 +84,22 @@ public:
/// FIXME: Currently only supports JSON compilation databases, which
/// are named 'compile_commands.json' in the given directory. Extend this
/// for other build types (like ninja build files).
- static CompilationDatabase *loadFromDirectory(StringRef BuildDirectory,
- std::string &ErrorMessage);
+ static std::unique_ptr<CompilationDatabase>
+ loadFromDirectory(StringRef BuildDirectory, std::string &ErrorMessage);
/// \brief Tries to detect a compilation database location and load it.
///
/// Looks for a compilation database in all parent paths of file 'SourceFile'
/// by calling loadFromDirectory.
- static CompilationDatabase *autoDetectFromSource(StringRef SourceFile,
- std::string &ErrorMessage);
+ static std::unique_ptr<CompilationDatabase>
+ autoDetectFromSource(StringRef SourceFile, std::string &ErrorMessage);
/// \brief Tries to detect a compilation database location and load it.
///
/// Looks for a compilation database in directory 'SourceDir' and all
/// its parent paths by calling loadFromDirectory.
- static CompilationDatabase *autoDetectFromDirectory(StringRef SourceDir,
- std::string &ErrorMessage);
+ static std::unique_ptr<CompilationDatabase>
+ autoDetectFromDirectory(StringRef SourceDir, std::string &ErrorMessage);
/// \brief Returns all compile commands in which the specified file was
/// compiled.
@@ -142,8 +142,8 @@ public:
/// \brief Loads a compilation database from a build directory.
///
/// \see CompilationDatabase::loadFromDirectory().
- virtual CompilationDatabase *loadFromDirectory(StringRef Directory,
- std::string &ErrorMessage) = 0;
+ virtual std::unique_ptr<CompilationDatabase>
+ loadFromDirectory(StringRef Directory, std::string &ErrorMessage) = 0;
};
/// \brief A compilation database that returns a single compile command line.
@@ -213,4 +213,4 @@ private:
} // end namespace tooling
} // end namespace clang
-#endif // LLVM_CLANG_TOOLING_COMPILATION_DATABASE_H
+#endif
diff --git a/include/clang/Tooling/CompilationDatabasePluginRegistry.h b/include/clang/Tooling/CompilationDatabasePluginRegistry.h
index 84fcd24b4a..7323ec8974 100644
--- a/include/clang/Tooling/CompilationDatabasePluginRegistry.h
+++ b/include/clang/Tooling/CompilationDatabasePluginRegistry.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOOLING_COMPILATION_DATABASE_PLUGIN_REGISTRY_H
-#define LLVM_CLANG_TOOLING_COMPILATION_DATABASE_PLUGIN_REGISTRY_H
+#ifndef LLVM_CLANG_TOOLING_COMPILATIONDATABASEPLUGINREGISTRY_H
+#define LLVM_CLANG_TOOLING_COMPILATIONDATABASEPLUGINREGISTRY_H
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/Support/Registry.h"
@@ -24,4 +24,4 @@ typedef llvm::Registry<CompilationDatabasePlugin>
} // end namespace tooling
} // end namespace clang
-#endif // LLVM_CLANG_TOOLING_COMPILATION_DATABASE_PLUGIN_REGISTRY_H
+#endif
diff --git a/include/clang/Tooling/Core/Replacement.h b/include/clang/Tooling/Core/Replacement.h
new file mode 100644
index 0000000000..30a7036c2b
--- /dev/null
+++ b/include/clang/Tooling/Core/Replacement.h
@@ -0,0 +1,229 @@
+//===--- Replacement.h - Framework for clang refactoring tools --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Classes supporting refactorings that span multiple translation units.
+// While single translation unit refactorings are supported via the Rewriter,
+// when refactoring multiple translation units changes must be stored in a
+// SourceManager independent form, duplicate changes need to be removed, and
+// all changes must be applied at once at the end of the refactoring so that
+// the code is always parseable.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
+#define LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/StringRef.h"
+#include <set>
+#include <string>
+#include <vector>
+
+namespace clang {
+
+class Rewriter;
+
+namespace tooling {
+
+/// \brief A source range independent of the \c SourceManager.
+class Range {
+public:
+ Range() : Offset(0), Length(0) {}
+ Range(unsigned Offset, unsigned Length) : Offset(Offset), Length(Length) {}
+
+ /// \brief Accessors.
+ /// @{
+ unsigned getOffset() const { return Offset; }
+ unsigned getLength() const { return Length; }
+ /// @}
+
+ /// \name Range Predicates
+ /// @{
+ /// \brief Whether this range overlaps with \p RHS or not.
+ bool overlapsWith(Range RHS) const {
+ return Offset + Length > RHS.Offset && Offset < RHS.Offset + RHS.Length;
+ }
+
+ /// \brief Whether this range contains \p RHS or not.
+ bool contains(Range RHS) const {
+ return RHS.Offset >= Offset &&
+ (RHS.Offset + RHS.Length) <= (Offset + Length);
+ }
+ /// @}
+
+private:
+ unsigned Offset;
+ unsigned Length;
+};
+
+/// \brief A text replacement.
+///
+/// Represents a SourceManager independent replacement of a range of text in a
+/// specific file.
+class Replacement {
+public:
+ /// \brief Creates an invalid (not applicable) replacement.
+ Replacement();
+
+ /// \brief Creates a replacement of the range [Offset, Offset+Length) in
+ /// FilePath with ReplacementText.
+ ///
+ /// \param FilePath A source file accessible via a SourceManager.
+ /// \param Offset The byte offset of the start of the range in the file.
+ /// \param Length The length of the range in bytes.
+ Replacement(StringRef FilePath, unsigned Offset,
+ unsigned Length, StringRef ReplacementText);
+
+ /// \brief Creates a Replacement of the range [Start, Start+Length) with
+ /// ReplacementText.
+ Replacement(const SourceManager &Sources, SourceLocation Start, unsigned Length,
+ StringRef ReplacementText);
+
+ /// \brief Creates a Replacement of the given range with ReplacementText.
+ Replacement(const SourceManager &Sources, const CharSourceRange &Range,
+ StringRef ReplacementText);
+
+ /// \brief Creates a Replacement of the node with ReplacementText.
+ template <typename Node>
+ Replacement(const SourceManager &Sources, const Node &NodeToReplace,
+ StringRef ReplacementText);
+
+ /// \brief Returns whether this replacement can be applied to a file.
+ ///
+ /// Only replacements that are in a valid file can be applied.
+ bool isApplicable() const;
+
+ /// \brief Accessors.
+ /// @{
+ StringRef getFilePath() const { return FilePath; }
+ unsigned getOffset() const { return ReplacementRange.getOffset(); }
+ unsigned getLength() const { return ReplacementRange.getLength(); }
+ StringRef getReplacementText() const { return ReplacementText; }
+ /// @}
+
+ /// \brief Applies the replacement on the Rewriter.
+ bool apply(Rewriter &Rewrite) const;
+
+ /// \brief Returns a human readable string representation.
+ std::string toString() const;
+
+ private:
+ void setFromSourceLocation(const SourceManager &Sources, SourceLocation Start,
+ unsigned Length, StringRef ReplacementText);
+ void setFromSourceRange(const SourceManager &Sources,
+ const CharSourceRange &Range,
+ StringRef ReplacementText);
+
+ std::string FilePath;
+ Range ReplacementRange;
+ std::string ReplacementText;
+};
+
+/// \brief Less-than operator between two Replacements.
+bool operator<(const Replacement &LHS, const Replacement &RHS);
+
+/// \brief Equal-to operator between two Replacements.
+bool operator==(const Replacement &LHS, const Replacement &RHS);
+
+/// \brief A set of Replacements.
+/// FIXME: Change to a vector and deduplicate in the RefactoringTool.
+typedef std::set<Replacement> Replacements;
+
+/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
+///
+/// Replacement applications happen independently of the success of
+/// other applications.
+///
+/// \returns true if all replacements apply. false otherwise.
+bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
+
+/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
+///
+/// Replacement applications happen independently of the success of
+/// other applications.
+///
+/// \returns true if all replacements apply. false otherwise.
+bool applyAllReplacements(const std::vector<Replacement> &Replaces,
+ Rewriter &Rewrite);
+
+/// \brief Applies all replacements in \p Replaces to \p Code.
+///
+/// This completely ignores the path stored in each replacement. If one or more
+/// replacements cannot be applied, this returns an empty \c string.
+std::string applyAllReplacements(StringRef Code, const Replacements &Replaces);
+
+/// \brief Calculates how a code \p Position is shifted when \p Replaces are
+/// applied.
+unsigned shiftedCodePosition(const Replacements& Replaces, unsigned Position);
+
+/// \brief Calculates how a code \p Position is shifted when \p Replaces are
+/// applied.
+///
+/// \pre Replaces[i].getOffset() <= Replaces[i+1].getOffset().
+unsigned shiftedCodePosition(const std::vector<Replacement> &Replaces,
+ unsigned Position);
+
+/// \brief Removes duplicate Replacements and reports if Replacements conflict
+/// with one another. All Replacements are assumed to be in the same file.
+///
+/// \post Replaces[i].getOffset() <= Replaces[i+1].getOffset().
+///
+/// This function sorts \p Replaces so that conflicts can be reported simply by
+/// offset into \p Replaces and number of elements in the conflict.
+void deduplicate(std::vector<Replacement> &Replaces,
+ std::vector<Range> &Conflicts);
+
+/// \brief Collection of Replacements generated from a single translation unit.
+struct TranslationUnitReplacements {
+ /// Name of the main source for the translation unit.
+ std::string MainSourceFile;
+
+ /// A freeform chunk of text to describe the context of the replacements.
+ /// Will be printed, for example, when detecting conflicts during replacement
+ /// deduplication.
+ std::string Context;
+
+ std::vector<Replacement> Replacements;
+};
+
+/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
+///
+/// Replacement applications happen independently of the success of
+/// other applications.
+///
+/// \returns true if all replacements apply. false otherwise.
+bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
+
+/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
+///
+/// Replacement applications happen independently of the success of
+/// other applications.
+///
+/// \returns true if all replacements apply. false otherwise.
+bool applyAllReplacements(const std::vector<Replacement> &Replaces,
+ Rewriter &Rewrite);
+
+/// \brief Applies all replacements in \p Replaces to \p Code.
+///
+/// This completely ignores the path stored in each replacement. If one or more
+/// replacements cannot be applied, this returns an empty \c string.
+std::string applyAllReplacements(StringRef Code, const Replacements &Replaces);
+
+template <typename Node>
+Replacement::Replacement(const SourceManager &Sources,
+ const Node &NodeToReplace, StringRef ReplacementText) {
+ const CharSourceRange Range =
+ CharSourceRange::getTokenRange(NodeToReplace->getSourceRange());
+ setFromSourceRange(Sources, Range, ReplacementText);
+}
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
diff --git a/include/clang/Tooling/FileMatchTrie.h b/include/clang/Tooling/FileMatchTrie.h
index be37baff2f..745c164506 100644
--- a/include/clang/Tooling/FileMatchTrie.h
+++ b/include/clang/Tooling/FileMatchTrie.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOOLING_FILE_MATCH_TRIE_H
-#define LLVM_CLANG_TOOLING_FILE_MATCH_TRIE_H
+#ifndef LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
+#define LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
@@ -86,4 +86,4 @@ private:
} // end namespace tooling
} // end namespace clang
-#endif // LLVM_CLANG_TOOLING_FILE_MATCH_TRIE_H
+#endif
diff --git a/include/clang/Tooling/JSONCompilationDatabase.h b/include/clang/Tooling/JSONCompilationDatabase.h
index 1b33359685..b4edc31652 100644
--- a/include/clang/Tooling/JSONCompilationDatabase.h
+++ b/include/clang/Tooling/JSONCompilationDatabase.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOOLING_JSON_COMPILATION_DATABASE_H
-#define LLVM_CLANG_TOOLING_JSON_COMPILATION_DATABASE_H
+#ifndef LLVM_CLANG_TOOLING_JSONCOMPILATIONDATABASE_H
+#define LLVM_CLANG_TOOLING_JSONCOMPILATIONDATABASE_H
#include "clang/Basic/LLVM.h"
#include "clang/Tooling/CompilationDatabase.h"
@@ -53,14 +53,14 @@ public:
///
/// Returns NULL and sets ErrorMessage if the database could not be
/// loaded from the given file.
- static JSONCompilationDatabase *loadFromFile(StringRef FilePath,
- std::string &ErrorMessage);
+ static std::unique_ptr<JSONCompilationDatabase>
+ loadFromFile(StringRef FilePath, std::string &ErrorMessage);
/// \brief Loads a JSON compilation database from a data buffer.
///
/// Returns NULL and sets ErrorMessage if the database could not be loaded.
- static JSONCompilationDatabase *loadFromBuffer(StringRef DatabaseString,
- std::string &ErrorMessage);
+ static std::unique_ptr<JSONCompilationDatabase>
+ loadFromBuffer(StringRef DatabaseString, std::string &ErrorMessage);
/// \brief Returns all compile comamnds in which the specified file was
/// compiled.
@@ -81,8 +81,9 @@ public:
private:
/// \brief Constructs a JSON compilation database on a memory buffer.
- JSONCompilationDatabase(llvm::MemoryBuffer *Database)
- : Database(Database), YAMLStream(Database->getBuffer(), SM) {}
+ JSONCompilationDatabase(std::unique_ptr<llvm::MemoryBuffer> Database)
+ : Database(std::move(Database)),
+ YAMLStream(this->Database->getBuffer(), SM) {}
/// \brief Parses the database file and creates the index.
///
@@ -112,4 +113,4 @@ private:
} // end namespace tooling
} // end namespace clang
-#endif // LLVM_CLANG_TOOLING_JSON_COMPILATION_DATABASE_H
+#endif
diff --git a/include/clang/Tooling/Refactoring.h b/include/clang/Tooling/Refactoring.h
index cd2fb9f6c5..e3e7f83c38 100644
--- a/include/clang/Tooling/Refactoring.h
+++ b/include/clang/Tooling/Refactoring.h
@@ -19,180 +19,16 @@
#ifndef LLVM_CLANG_TOOLING_REFACTORING_H
#define LLVM_CLANG_TOOLING_REFACTORING_H
-#include "clang/Basic/SourceLocation.h"
+#include "clang/Tooling/Core/Replacement.h"
#include "clang/Tooling/Tooling.h"
-#include "llvm/ADT/StringRef.h"
-#include <set>
#include <string>
namespace clang {
class Rewriter;
-class SourceLocation;
namespace tooling {
-/// \brief A source range independent of the \c SourceManager.
-class Range {
-public:
- Range() : Offset(0), Length(0) {}
- Range(unsigned Offset, unsigned Length) : Offset(Offset), Length(Length) {}
-
- /// \brief Accessors.
- /// @{
- unsigned getOffset() const { return Offset; }
- unsigned getLength() const { return Length; }
- /// @}
-
- /// \name Range Predicates
- /// @{
- /// \brief Whether this range overlaps with \p RHS or not.
- bool overlapsWith(Range RHS) const {
- return Offset + Length > RHS.Offset && Offset < RHS.Offset + RHS.Length;
- }
-
- /// \brief Whether this range contains \p RHS or not.
- bool contains(Range RHS) const {
- return RHS.Offset >= Offset &&
- (RHS.Offset + RHS.Length) <= (Offset + Length);
- }
- /// @}
-
-private:
- unsigned Offset;
- unsigned Length;
-};
-
-/// \brief A text replacement.
-///
-/// Represents a SourceManager independent replacement of a range of text in a
-/// specific file.
-class Replacement {
-public:
- /// \brief Creates an invalid (not applicable) replacement.
- Replacement();
-
- /// \brief Creates a replacement of the range [Offset, Offset+Length) in
- /// FilePath with ReplacementText.
- ///
- /// \param FilePath A source file accessible via a SourceManager.
- /// \param Offset The byte offset of the start of the range in the file.
- /// \param Length The length of the range in bytes.
- Replacement(StringRef FilePath, unsigned Offset,
- unsigned Length, StringRef ReplacementText);
-
- /// \brief Creates a Replacement of the range [Start, Start+Length) with
- /// ReplacementText.
- Replacement(const SourceManager &Sources, SourceLocation Start, unsigned Length,
- StringRef ReplacementText);
-
- /// \brief Creates a Replacement of the given range with ReplacementText.
- Replacement(const SourceManager &Sources, const CharSourceRange &Range,
- StringRef ReplacementText);
-
- /// \brief Creates a Replacement of the node with ReplacementText.
- template <typename Node>
- Replacement(const SourceManager &Sources, const Node &NodeToReplace,
- StringRef ReplacementText);
-
- /// \brief Returns whether this replacement can be applied to a file.
- ///
- /// Only replacements that are in a valid file can be applied.
- bool isApplicable() const;
-
- /// \brief Accessors.
- /// @{
- StringRef getFilePath() const { return FilePath; }
- unsigned getOffset() const { return ReplacementRange.getOffset(); }
- unsigned getLength() const { return ReplacementRange.getLength(); }
- StringRef getReplacementText() const { return ReplacementText; }
- /// @}
-
- /// \brief Applies the replacement on the Rewriter.
- bool apply(Rewriter &Rewrite) const;
-
- /// \brief Returns a human readable string representation.
- std::string toString() const;
-
- private:
- void setFromSourceLocation(const SourceManager &Sources, SourceLocation Start,
- unsigned Length, StringRef ReplacementText);
- void setFromSourceRange(const SourceManager &Sources,
- const CharSourceRange &Range,
- StringRef ReplacementText);
-
- std::string FilePath;
- Range ReplacementRange;
- std::string ReplacementText;
-};
-
-/// \brief Less-than operator between two Replacements.
-bool operator<(const Replacement &LHS, const Replacement &RHS);
-
-/// \brief Equal-to operator between two Replacements.
-bool operator==(const Replacement &LHS, const Replacement &RHS);
-
-/// \brief A set of Replacements.
-/// FIXME: Change to a vector and deduplicate in the RefactoringTool.
-typedef std::set<Replacement> Replacements;
-
-/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
-///
-/// Replacement applications happen independently of the success of
-/// other applications.
-///
-/// \returns true if all replacements apply. false otherwise.
-bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
-
-/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
-///
-/// Replacement applications happen independently of the success of
-/// other applications.
-///
-/// \returns true if all replacements apply. false otherwise.
-bool applyAllReplacements(const std::vector<Replacement> &Replaces,
- Rewriter &Rewrite);
-
-/// \brief Applies all replacements in \p Replaces to \p Code.
-///
-/// This completely ignores the path stored in each replacement. If one or more
-/// replacements cannot be applied, this returns an empty \c string.
-std::string applyAllReplacements(StringRef Code, const Replacements &Replaces);
-
-/// \brief Calculates how a code \p Position is shifted when \p Replaces are
-/// applied.
-unsigned shiftedCodePosition(const Replacements& Replaces, unsigned Position);
-
-/// \brief Calculates how a code \p Position is shifted when \p Replaces are
-/// applied.
-///
-/// \pre Replaces[i].getOffset() <= Replaces[i+1].getOffset().
-unsigned shiftedCodePosition(const std::vector<Replacement> &Replaces,
- unsigned Position);
-
-/// \brief Removes duplicate Replacements and reports if Replacements conflict
-/// with one another.
-///
-/// \post Replaces[i].getOffset() <= Replaces[i+1].getOffset().
-///
-/// This function sorts \p Replaces so that conflicts can be reported simply by
-/// offset into \p Replaces and number of elements in the conflict.
-void deduplicate(std::vector<Replacement> &Replaces,
- std::vector<Range> &Conflicts);
-
-/// \brief Collection of Replacements generated from a single translation unit.
-struct TranslationUnitReplacements {
- /// Name of the main source for the translation unit.
- std::string MainSourceFile;
-
- /// A freeform chunk of text to describe the context of the replacements.
- /// Will be printed, for example, when detecting conflicts during replacement
- /// deduplication.
- std::string Context;
-
- std::vector<Replacement> Replacements;
-};
-
/// \brief A tool to run refactorings.
///
/// This is a refactoring specific version of \see ClangTool. FrontendActions
@@ -230,15 +66,7 @@ private:
Replacements Replace;
};
-template <typename Node>
-Replacement::Replacement(const SourceManager &Sources,
- const Node &NodeToReplace, StringRef ReplacementText) {
- const CharSourceRange Range =
- CharSourceRange::getTokenRange(NodeToReplace->getSourceRange());
- setFromSourceRange(Sources, Range, ReplacementText);
-}
-
} // end namespace tooling
} // end namespace clang
-#endif // end namespace LLVM_CLANG_TOOLING_REFACTORING_H
+#endif // LLVM_CLANG_TOOLING_REFACTORING_H
diff --git a/include/clang/Tooling/RefactoringCallbacks.h b/include/clang/Tooling/RefactoringCallbacks.h
index 19f277431a..6ef9ea11f0 100644
--- a/include/clang/Tooling/RefactoringCallbacks.h
+++ b/include/clang/Tooling/RefactoringCallbacks.h
@@ -26,8 +26,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOOLING_REFACTORING_CALLBACKS_H
-#define LLVM_CLANG_TOOLING_REFACTORING_CALLBACKS_H
+#ifndef LLVM_CLANG_TOOLING_REFACTORINGCALLBACKS_H
+#define LLVM_CLANG_TOOLING_REFACTORINGCALLBACKS_H
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Tooling/Refactoring.h"
@@ -87,4 +87,4 @@ private:
} // end namespace tooling
} // end namespace clang
-#endif // LLVM_CLANG_TOOLING_REFACTORING_CALLBACKS_H
+#endif
diff --git a/include/clang/Tooling/ReplacementsYaml.h b/include/clang/Tooling/ReplacementsYaml.h
index ac9f46908f..4a7666d2c5 100644
--- a/include/clang/Tooling/ReplacementsYaml.h
+++ b/include/clang/Tooling/ReplacementsYaml.h
@@ -13,8 +13,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_TOOLING_REPLACEMENTS_YAML_H
-#define LLVM_CLANG_TOOLING_REPLACEMENTS_YAML_H
+#ifndef LLVM_CLANG_TOOLING_REPLACEMENTSYAML_H
+#define LLVM_CLANG_TOOLING_REPLACEMENTSYAML_H
#include "clang/Tooling/Refactoring.h"
#include "llvm/Support/YAMLTraits.h"
@@ -73,4 +73,4 @@ template <> struct MappingTraits<clang::tooling::TranslationUnitReplacements> {
} // end namespace yaml
} // end namespace llvm
-#endif // LLVM_CLANG_TOOLING_REPLACEMENTS_YAML_H
+#endif
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
index 769acd3253..89a4798b8c 100644
--- a/include/clang/Tooling/Tooling.h
+++ b/include/clang/Tooling/Tooling.h
@@ -30,6 +30,7 @@
#ifndef LLVM_CLANG_TOOLING_TOOLING_H
#define LLVM_CLANG_TOOLING_TOOLING_H
+#include "clang/AST/ASTConsumer.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h"
@@ -202,7 +203,9 @@ class ToolInvocation {
~ToolInvocation();
/// \brief Set a \c DiagnosticConsumer to use during parsing.
- void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer);
+ void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
+ this->DiagConsumer = DiagConsumer;
+ }
/// \brief Map a virtual file to be used while running the tool.
///
@@ -249,10 +252,12 @@ class ClangTool {
ClangTool(const CompilationDatabase &Compilations,
ArrayRef<std::string> SourcePaths);
- virtual ~ClangTool() { clearArgumentsAdjusters(); }
+ ~ClangTool();
/// \brief Set a \c DiagnosticConsumer to use during parsing.
- void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer);
+ void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
+ this->DiagConsumer = DiagConsumer;
+ }
/// \brief Map a virtual file to be used while running the tool.
///
@@ -260,14 +265,6 @@ class ClangTool {
/// \param Content A null terminated buffer of the file's content.
void mapVirtualFile(StringRef FilePath, StringRef Content);
- /// \brief Install command line arguments adjuster.
- ///
- /// \param Adjuster Command line arguments adjuster.
- //
- /// FIXME: Function is deprecated. Use (clear/append)ArgumentsAdjuster instead.
- /// Remove it once all callers are gone.
- void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster);
-
/// \brief Append a command line arguments adjuster to the adjuster chain.
///
/// \param Adjuster An argument adjuster, which will be run on the output of
@@ -292,14 +289,14 @@ class ClangTool {
FileManager &getFiles() { return *Files; }
private:
- // We store compile commands as pair (file name, compile command).
- std::vector< std::pair<std::string, CompileCommand> > CompileCommands;
+ const CompilationDatabase &Compilations;
+ std::vector<std::string> SourcePaths;
llvm::IntrusiveRefCntPtr<FileManager> Files;
// Contains a list of pairs (<file name>, <file content>).
std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
- SmallVector<ArgumentsAdjuster *, 2> ArgsAdjusters;
+ SmallVector<std::unique_ptr<ArgumentsAdjuster>, 2> ArgsAdjusters;
DiagnosticConsumer *DiagConsumer;
};
@@ -335,8 +332,8 @@ inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
SourceFileCallbacks *Callbacks)
: ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
- clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &,
- StringRef) override {
+ std::unique_ptr<clang::ASTConsumer>
+ CreateASTConsumer(clang::CompilerInstance &, StringRef) override {
return ConsumerFactory->newASTConsumer();
}
diff --git a/include/clang/module.modulemap b/include/clang/module.modulemap
index 03806016cc..5058d15025 100644
--- a/include/clang/module.modulemap
+++ b/include/clang/module.modulemap
@@ -39,6 +39,7 @@ module Clang_Basic {
exclude header "Basic/BuiltinsR600.def"
exclude header "Basic/BuiltinsX86.def"
exclude header "Basic/BuiltinsXCore.def"
+ exclude header "Basic/BuiltinsLe64.def"
exclude header "Basic/DiagnosticOptions.def"
exclude header "Basic/LangOptions.def"
exclude header "Basic/OpenCLExtensions.def"
@@ -47,9 +48,6 @@ module Clang_Basic {
exclude header "Basic/Sanitizers.def"
exclude header "Basic/TokenKinds.def"
- // This file is one big layering violation.
- exclude header "Basic/AllDiagnostics.h"
-
// This file includes a header from Lex.
exclude header "Basic/PlistSupport.h"
@@ -62,6 +60,24 @@ module Clang_Basic {
module Clang_CodeGen { requires cplusplus umbrella "CodeGen" module * { export * } }
module Clang_Config { requires cplusplus umbrella "Config" module * { export * } }
+// Files for diagnostic groups are spread all over the include/clang/ tree, but
+// logically form a single module.
+module Clang_Diagnostics {
+ requires cplusplus
+
+ module All { header "Basic/AllDiagnostics.h" export * }
+ module Analysis { header "Analysis/AnalysisDiagnostic.h" export * }
+ module AST { header "AST/ASTDiagnostic.h" export * }
+ module Comment { header "AST/CommentDiagnostic.h" export * }
+ module Driver { header "Driver/DriverDiagnostic.h" export * }
+ module Frontend { header "Frontend/FrontendDiagnostic.h" export * }
+ module Lex { header "Lex/LexDiagnostic.h" export * }
+ module Parse { header "Parse/ParseDiagnostic.h" export * }
+ // FIXME: This breaks the build of Clang_Sema, for unknown reasons.
+ //module Sema { header "Sema/SemaDiagnostic.h" export * }
+ module Serialization { header "Serialization/SerializationDiagnostic.h" export * }
+}
+
module Clang_Driver {
requires cplusplus
umbrella "Driver"
@@ -101,9 +117,6 @@ module Clang_StaticAnalyzer {
// This file is intended for repeated textual inclusion.
exclude header "StaticAnalyzer/Core/Analyses.def"
- // FIXME: This is logically a part of Basic, but has been put in the wrong place.
- exclude header "StaticAnalyzer/Core/AnalyzerOptions.h"
-
module * { export * }
}