aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:08 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:08 +0000
commitbab175ec4b075c8076ba14c762900392533f6ee4 (patch)
tree01f4f29419a2cb10abe13c1e63cd2a66068b0137 /include
parent8b7a8012d223fac5d17d16a66bb39168a9a1dfc0 (diff)
downloadsrc-bab175ec4b075c8076ba14c762900392533f6ee4.tar.gz
src-bab175ec4b075c8076ba14c762900392533f6ee4.zip
Vendor import of clang trunk r290819:vendor/clang/clang-trunk-r290819
Notes
Notes: svn path=/vendor/clang/dist/; revision=311118 svn path=/vendor/clang/clang-trunk-r290819/; revision=311119; tag=vendor/clang/clang-trunk-r290819
Diffstat (limited to 'include')
-rw-r--r--include/clang-c/Index.h81
-rw-r--r--include/clang/AST/APValue.h14
-rw-r--r--include/clang/AST/ASTConsumer.h2
-rw-r--r--include/clang/AST/ASTContext.h248
-rw-r--r--include/clang/AST/ASTImporter.h19
-rw-r--r--include/clang/AST/ASTMutationListener.h4
-rw-r--r--include/clang/AST/ASTTypeTraits.h6
-rw-r--r--include/clang/AST/ASTVector.h3
-rw-r--r--include/clang/AST/Attr.h11
-rw-r--r--include/clang/AST/AttrIterator.h3
-rw-r--r--include/clang/AST/CXXInheritance.h4
-rw-r--r--include/clang/AST/CanonicalType.h8
-rw-r--r--include/clang/AST/CommentLexer.h1
-rw-r--r--include/clang/AST/Decl.h135
-rw-r--r--include/clang/AST/DeclBase.h20
-rw-r--r--include/clang/AST/DeclCXX.h322
-rw-r--r--include/clang/AST/DeclFriend.h2
-rw-r--r--include/clang/AST/DeclGroup.h2
-rw-r--r--include/clang/AST/DeclObjC.h8
-rw-r--r--include/clang/AST/DeclOpenMP.h11
-rw-r--r--include/clang/AST/DeclTemplate.h81
-rw-r--r--include/clang/AST/Expr.h139
-rw-r--r--include/clang/AST/ExprCXX.h89
-rw-r--r--include/clang/AST/ExprObjC.h2
-rw-r--r--include/clang/AST/Mangle.h8
-rw-r--r--include/clang/AST/MangleNumberingContext.h3
-rw-r--r--include/clang/AST/OpenMPClause.h233
-rw-r--r--include/clang/AST/OperationKinds.def5
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h145
-rw-r--r--include/clang/AST/Redeclarable.h65
-rw-r--r--include/clang/AST/Stmt.h23
-rw-r--r--include/clang/AST/StmtCXX.h13
-rw-r--r--include/clang/AST/StmtGraphTraits.h14
-rw-r--r--include/clang/AST/StmtOpenMP.h552
-rw-r--r--include/clang/AST/TemplateBase.h14
-rw-r--r--include/clang/AST/Type.h285
-rw-r--r--include/clang/AST/TypeLoc.h127
-rw-r--r--include/clang/AST/TypeNodes.def1
-rw-r--r--include/clang/AST/UnresolvedSet.h5
-rw-r--r--include/clang/AST/VTTBuilder.h1
-rw-r--r--include/clang/AST/VTableBuilder.h144
-rw-r--r--include/clang/ASTMatchers/ASTMatchFinder.h7
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h245
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h29
-rw-r--r--include/clang/ASTMatchers/ASTMatchersMacros.h4
-rw-r--r--include/clang/ASTMatchers/Dynamic/Registry.h33
-rw-r--r--include/clang/ASTMatchers/Dynamic/VariantValue.h5
-rw-r--r--include/clang/Analysis/Analyses/Consumed.h5
-rw-r--r--include/clang/Analysis/Analyses/Dominators.h28
-rw-r--r--include/clang/Analysis/Analyses/FormatString.h49
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h1
-rw-r--r--include/clang/Analysis/Analyses/OSLog.h155
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyCommon.h21
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyUtil.h2
-rw-r--r--include/clang/Analysis/AnalysisContext.h3
-rw-r--r--include/clang/Analysis/CFG.h152
-rw-r--r--include/clang/Analysis/CallGraph.h60
-rw-r--r--include/clang/Analysis/CloneDetection.h288
-rw-r--r--include/clang/Analysis/ProgramPoint.h4
-rw-r--r--include/clang/Basic/Attr.td90
-rw-r--r--include/clang/Basic/AttrDocs.td550
-rw-r--r--include/clang/Basic/Attributes.h2
-rw-r--r--include/clang/Basic/Builtins.def106
-rw-r--r--include/clang/Basic/Builtins.h7
-rw-r--r--include/clang/Basic/BuiltinsAMDGPU.def20
-rw-r--r--include/clang/Basic/BuiltinsARM.def27
-rw-r--r--include/clang/Basic/BuiltinsNVPTX.def73
-rw-r--r--include/clang/Basic/BuiltinsPPC.def78
-rw-r--r--include/clang/Basic/BuiltinsX86.def459
-rw-r--r--include/clang/Basic/BuiltinsX86_64.def90
-rw-r--r--include/clang/Basic/DeclNodes.td4
-rw-r--r--include/clang/Basic/Diagnostic.h79
-rw-r--r--include/clang/Basic/Diagnostic.td3
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td6
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticDocs.td84
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td28
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td9
-rw-r--r--include/clang/Basic/DiagnosticGroups.td51
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td11
-rw-r--r--include/clang/Basic/DiagnosticOptions.def1
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td94
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td663
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td6
-rw-r--r--include/clang/Basic/FileManager.h43
-rw-r--r--include/clang/Basic/FileSystemStatCache.h8
-rw-r--r--include/clang/Basic/IdentifierTable.h75
-rw-r--r--include/clang/Basic/LLVM.h4
-rw-r--r--include/clang/Basic/LangOptions.def13
-rw-r--r--include/clang/Basic/LangOptions.h19
-rw-r--r--include/clang/Basic/Linkage.h4
-rw-r--r--include/clang/Basic/Module.h4
-rw-r--r--include/clang/Basic/ObjCRuntime.h1
-rw-r--r--include/clang/Basic/OpenCLExtensions.def5
-rw-r--r--include/clang/Basic/OpenCLImageTypes.def100
-rw-r--r--include/clang/Basic/OpenCLOptions.h124
-rw-r--r--include/clang/Basic/OpenMPKinds.def183
-rw-r--r--include/clang/Basic/OpenMPKinds.h22
-rw-r--r--include/clang/Basic/PlistSupport.h1
-rw-r--r--include/clang/Basic/SourceManager.h64
-rw-r--r--include/clang/Basic/SourceManagerInternals.h4
-rw-r--r--include/clang/Basic/Specifiers.h2
-rw-r--r--include/clang/Basic/StmtNodes.td10
-rw-r--r--include/clang/Basic/TargetBuiltins.h12
-rw-r--r--include/clang/Basic/TargetCXXABI.h1
-rw-r--r--include/clang/Basic/TargetInfo.h58
-rw-r--r--include/clang/Basic/TargetOptions.h4
-rw-r--r--include/clang/Basic/TokenKinds.def10
-rw-r--r--include/clang/Basic/Version.h20
-rw-r--r--include/clang/Basic/Version.inc.in3
-rw-r--r--include/clang/Basic/VirtualFileSystem.h63
-rw-r--r--include/clang/CodeGen/CGFunctionInfo.h23
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h1
-rw-r--r--include/clang/CodeGen/ObjectFilePCHContainerOperations.h6
-rw-r--r--include/clang/CodeGen/SwiftCallingConv.h6
-rw-r--r--include/clang/Config/config.h.cmake9
-rw-r--r--include/clang/Driver/Action.h95
-rw-r--r--include/clang/Driver/CC1Options.td51
-rw-r--r--include/clang/Driver/CLCompatOptions.td15
-rw-r--r--include/clang/Driver/Compilation.h41
-rw-r--r--include/clang/Driver/Distro.h122
-rw-r--r--include/clang/Driver/Driver.h102
-rw-r--r--include/clang/Driver/Job.h3
-rw-r--r--include/clang/Driver/Multilib.h1
-rw-r--r--include/clang/Driver/Options.td188
-rw-r--r--include/clang/Driver/SanitizerArgs.h4
-rw-r--r--include/clang/Driver/Tool.h14
-rw-r--r--include/clang/Driver/ToolChain.h55
-rw-r--r--include/clang/Driver/Types.def3
-rw-r--r--include/clang/Driver/Types.h19
-rw-r--r--include/clang/Edit/Rewriters.h1
-rw-r--r--include/clang/Format/Format.h49
-rw-r--r--include/clang/Frontend/ASTUnit.h8
-rw-r--r--include/clang/Frontend/CodeGenOptions.def33
-rw-r--r--include/clang/Frontend/CodeGenOptions.h24
-rw-r--r--include/clang/Frontend/CompilerInstance.h9
-rw-r--r--include/clang/Frontend/CompilerInvocation.h15
-rw-r--r--include/clang/Frontend/DiagnosticRenderer.h1
-rw-r--r--include/clang/Frontend/FrontendActions.h39
-rw-r--r--include/clang/Frontend/FrontendOptions.h7
-rw-r--r--include/clang/Frontend/FrontendPluginRegistry.h3
-rw-r--r--include/clang/Frontend/LangStandards.def2
-rw-r--r--include/clang/Frontend/PCHContainerOperations.h12
-rw-r--r--include/clang/Frontend/PreprocessorOutputOptions.h2
-rw-r--r--include/clang/Frontend/SerializedDiagnosticReader.h1
-rw-r--r--include/clang/Frontend/TextDiagnostic.h2
-rw-r--r--include/clang/Frontend/Utils.h4
-rw-r--r--include/clang/Index/CommentToXML.h5
-rw-r--r--include/clang/Index/IndexSymbol.h20
-rw-r--r--include/clang/Lex/DirectoryLookup.h2
-rw-r--r--include/clang/Lex/HeaderMap.h2
-rw-r--r--include/clang/Lex/HeaderSearch.h27
-rw-r--r--include/clang/Lex/HeaderSearchOptions.h14
-rw-r--r--include/clang/Lex/LiteralSupport.h2
-rw-r--r--include/clang/Lex/ModuleLoader.h25
-rw-r--r--include/clang/Lex/ModuleMap.h44
-rw-r--r--include/clang/Lex/PPCallbacks.h4
-rw-r--r--include/clang/Lex/PTHManager.h7
-rw-r--r--include/clang/Lex/PreprocessingRecord.h23
-rw-r--r--include/clang/Lex/Preprocessor.h47
-rw-r--r--include/clang/Lex/PreprocessorOptions.h1
-rw-r--r--include/clang/Parse/Parser.h91
-rw-r--r--include/clang/Rewrite/Core/HTMLRewrite.h4
-rw-r--r--include/clang/Sema/AttributeList.h24
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h17
-rw-r--r--include/clang/Sema/DeclSpec.h251
-rw-r--r--include/clang/Sema/DelayedDiagnostic.h44
-rw-r--r--include/clang/Sema/ExternalSemaSource.h3
-rw-r--r--include/clang/Sema/Initialization.h90
-rw-r--r--include/clang/Sema/MultiplexExternalSemaSource.h4
-rw-r--r--include/clang/Sema/Overload.h37
-rw-r--r--include/clang/Sema/Ownership.h1
-rw-r--r--include/clang/Sema/ScopeInfo.h18
-rw-r--r--include/clang/Sema/Sema.h914
-rw-r--r--include/clang/Sema/SemaInternal.h6
-rw-r--r--include/clang/Sema/Template.h9
-rw-r--r--include/clang/Sema/TemplateDeduction.h23
-rw-r--r--include/clang/Sema/TypoCorrection.h11
-rw-r--r--include/clang/Serialization/ASTBitCodes.h65
-rw-r--r--include/clang/Serialization/ASTReader.h349
-rw-r--r--include/clang/Serialization/ASTWriter.h29
-rw-r--r--include/clang/Serialization/Module.h10
-rw-r--r--include/clang/Serialization/ModuleManager.h2
-rw-r--r--include/clang/StaticAnalyzer/Checkers/Checkers.td99
-rw-r--r--include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h97
-rw-r--r--include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h10
-rw-r--r--include/clang/StaticAnalyzer/Checkers/SValExplainer.h15
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h16
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h70
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h24
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugType.h1
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h26
-rw-r--r--include/clang/StaticAnalyzer/Core/Checker.h9
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h14
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerRegistry.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h48
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h35
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h5
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h51
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h23
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h6
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h77
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h10
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h18
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def1
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h46
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h8
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h3
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h18
-rw-r--r--include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h5
-rw-r--r--include/clang/StaticAnalyzer/Frontend/FrontendActions.h3
-rw-r--r--include/clang/Tooling/CompilationDatabase.h8
-rw-r--r--include/clang/Tooling/Core/Replacement.h236
-rw-r--r--include/clang/Tooling/FileMatchTrie.h7
-rw-r--r--include/clang/Tooling/JSONCompilationDatabase.h23
-rw-r--r--include/clang/Tooling/Refactoring.h22
-rw-r--r--include/clang/Tooling/ReplacementsYaml.h1
-rw-r--r--include/clang/module.modulemap1
219 files changed, 8807 insertions, 2781 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 13db2085ba69..47998859f674 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -32,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 35
+#define CINDEX_VERSION_MINOR 37
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -326,7 +326,7 @@ clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file);
*
* \param tu the translation unit
*
-* \param file_name the name of the file.
+ * \param file_name the name of the file.
*
* \returns the file handle for the named file in the translation unit \p tu,
* or a NULL file handle if the file was not a part of this translation unit.
@@ -627,6 +627,15 @@ CINDEX_LINKAGE CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit tu,
CXFile file);
/**
+ * \brief Retrieve all ranges from all files that were skipped by the
+ * preprocessor.
+ *
+ * The preprocessor will skip lines when they are surrounded by an
+ * if/ifdef/ifndef directive whose condition does not evaluate to true.
+ */
+CINDEX_LINKAGE CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit tu);
+
+/**
* \brief Destroy the given \c CXSourceRangeList.
*/
CINDEX_LINKAGE void clang_disposeSourceRangeList(CXSourceRangeList *ranges);
@@ -2325,7 +2334,39 @@ enum CXCursorKind {
*/
CXCursor_OMPTargetParallelForSimdDirective = 269,
- CXCursor_LastStmt = CXCursor_OMPTargetParallelForSimdDirective,
+ /** \brief OpenMP target simd directive.
+ */
+ CXCursor_OMPTargetSimdDirective = 270,
+
+ /** \brief OpenMP teams distribute directive.
+ */
+ CXCursor_OMPTeamsDistributeDirective = 271,
+
+ /** \brief OpenMP teams distribute simd directive.
+ */
+ CXCursor_OMPTeamsDistributeSimdDirective = 272,
+
+ /** \brief OpenMP teams distribute parallel for simd directive.
+ */
+ CXCursor_OMPTeamsDistributeParallelForSimdDirective = 273,
+
+ /** \brief OpenMP teams distribute parallel for directive.
+ */
+ CXCursor_OMPTeamsDistributeParallelForDirective = 274,
+
+ /** \brief OpenMP target teams directive.
+ */
+ CXCursor_OMPTargetTeamsDirective = 275,
+
+ /** \brief OpenMP target teams distribute directive.
+ */
+ CXCursor_OMPTargetTeamsDistributeDirective = 276,
+
+ /** \brief OpenMP target teams distribute parallel for directive.
+ */
+ CXCursor_OMPTargetTeamsDistributeParallelForDirective = 277,
+
+ CXCursor_LastStmt = CXCursor_OMPTargetTeamsDistributeParallelForDirective,
/**
* \brief Cursor that represents the translation unit itself.
@@ -2383,8 +2424,12 @@ enum CXCursorKind {
* \brief A static_assert or _Static_assert node
*/
CXCursor_StaticAssert = 602,
+ /**
+ * \brief a friend declaration.
+ */
+ CXCursor_FriendDecl = 603,
CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl,
- CXCursor_LastExtraDecl = CXCursor_StaticAssert,
+ CXCursor_LastExtraDecl = CXCursor_FriendDecl,
/**
* \brief A code completion overload candidate.
@@ -3001,7 +3046,7 @@ enum CXCallingConv {
CXCallingConv_X86Pascal = 5,
CXCallingConv_AAPCS = 6,
CXCallingConv_AAPCS_VFP = 7,
- /* Value 8 was PnaclCall, but it was never used, so it could safely be re-used. */
+ CXCallingConv_X86RegCall = 8,
CXCallingConv_IntelOclBicc = 9,
CXCallingConv_X86_64Win64 = 10,
CXCallingConv_X86_64SysV = 11,
@@ -3491,11 +3536,8 @@ enum CXRefQualifierKind {
};
/**
- * \brief Returns the number of template arguments for given class template
- * specialization, or -1 if type \c T is not a class template specialization.
- *
- * Variadic argument packs count as only one argument, and can not be inspected
- * further.
+ * \brief Returns the number of template arguments for given template
+ * specialization, or -1 if type \c T is not a template specialization.
*/
CINDEX_LINKAGE int clang_Type_getNumTemplateArguments(CXType T);
@@ -5240,6 +5282,25 @@ CINDEX_LINKAGE CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E);
CINDEX_LINKAGE int clang_EvalResult_getAsInt(CXEvalResult E);
/**
+ * \brief Returns the evaluation result as a long long integer if the
+ * kind is Int. This prevents overflows that may happen if the result is
+ * returned with clang_EvalResult_getAsInt.
+ */
+CINDEX_LINKAGE long long clang_EvalResult_getAsLongLong(CXEvalResult E);
+
+/**
+ * \brief Returns a non-zero value if the kind is Int and the evaluation
+ * result resulted in an unsigned integer.
+ */
+CINDEX_LINKAGE unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E);
+
+/**
+ * \brief Returns the evaluation result as an unsigned integer if
+ * the kind is Int and clang_EvalResult_isUnsignedInt is non-zero.
+ */
+CINDEX_LINKAGE unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E);
+
+/**
* \brief Returns the evaluation result as double if the
* kind is double.
*/
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index e58c21923f51..7c431f3be8c4 100644
--- a/include/clang/AST/APValue.h
+++ b/include/clang/AST/APValue.h
@@ -135,14 +135,15 @@ public:
}
APValue(const APValue &RHS);
APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
- APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
+ APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex,
+ bool IsNullPtr = false)
: Kind(Uninitialized) {
- MakeLValue(); setLValue(B, O, N, CallIndex);
+ MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr);
}
APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
- bool OnePastTheEnd, unsigned CallIndex)
+ bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false)
: Kind(Uninitialized) {
- MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex);
+ MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr);
}
APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
MakeArray(InitElts, Size);
@@ -254,6 +255,7 @@ public:
bool hasLValuePath() const;
ArrayRef<LValuePathEntry> getLValuePath() const;
unsigned getLValueCallIndex() const;
+ bool isNullPointer() const;
APValue &getVectorElt(unsigned I) {
assert(isVector() && "Invalid accessor");
@@ -374,10 +376,10 @@ public:
((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
}
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
- unsigned CallIndex);
+ unsigned CallIndex, bool IsNullPtr);
void setLValue(LValueBase B, const CharUnits &O,
ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
- unsigned CallIndex);
+ unsigned CallIndex, bool IsNullPtr);
void setUnion(const FieldDecl *Field, const APValue &Value) {
assert(isUnion() && "Invalid accessor");
((UnionData*)(char*)Data.buffer)->Field = Field;
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 0b1f0068fa6f..ad368c86c79c 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -14,8 +14,6 @@
#ifndef LLVM_CLANG_AST_ASTCONSUMER_H
#define LLVM_CLANG_AST_ASTCONSUMER_H
-#include "llvm/ADT/StringRef.h"
-
namespace clang {
class ASTContext;
class CXXMethodDecl;
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 1d223f47a9ae..1c9ce821438d 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -19,73 +19,107 @@
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RawCommentList.h"
+#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Linkage.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SanitizerBlacklist.h"
-#include "clang/Basic/VersionTuple.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
#include <memory>
+#include <new>
+#include <string>
+#include <utility>
#include <vector>
namespace llvm {
- struct fltSemantics;
-}
+
+struct fltSemantics;
+
+} // end namespace llvm
namespace clang {
- class FileManager;
- class AtomicExpr;
- class ASTRecordLayout;
- class BlockExpr;
- class CharUnits;
- class DiagnosticsEngine;
- class Expr;
- class ASTMutationListener;
- class IdentifierTable;
- class MaterializeTemporaryExpr;
- class SelectorTable;
- class TargetInfo;
- class CXXABI;
- class MangleNumberingContext;
- // Decls
- class MangleContext;
- class ObjCIvarDecl;
- class ObjCPropertyDecl;
- class UnresolvedSetIterator;
- class UsingDecl;
- class UsingShadowDecl;
- class VTableContextBase;
-
- namespace Builtin { class Context; }
- enum BuiltinTemplateKind : int;
-
- namespace comments {
- class FullComment;
- }
-
- struct TypeInfo {
- uint64_t Width;
- unsigned Align;
- bool AlignIsRequired : 1;
- TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {}
- TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
- : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
- };
+
+class ASTMutationListener;
+class ASTRecordLayout;
+class AtomicExpr;
+class BlockExpr;
+class CharUnits;
+class CXXABI;
+class DiagnosticsEngine;
+class Expr;
+class MangleNumberingContext;
+class MaterializeTemporaryExpr;
+class TargetInfo;
+// Decls
+class MangleContext;
+class ObjCIvarDecl;
+class ObjCPropertyDecl;
+class UnresolvedSetIterator;
+class UsingDecl;
+class UsingShadowDecl;
+class VTableContextBase;
+
+namespace Builtin {
+
+ class Context;
+
+} // end namespace Builtin
+
+enum BuiltinTemplateKind : int;
+
+namespace comments {
+
+ class FullComment;
+
+} // end namespace comments
+
+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.
@@ -114,6 +148,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
mutable llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
+ mutable llvm::FoldingSet<ObjCTypeParamType> ObjCTypeParamTypes;
mutable llvm::FoldingSet<SubstTemplateTypeParmType>
SubstTemplateTypeParmTypes;
mutable llvm::FoldingSet<SubstTemplateTypeParmPackType>
@@ -312,13 +347,24 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// definitions of that entity.
llvm::DenseMap<NamedDecl*, llvm::TinyPtrVector<Module*>> MergedDefModules;
+ /// \brief Initializers for a module, in order. Each Decl will be either
+ /// something that has a semantic effect on startup (such as a variable with
+ /// a non-constant initializer), or an ImportDecl (which recursively triggers
+ /// initialization of another module).
+ struct PerModuleInitializers {
+ llvm::SmallVector<Decl*, 4> Initializers;
+ llvm::SmallVector<uint32_t, 4> LazyInitializers;
+
+ void resolve(ASTContext &Ctx);
+ };
+ llvm::DenseMap<Module*, PerModuleInitializers*> ModuleInitializers;
+
public:
/// \brief A type synonym for the TemplateOrInstantiation mapping.
typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>
TemplateOrSpecializationInfo;
private:
-
/// \brief A mapping to contain the template or declaration that
/// a variable declaration describes or was instantiated from,
/// respectively.
@@ -352,11 +398,11 @@ private:
llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>
TemplateOrInstantiation;
- /// \brief Keeps track of the declaration from which a UsingDecl was
+ /// \brief Keeps track of the declaration from which a using declaration was
/// created during instantiation.
///
- /// The source declaration is always a UsingDecl, an UnresolvedUsingValueDecl,
- /// or an UnresolvedUsingTypenameDecl.
+ /// The source and target declarations are always a UsingDecl, an
+ /// UnresolvedUsingValueDecl, or an UnresolvedUsingTypenameDecl.
///
/// For example:
/// \code
@@ -375,7 +421,7 @@ private:
///
/// This mapping will contain an entry that maps from the UsingDecl in
/// B<int> to the UnresolvedUsingDecl in B<T>.
- llvm::DenseMap<UsingDecl *, NamedDecl *> InstantiatedFromUsingDecl;
+ llvm::DenseMap<NamedDecl *, NamedDecl *> InstantiatedFromUsingDecl;
llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>
InstantiatedFromUsingShadowDecl;
@@ -394,7 +440,7 @@ private:
/// \brief Mapping from each declaration context to its corresponding
/// mangling numbering context (used for constructs like lambdas which
/// need to be consistently numbered for the mangler).
- llvm::DenseMap<const DeclContext *, MangleNumberingContext *>
+ llvm::DenseMap<const DeclContext *, std::unique_ptr<MangleNumberingContext>>
MangleNumberingContexts;
/// \brief Side-table of mangling numbers for declarations which rarely
@@ -514,6 +560,7 @@ public:
size_t size() const { return end() - begin(); }
bool empty() const { return begin() == end(); }
+
const DynTypedNode &operator[](size_t N) const {
assert(N < size() && "Out of bounds!");
return *(begin() + N);
@@ -569,7 +616,7 @@ public:
return BumpAlloc.Allocate(Size, Align);
}
template <typename T> T *Allocate(size_t Num = 1) const {
- return static_cast<T *>(Allocate(Num * sizeof(T), llvm::alignOf<T>()));
+ return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
}
void Deallocate(void *Ptr) const { }
@@ -802,11 +849,11 @@ public:
/// \brief If the given using decl \p Inst is an instantiation of a
/// (possibly unresolved) using decl from a template instantiation,
/// return it.
- NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst);
+ NamedDecl *getInstantiatedFromUsingDecl(NamedDecl *Inst);
/// \brief Remember that the using decl \p Inst is an instantiation
/// of the using decl \p Pattern of a class template.
- void setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern);
+ void setInstantiatedFromUsingDecl(NamedDecl *Inst, NamedDecl *Pattern);
void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
UsingShadowDecl *Pattern);
@@ -883,6 +930,17 @@ public:
return MergedIt->second;
}
+ /// Add a declaration to the list of declarations that are initialized
+ /// for a module. This will typically be a global variable (with internal
+ /// linkage) that runs module initializers, such as the iostream initializer,
+ /// or an ImportDecl nominating another module that has initializers.
+ void addModuleInitializer(Module *M, Decl *Init);
+
+ void addLazyModuleInitializers(Module *M, ArrayRef<uint32_t> IDs);
+
+ /// Get the initializations to perform when importing a module, if any.
+ ArrayRef<Decl*> getModuleInitializers(Module *M);
+
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
ExternCContextDecl *getExternCContextDecl() const;
@@ -928,7 +986,8 @@ public:
ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
SelectorTable &sels, Builtin::Context &builtins);
-
+ ASTContext(const ASTContext &) = delete;
+ ASTContext &operator=(const ASTContext &) = delete;
~ASTContext();
/// \brief Attach an external AST source to the AST context.
@@ -987,6 +1046,8 @@ private:
QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const;
+ QualType getPipeType(QualType T, bool ReadOnly) const;
+
public:
/// \brief Return the uniqued reference to the type for an address space
/// qualified type with the specified type and address space.
@@ -996,6 +1057,14 @@ public:
/// replaced.
QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const;
+ /// \brief Apply Objective-C protocol qualifiers to the given type.
+ /// \param allowOnPointerType specifies if we can apply protocol
+ /// qualifiers on ObjCObjectPointerType. It can be set to true when
+ /// contructing the canonical type of a Objective-C type parameter.
+ QualType applyObjCProtocolQualifiers(QualType type,
+ ArrayRef<ObjCProtocolDecl *> protocols, bool &hasError,
+ bool allowOnPointerType = false) const;
+
/// \brief Return the uniqued reference to the type for an Objective-C
/// gc-qualified type.
///
@@ -1040,6 +1109,10 @@ public:
/// \brief Change the result type of a function type once it is deduced.
void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
+ /// \brief Determine whether two function types are the same, ignoring
+ /// exception specifications in cases where they're part of the type.
+ bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U);
+
/// \brief Change the exception specification on a function once it is
/// delay-parsed, instantiated, or computed.
void adjustExceptionSpec(FunctionDecl *FD,
@@ -1088,8 +1161,10 @@ public:
/// blocks.
QualType getBlockDescriptorType() const;
- /// \brief Return pipe type for the specified type.
- QualType getPipeType(QualType T) const;
+ /// \brief Return a read_only pipe type for the specified type.
+ QualType getReadPipeType(QualType T) const;
+ /// \brief Return a write_only pipe type for the specified type.
+ QualType getWritePipeType(QualType T) const;
/// Gets the struct used to keep track of the extended descriptor for
/// pointer to blocks.
@@ -1192,8 +1267,17 @@ public:
/// \brief Return a normal function type with a typed argument list.
QualType getFunctionType(QualType ResultTy, ArrayRef<QualType> Args,
- const FunctionProtoType::ExtProtoInfo &EPI) const;
+ const FunctionProtoType::ExtProtoInfo &EPI) const {
+ return getFunctionTypeInternal(ResultTy, Args, EPI, false);
+ }
+
+private:
+ /// \brief Return a normal function type with a typed argument list.
+ QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef<QualType> Args,
+ const FunctionProtoType::ExtProtoInfo &EPI,
+ bool OnlyWantCanonical) const;
+public:
/// \brief Return the unique reference to the type for the specified type
/// declaration.
QualType getTypeDeclType(const TypeDecl *Decl,
@@ -1271,6 +1355,12 @@ public:
ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const;
+ /// Get a template argument list with one argument per template parameter
+ /// in a template parameter list, such as for the injected class name of
+ /// a class template.
+ void getInjectedTemplateArgs(const TemplateParameterList *Params,
+ SmallVectorImpl<TemplateArgument> &Args);
+
QualType getPackExpansionType(QualType Pattern,
Optional<unsigned> NumExpansions);
@@ -1286,6 +1376,10 @@ public:
ArrayRef<QualType> typeArgs,
ArrayRef<ObjCProtocolDecl *> protocols,
bool isKindOf) const;
+
+ QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
+ ArrayRef<ObjCProtocolDecl *> protocols,
+ QualType Canonical = QualType()) const;
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
/// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
@@ -1440,7 +1534,6 @@ public:
return getObjCSelType();
return ObjCSelRedefinitionType;
}
-
/// \brief Set the user-written type that redefines 'SEL'.
void setObjCSelRedefinitionType(QualType RedefType) {
@@ -1569,16 +1662,12 @@ public:
///
/// \returns true if an error occurred (e.g., because one of the parameter
/// types is incomplete), false otherwise.
- bool getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S);
+ std::string getObjCEncodingForFunctionDecl(const FunctionDecl *Decl) const;
/// \brief Emit the encoded type for the method declaration \p Decl into
/// \p S.
- ///
- /// \returns true if an error occurred (e.g., because one of the parameter
- /// types is incomplete), false otherwise.
- bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S,
- bool Extended = false)
- const;
+ std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
+ bool Extended = false) const;
/// \brief Return the encoded type for this block declaration.
std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const;
@@ -1587,9 +1676,8 @@ public:
/// this method declaration. If non-NULL, Container must be either
/// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
/// only be NULL when getting encodings for protocol properties.
- void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
- const Decl *Container,
- std::string &S) const;
+ std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
+ const Decl *Container) const;
bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
ObjCProtocolDecl *rProto) const;
@@ -1834,6 +1922,11 @@ public:
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 type, in bits, or 0 if
+ /// the type is incomplete and we cannot determine the alignment (for
+ /// example, from alignment attributes).
+ unsigned getTypeAlignIfKnown(QualType T) const;
+
/// \brief Return the ABI-specified alignment of a (complete) type \p T, in
/// characters.
CharUnits getTypeAlignInChars(QualType T) const;
@@ -1860,7 +1953,7 @@ public:
/// \brief Return the default alignment for __attribute__((aligned)) on
/// this target, to be used if no alignment value is specified.
- unsigned getTargetDefaultAlignForAttributeAligned(void) const;
+ unsigned getTargetDefaultAlignForAttributeAligned() const;
/// \brief Return the alignment in bits that should be given to a
/// global variable with type \p T.
@@ -2212,6 +2305,10 @@ public:
return (*AddrSpaceMap)[AS - LangAS::Offset];
}
+ /// Get target-dependent integer value for null pointer which is used for
+ /// constant folding.
+ uint64_t getTargetNullPointerValue(QualType QT) const;
+
bool addressSpaceMapManglingFor(unsigned AS) const {
return AddrSpaceMapMangling ||
AS < LangAS::Offset ||
@@ -2223,7 +2320,6 @@ private:
unsigned getIntegerRank(const Type *T) const;
public:
-
//===--------------------------------------------------------------------===//
// Type Compatibility Predicates
//===--------------------------------------------------------------------===//
@@ -2399,12 +2495,6 @@ public:
void addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
CXXConstructorDecl *CD);
- void addDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
- unsigned ParmIdx, Expr *DAE);
-
- Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
- unsigned ParmIdx);
-
void addTypedefNameForUnnamedTagDecl(TagDecl *TD, TypedefNameDecl *TND);
TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD);
@@ -2423,7 +2513,7 @@ public:
/// DeclContext.
MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
- MangleNumberingContext *createMangleNumberingContext() const;
+ std::unique_ptr<MangleNumberingContext> createMangleNumberingContext() const;
/// \brief Used by ParmVarDecl to store on the side the
/// index of the parameter when it exceeds the size of the normal bitfield.
@@ -2484,10 +2574,6 @@ public:
/// declarations were built.
static unsigned NumImplicitDestructorsDeclared;
-private:
- ASTContext(const ASTContext &) = delete;
- void operator=(const ASTContext &) = delete;
-
public:
/// \brief Initialize built-in types.
///
@@ -2567,6 +2653,7 @@ private:
friend class DeclContext;
friend class DeclarationNameTable;
+
void ReleaseDeclContextMaps();
void ReleaseParentMapEntries();
@@ -2589,7 +2676,8 @@ public:
DeclaratorDecl *Decl;
SourceLocation PragmaSectionLocation;
int SectionFlags;
- SectionInfo() {}
+
+ SectionInfo() = default;
SectionInfo(DeclaratorDecl *Decl,
SourceLocation PragmaSectionLocation,
int SectionFlags)
@@ -2711,4 +2799,4 @@ typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType
return Value;
}
-#endif
+#endif // LLVM_CLANG_AST_ASTCONTEXT_H
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index e116abaef797..66b9cd394b9d 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -24,6 +24,7 @@
namespace clang {
class ASTContext;
class CXXCtorInitializer;
+ class CXXBaseSpecifier;
class Decl;
class DeclContext;
class DiagnosticsEngine;
@@ -39,7 +40,9 @@ namespace clang {
class ASTImporter {
public:
typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
-
+ typedef llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>
+ ImportedCXXBaseSpecifierMap;
+
private:
/// \brief The contexts we're importing to and from.
ASTContext &ToContext, &FromContext;
@@ -68,7 +71,12 @@ namespace clang {
/// \brief Mapping from the already-imported FileIDs in the "from" source
/// manager to the corresponding FileIDs in the "to" source manager.
llvm::DenseMap<FileID, FileID> ImportedFileIDs;
-
+
+ /// \brief Mapping from the already-imported CXXBasesSpecifier in
+ /// the "from" source manager to the corresponding CXXBasesSpecifier
+ /// in the "to" source manager.
+ ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers;
+
/// \brief Imported, anonymous tag declarations that are missing their
/// corresponding typedefs.
SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs;
@@ -212,8 +220,13 @@ namespace clang {
/// \returns the equivalent initializer in the "to" context.
CXXCtorInitializer *Import(CXXCtorInitializer *FromInit);
+ /// \brief Import the given CXXBaseSpecifier from the "from" context into
+ /// the "to" context.
+ ///
+ /// \returns the equivalent CXXBaseSpecifier in the source manager of the
+ /// "to" context.
+ CXXBaseSpecifier *Import(const CXXBaseSpecifier *FromSpec);
-
/// \brief Import the definition of the given declaration, including all of
/// the declarations it contains.
///
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index e2d184d654e3..a8eff1a2fcbb 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -22,6 +22,7 @@ namespace clang {
class CXXRecordDecl;
class Decl;
class DeclContext;
+ class FieldDecl;
class FunctionDecl;
class FunctionTemplateDecl;
class Module;
@@ -93,6 +94,9 @@ public:
/// \brief A default argument was instantiated.
virtual void DefaultArgumentInstantiated(const ParmVarDecl *D) {}
+ /// \brief A default member initializer was instantiated.
+ virtual void DefaultMemberInitializerInstantiated(const FieldDecl *D) {}
+
/// \brief A new objc category class was added for an interface.
virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) {}
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
index ad301b14829e..51d60a90a146 100644
--- a/include/clang/AST/ASTTypeTraits.h
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -121,6 +121,7 @@ private:
enum NodeKindId {
NKI_None,
NKI_TemplateArgument,
+ NKI_TemplateName,
NKI_NestedNameSpecifierLoc,
NKI_QualType,
NKI_TypeLoc,
@@ -175,6 +176,7 @@ private:
};
KIND_TO_KIND_ID(CXXCtorInitializer)
KIND_TO_KIND_ID(TemplateArgument)
+KIND_TO_KIND_ID(TemplateName)
KIND_TO_KIND_ID(NestedNameSpecifier)
KIND_TO_KIND_ID(NestedNameSpecifierLoc)
KIND_TO_KIND_ID(QualType)
@@ -472,6 +474,10 @@ struct DynTypedNode::BaseConverter<
template <>
struct DynTypedNode::BaseConverter<
+ TemplateName, void> : public ValueConverter<TemplateName> {};
+
+template <>
+struct DynTypedNode::BaseConverter<
NestedNameSpecifierLoc,
void> : public ValueConverter<NestedNameSpecifierLoc> {};
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 79453bf10871..9ae5fd62c65a 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -20,7 +20,6 @@
#include "clang/AST/AttrIterator.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Allocator.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cstring>
@@ -381,7 +380,7 @@ void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) {
NewCapacity = MinSize;
// Allocate the memory from the ASTContext.
- T *NewElts = new (C, llvm::alignOf<T>()) T[NewCapacity];
+ T *NewElts = new (C, alignof(T)) T[NewCapacity];
// Copy the elements over.
if (Begin != End) {
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index a94b161a04bc..bbe320c28a3b 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -24,8 +24,6 @@
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/VersionTuple.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
@@ -57,21 +55,20 @@ protected:
unsigned IsLateParsed : 1;
unsigned DuplicatesAllowed : 1;
- void *operator new(size_t bytes) LLVM_NOEXCEPT {
+ void *operator new(size_t bytes) noexcept {
llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
}
- void operator delete(void *data) LLVM_NOEXCEPT {
+ void operator delete(void *data) noexcept {
llvm_unreachable("Attrs cannot be released with regular 'delete'.");
}
public:
// Forward so that the regular new and delete do not hide global ones.
void *operator new(size_t Bytes, ASTContext &C,
- size_t Alignment = 8) LLVM_NOEXCEPT {
+ size_t Alignment = 8) noexcept {
return ::operator new(Bytes, C, Alignment);
}
- void operator delete(void *Ptr, ASTContext &C,
- size_t Alignment) LLVM_NOEXCEPT {
+ void operator delete(void *Ptr, ASTContext &C, size_t Alignment) noexcept {
return ::operator delete(Ptr, C, Alignment);
}
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index a0c803096af8..fb9b049e5d6b 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -39,8 +39,7 @@ void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
namespace clang {
/// AttrVec - A vector of Attr, which is how they are stored on the AST.
-typedef SmallVector<Attr*, 2> AttrVec;
-typedef SmallVector<const Attr*, 2> ConstAttrVec;
+typedef SmallVector<Attr *, 4> AttrVec;
/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
/// providing attributes that are of a specific type.
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 8587260049a0..3cf058f26bc6 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -16,7 +16,6 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.h"
#include "llvm/ADT/MapVector.h"
@@ -24,7 +23,6 @@
#include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <list>
-#include <map>
namespace clang {
@@ -174,7 +172,7 @@ public:
/// paths for a derived-to-base search.
explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true,
bool DetectVirtual = true)
- : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
+ : Origin(), FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
DetectVirtual(DetectVirtual), DetectedVirtual(nullptr),
NumDeclsFound(0) {}
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 77510afeec1b..25f6172be9b1 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -630,8 +630,8 @@ CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
template<typename T>
template<typename U>
CanProxy<U> CanQual<T>::getAs() const {
- ArrayType_cannot_be_used_with_getAs<U> at;
- (void)at;
+ static_assert(!TypeIsArrayType<T>::value,
+ "ArrayType cannot be used with getAs!");
if (Stored.isNull())
return CanProxy<U>();
@@ -645,8 +645,8 @@ CanProxy<U> CanQual<T>::getAs() const {
template<typename T>
template<typename U>
CanProxy<U> CanQual<T>::castAs() const {
- ArrayType_cannot_be_used_with_getAs<U> at;
- (void)at;
+ static_assert(!TypeIsArrayType<U>::value,
+ "ArrayType cannot be used with castAs!");
assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
return CanQual<U>::CreateUnsafe(Stored);
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index f190b932c0a0..5bb075807be5 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -17,7 +17,6 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 109036f9588e..b2e332d6d85c 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -251,7 +251,7 @@ public:
// FIXME: Deprecated, move clients to getName().
std::string getNameAsString() const { return Name.getAsString(); }
- void printName(raw_ostream &os) const { os << Name; }
+ virtual void printName(raw_ostream &os) const;
/// getDeclName - Get the actual, stored name of the declaration,
/// which may be a special name.
@@ -789,7 +789,7 @@ public:
protected:
// A pointer union of Stmt * and EvaluatedStmt *. When an EvaluatedStmt, we
- // have allocated the auxilliary struct of information there.
+ // have allocated the auxiliary struct of information there.
//
// TODO: It is a bit unfortunate to use a PointerUnion inside the VarDecl for
// this as *many* VarDecls are ParmVarDecls that don't have default
@@ -865,6 +865,11 @@ protected:
unsigned : NumVarDeclBits;
+ // FIXME: We need something similar to CXXRecordDecl::DefinitionData.
+ /// \brief Whether this variable is a definition which was demoted due to
+ /// module merge.
+ unsigned IsThisDeclarationADemotedDefinition : 1;
+
/// \brief Whether this variable is the exception variable in a C++ catch
/// or an Objective-C @catch statement.
unsigned ExceptionVar : 1;
@@ -1025,7 +1030,7 @@ public:
/// void foo() { int x; static int y; extern int z; }
///
bool isLocalVarDecl() const {
- if (getKind() != Decl::Var)
+ if (getKind() != Decl::Var && getKind() != Decl::Decomposition)
return false;
if (const DeclContext *DC = getLexicalDeclContext())
return DC->getRedeclContext()->isFunctionOrMethod();
@@ -1040,7 +1045,7 @@ public:
/// isFunctionOrMethodVarDecl - Similar to isLocalVarDecl, but
/// excludes variables declared in blocks.
bool isFunctionOrMethodVarDecl() const {
- if (getKind() != Decl::Var)
+ if (getKind() != Decl::Var && getKind() != Decl::Decomposition)
return false;
const DeclContext *DC = getLexicalDeclContext()->getRedeclContext();
return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;
@@ -1198,12 +1203,28 @@ public:
InitializationStyle getInitStyle() const {
return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
}
-
/// \brief Whether the initializer is a direct-initializer (list or call).
bool isDirectInit() const {
return getInitStyle() != CInit;
}
+ /// \brief If this definition should pretend to be a declaration.
+ bool isThisDeclarationADemotedDefinition() const {
+ return isa<ParmVarDecl>(this) ? false :
+ NonParmVarDeclBits.IsThisDeclarationADemotedDefinition;
+ }
+
+ /// \brief This is a definition which should be demoted to a declaration.
+ ///
+ /// In some cases (mostly module merging) we can end up with two visible
+ /// definitions one of which needs to be demoted to a declaration to keep
+ /// the AST invariants.
+ void demoteThisDefinitionToDeclaration() {
+ assert (isThisDeclarationADefinition() && "Not a definition!");
+ assert (!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!");
+ NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = 1;
+ }
+
/// \brief Determine whether this variable is the exception variable in a
/// C++ catch statememt or an Objective-C \@catch statement.
bool isExceptionVariable() const {
@@ -1302,6 +1323,10 @@ public:
NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same;
}
+ /// \brief Retrieve the variable declaration from which this variable could
+ /// be instantiated, if it is an instantiation (rather than a non-template).
+ VarDecl *getTemplateInstantiationPattern() const;
+
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
/// from which it was instantiated.
@@ -1576,11 +1601,6 @@ private:
/// no formals.
ParmVarDecl **ParamInfo;
- /// DeclsInPrototypeScope - Array of pointers to NamedDecls for
- /// decls defined in the function prototype that are not parameters. E.g.
- /// 'enum Y' in 'void f(enum Y {AA} x) {}'.
- ArrayRef<NamedDecl *> DeclsInPrototypeScope;
-
LazyDeclStmtPtr Body;
// FIXME: This can be packed into the bitfields in DeclContext.
@@ -1607,6 +1627,11 @@ private:
/// skipped.
unsigned HasSkippedBody : 1;
+ /// Indicates if the function declaration will have a body, once we're done
+ /// parsing it. (We don't set it to false when we're done parsing, in the
+ /// hopes this is simpler.)
+ unsigned WillHaveBody : 1;
+
/// \brief End part of this FunctionDecl's source range.
///
/// We could compute the full range in getSourceRange(). However, when we're
@@ -1676,25 +1701,21 @@ private:
protected:
FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass S, bool isInlineSpecified,
+ const DeclarationNameInfo &NameInfo, QualType T,
+ TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified,
bool isConstexprSpecified)
- : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
- StartLoc),
- DeclContext(DK),
- redeclarable_base(C),
- ParamInfo(nullptr), Body(),
- SClass(S),
- IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
- IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
- HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
- IsDefaulted(false), IsExplicitlyDefaulted(false),
- HasImplicitReturnZero(false), IsLateTemplateParsed(false),
- IsConstexpr(isConstexprSpecified), UsesSEHTry(false),
- HasSkippedBody(false), EndRangeLoc(NameInfo.getEndLoc()),
- TemplateOrSpecialization(),
- DNLoc(NameInfo.getInfo()) {}
+ : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
+ StartLoc),
+ DeclContext(DK), redeclarable_base(C), ParamInfo(nullptr), Body(),
+ SClass(S), IsInline(isInlineSpecified),
+ IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false),
+ IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true),
+ IsDeleted(false), IsTrivial(false), IsDefaulted(false),
+ IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
+ IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
+ UsesSEHTry(false), HasSkippedBody(false), WillHaveBody(false),
+ EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(),
+ DNLoc(NameInfo.getInfo()) {}
typedef Redeclarable<FunctionDecl> redeclarable_base;
FunctionDecl *getNextRedeclarationImpl() override {
@@ -1976,6 +1997,10 @@ public:
bool hasSkippedBody() const { return HasSkippedBody; }
void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
+ /// True if this function will eventually have a body, once it's fully parsed.
+ bool willHaveBody() const { return WillHaveBody; }
+ void setWillHaveBody(bool V = true) { WillHaveBody = V; }
+
void setPreviousDeclaration(FunctionDecl * PrevDecl);
FunctionDecl *getCanonicalDecl() override;
@@ -2020,11 +2045,6 @@ public:
setParams(getASTContext(), NewParamInfo);
}
- ArrayRef<NamedDecl *> getDeclsInPrototypeScope() const {
- return DeclsInPrototypeScope;
- }
- void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls);
-
/// getMinRequiredArguments - Returns the minimum number of arguments
/// needed to call this function. This may be fewer than the number of
/// function parameters, if some of the parameters have default
@@ -3784,6 +3804,55 @@ public:
static bool classofKind(Kind K) { return K == Import; }
};
+/// \brief Represents a C++ Modules TS module export declaration.
+///
+/// For example:
+/// \code
+/// export void foo();
+/// \endcode
+class ExportDecl final : public Decl, public DeclContext {
+ virtual void anchor();
+private:
+ /// \brief The source location for the right brace (if valid).
+ SourceLocation RBraceLoc;
+
+ ExportDecl(DeclContext *DC, SourceLocation ExportLoc)
+ : Decl(Export, DC, ExportLoc), DeclContext(Export),
+ RBraceLoc(SourceLocation()) { }
+
+ friend class ASTDeclReader;
+
+public:
+ static ExportDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation ExportLoc);
+ static ExportDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ SourceLocation getExportLoc() const { return getLocation(); }
+ SourceLocation getRBraceLoc() const { return RBraceLoc; }
+ void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
+
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ if (RBraceLoc.isValid())
+ return RBraceLoc;
+ // No braces: get the end location of the (only) declaration in context
+ // (if present).
+ return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
+ }
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
+ return SourceRange(getLocation(), getLocEnd());
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == Export; }
+ static DeclContext *castToDeclContext(const ExportDecl *D) {
+ return static_cast<DeclContext *>(const_cast<ExportDecl*>(D));
+ }
+ static ExportDecl *castFromDeclContext(const DeclContext *DC) {
+ return static_cast<ExportDecl *>(const_cast<DeclContext*>(DC));
+ }
+};
+
/// \brief Represents an empty-declaration.
class EmptyDecl : public Decl {
virtual void anchor();
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index ec8bb3aaa305..5de1d0588e80 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -17,6 +17,7 @@
#include "clang/AST/AttrIterator.h"
#include "clang/AST/DeclarationName.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
@@ -32,6 +33,7 @@ class DeclContext;
class DeclarationName;
class DependentDiagnostic;
class EnumDecl;
+class ExportDecl;
class FunctionDecl;
class FunctionType;
enum Linkage : unsigned char;
@@ -566,6 +568,10 @@ public:
return NextInContextAndBits.getInt() & ModulePrivateFlag;
}
+ /// \brief Whether this declaration is exported (by virtue of being lexically
+ /// within an ExportDecl or by being a NamespaceDecl).
+ bool isExported() const;
+
/// Return true if this declaration has an attribute which acts as
/// definition of the entity, such as 'alias' or 'ifunc'.
bool hasDefiningAttr() const;
@@ -603,7 +609,12 @@ public:
/// AR_Available, will be set to a (possibly empty) message
/// describing why the declaration has not been introduced, is
/// deprecated, or is unavailable.
- AvailabilityResult getAvailability(std::string *Message = nullptr) const;
+ ///
+ /// \param EnclosingVersion The version to compare with. If empty, assume the
+ /// deployment target version.
+ AvailabilityResult
+ getAvailability(std::string *Message = nullptr,
+ VersionTuple EnclosingVersion = VersionTuple()) const;
/// \brief Determine whether this declaration is marked 'deprecated'.
///
@@ -1129,6 +1140,7 @@ public:
/// ObjCMethodDecl
/// ObjCContainerDecl
/// LinkageSpecDecl
+/// ExportDecl
/// BlockDecl
/// OMPDeclareReductionDecl
///
@@ -1273,7 +1285,8 @@ public:
/// \brief Test whether the context supports looking up names.
bool isLookupContext() const {
- return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec;
+ return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec &&
+ DeclKind != Decl::Export;
}
bool isFileContext() const {
@@ -1321,6 +1334,9 @@ public:
/// linkage specification context that specifies C linkage.
bool isExternCContext() const;
+ /// \brief Retrieve the nearest enclosing C linkage specification context.
+ const LinkageSpecDecl *getExternCContext() const;
+
/// \brief Determines whether this context or some of its ancestors is a
/// linkage specification context that specifies C++ linkage.
bool isExternCXXContext() const;
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 66acfee60db0..06ecd3c37342 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -139,7 +139,6 @@ public:
static bool classofKind(Kind K) { return K == AccessSpec; }
};
-
/// \brief Represents a base class of a C++ class.
///
/// Each CXXBaseSpecifier represents a single, direct base class (or
@@ -536,11 +535,10 @@ class CXXRecordDecl : public RecordDecl {
MethodTyInfo(Info) {
IsLambda = true;
- // C++11 [expr.prim.lambda]p3:
- // This class type is neither an aggregate nor a literal type.
+ // C++1z [expr.prim.lambda]p4:
+ // This class type is not an aggregate type.
Aggregate = false;
PlainOldData = false;
- HasNonLiteralTypeFieldsOrBases = true;
}
/// \brief Whether this lambda is known to be dependent, even if its
@@ -573,7 +571,7 @@ class CXXRecordDecl : public RecordDecl {
/// actual DeclContext does not suffice. This is used for lambdas that
/// occur within default arguments of function parameters within the class
/// or within a data member initializer.
- Decl *ContextDecl;
+ LazyDeclPtr ContextDecl;
/// \brief The list of captures, both explicit and implicit, for this
/// lambda.
@@ -995,7 +993,11 @@ public:
!hasUserDeclaredCopyConstructor() &&
!hasUserDeclaredCopyAssignment() &&
!hasUserDeclaredMoveConstructor() &&
- !hasUserDeclaredDestructor();
+ !hasUserDeclaredDestructor() &&
+ // C++1z [expr.prim.lambda]p21: "the closure type has a deleted copy
+ // assignment operator". The intent is that this counts as a user
+ // declared copy assignment, but we do not model it that way.
+ !isLambda();
}
/// \brief Determine whether we need to eagerly declare a move assignment
@@ -1149,6 +1151,12 @@ public:
/// \note This does NOT include a check for union-ness.
bool isEmpty() const { return data().Empty; }
+ /// \brief Determine whether this class has direct non-static data members.
+ bool hasDirectFields() const {
+ auto &D = data();
+ return D.HasPublicFields || D.HasProtectedFields || D.HasPrivateFields;
+ }
+
/// Whether this class is polymorphic (C++ [class.virtual]),
/// which means that the class contains or inherits a virtual function.
bool isPolymorphic() const { return data().Polymorphic; }
@@ -1339,11 +1347,15 @@ public:
///
/// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
/// treating types with trivial default constructors as literal types.
+ ///
+ /// Only in C++1z and beyond, are lambdas literal types.
bool isLiteral() const {
return hasTrivialDestructor() &&
- (isAggregate() || hasConstexprNonCopyMoveConstructor() ||
- hasTrivialDefaultConstructor()) &&
- !hasNonLiteralTypeFieldsOrBases();
+ (!isLambda() || getASTContext().getLangOpts().CPlusPlus1z) &&
+ !hasNonLiteralTypeFieldsOrBases() &&
+ (isAggregate() || isLambda() ||
+ hasConstexprNonCopyMoveConstructor() ||
+ hasTrivialDefaultConstructor());
}
/// \brief If this record is an instantiation of a member class,
@@ -1665,10 +1677,7 @@ public:
/// the declaration in which the lambda occurs, e.g., the function parameter
/// or the non-static data member. Otherwise, it returns NULL to imply that
/// the declaration context suffices.
- Decl *getLambdaContextDecl() const {
- assert(isLambda() && "Not a lambda closure type!");
- return getLambdaData().ContextDecl;
- }
+ Decl *getLambdaContextDecl() const;
/// \brief Set the mangling number and context declaration for a lambda
/// class.
@@ -1919,8 +1928,7 @@ public:
/// B(A& a) : A(a), f(3.14159) { }
/// };
/// \endcode
-class CXXCtorInitializer final
- : private llvm::TrailingObjects<CXXCtorInitializer, VarDecl *> {
+class CXXCtorInitializer final {
/// \brief Either the base class name/delegating constructor type (stored as
/// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field
/// (IndirectFieldDecl*) being initialized.
@@ -1958,14 +1966,8 @@ class CXXCtorInitializer final
unsigned IsWritten : 1;
/// If IsWritten is true, then this number keeps track of the textual order
- /// of this initializer in the original sources, counting from 0; otherwise,
- /// it stores the number of array index variables stored after this object
- /// in memory.
- unsigned SourceOrderOrNumArrayIndices : 13;
-
- CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
- SourceLocation MemberLoc, SourceLocation L, Expr *Init,
- SourceLocation R, VarDecl **Indices, unsigned NumIndices);
+ /// of this initializer in the original sources, counting from 0.
+ unsigned SourceOrder : 13;
public:
/// \brief Creates a new base-class initializer.
@@ -1991,13 +1993,6 @@ public:
CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo,
SourceLocation L, Expr *Init, SourceLocation R);
- /// \brief Creates a new member initializer that optionally contains
- /// array indices used to describe an elementwise initialization.
- static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member,
- SourceLocation MemberLoc, SourceLocation L,
- Expr *Init, SourceLocation R,
- VarDecl **Indices, unsigned NumIndices);
-
/// \brief Determine whether this initializer is initializing a base class.
bool isBaseInitializer() const {
return Initializee.is<TypeSourceInfo*>() && !IsDelegating;
@@ -2102,7 +2097,7 @@ public:
/// \brief Return the source position of the initializer, counting from 0.
/// If the initializer was implicit, -1 is returned.
int getSourceOrder() const {
- return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1;
+ return IsWritten ? static_cast<int>(SourceOrder) : -1;
}
/// \brief Set the source order of this initializer.
@@ -2112,49 +2107,22 @@ public:
///
/// This assumes that the initializer was written in the source code, and
/// ensures that isWritten() returns true.
- void setSourceOrder(int pos) {
+ void setSourceOrder(int Pos) {
assert(!IsWritten &&
+ "setSourceOrder() used on implicit initializer");
+ assert(SourceOrder == 0 &&
"calling twice setSourceOrder() on the same initializer");
- assert(SourceOrderOrNumArrayIndices == 0 &&
- "setSourceOrder() used when there are implicit array indices");
- assert(pos >= 0 &&
+ assert(Pos >= 0 &&
"setSourceOrder() used to make an initializer implicit");
IsWritten = true;
- SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos);
+ SourceOrder = static_cast<unsigned>(Pos);
}
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
- /// \brief Determine the number of implicit array indices used while
- /// described an array member initialization.
- unsigned getNumArrayIndices() const {
- return IsWritten ? 0 : SourceOrderOrNumArrayIndices;
- }
-
- /// \brief Retrieve a particular array index variable used to
- /// describe an array member initialization.
- VarDecl *getArrayIndex(unsigned I) {
- assert(I < getNumArrayIndices() && "Out of bounds member array index");
- return getTrailingObjects<VarDecl *>()[I];
- }
- const VarDecl *getArrayIndex(unsigned I) const {
- assert(I < getNumArrayIndices() && "Out of bounds member array index");
- return getTrailingObjects<VarDecl *>()[I];
- }
- void setArrayIndex(unsigned I, VarDecl *Index) {
- assert(I < getNumArrayIndices() && "Out of bounds member array index");
- getTrailingObjects<VarDecl *>()[I] = Index;
- }
- ArrayRef<VarDecl *> getArrayIndices() {
- return llvm::makeArrayRef(getTrailingObjects<VarDecl *>(),
- getNumArrayIndices());
- }
-
/// \brief Get the initializer.
Expr *getInit() const { return static_cast<Expr*>(Init); }
-
- friend TrailingObjects;
};
/// Description of a constructor that was inherited from a base class.
@@ -2952,11 +2920,10 @@ class ConstructorUsingShadowDecl final : public UsingShadowDecl {
dyn_cast<ConstructorUsingShadowDecl>(Target)),
ConstructedBaseClassShadowDecl(NominatedBaseClassShadowDecl),
IsVirtual(TargetInVirtualBase) {
- // If we found a constructor for a non-virtual base class, but it chains to
- // a constructor for a virtual base, we should directly call the virtual
- // base constructor instead.
+ // If we found a constructor that chains to a constructor for a virtual
+ // base, we should directly call that virtual base constructor instead.
// FIXME: This logic belongs in Sema.
- if (!TargetInVirtualBase && NominatedBaseClassShadowDecl &&
+ if (NominatedBaseClassShadowDecl &&
NominatedBaseClassShadowDecl->constructsVirtualBase()) {
ConstructedBaseClassShadowDecl =
NominatedBaseClassShadowDecl->ConstructedBaseClassShadowDecl;
@@ -2964,7 +2931,9 @@ class ConstructorUsingShadowDecl final : public UsingShadowDecl {
}
}
ConstructorUsingShadowDecl(ASTContext &C, EmptyShell Empty)
- : UsingShadowDecl(ConstructorUsingShadow, C, Empty) {}
+ : UsingShadowDecl(ConstructorUsingShadow, C, Empty),
+ NominatedBaseClassShadowDecl(), ConstructedBaseClassShadowDecl(),
+ IsVirtual(false) {}
public:
static ConstructorUsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
@@ -3171,6 +3140,77 @@ public:
friend class ASTDeclWriter;
};
+/// Represents a pack of using declarations that a single
+/// using-declarator pack-expanded into.
+///
+/// \code
+/// template<typename ...T> struct X : T... {
+/// using T::operator()...;
+/// using T::operator T...;
+/// };
+/// \endcode
+///
+/// In the second case above, the UsingPackDecl will have the name
+/// 'operator T' (which contains an unexpanded pack), but the individual
+/// UsingDecls and UsingShadowDecls will have more reasonable names.
+class UsingPackDecl final
+ : public NamedDecl, public Mergeable<UsingPackDecl>,
+ private llvm::TrailingObjects<UsingPackDecl, NamedDecl *> {
+ void anchor() override;
+
+ /// The UnresolvedUsingValueDecl or UnresolvedUsingTypenameDecl from
+ /// which this waas instantiated.
+ NamedDecl *InstantiatedFrom;
+
+ /// The number of using-declarations created by this pack expansion.
+ unsigned NumExpansions;
+
+ UsingPackDecl(DeclContext *DC, NamedDecl *InstantiatedFrom,
+ ArrayRef<NamedDecl *> UsingDecls)
+ : NamedDecl(UsingPack, DC,
+ InstantiatedFrom ? InstantiatedFrom->getLocation()
+ : SourceLocation(),
+ InstantiatedFrom ? InstantiatedFrom->getDeclName()
+ : DeclarationName()),
+ InstantiatedFrom(InstantiatedFrom), NumExpansions(UsingDecls.size()) {
+ std::uninitialized_copy(UsingDecls.begin(), UsingDecls.end(),
+ getTrailingObjects<NamedDecl *>());
+ }
+
+public:
+ /// Get the using declaration from which this was instantiated. This will
+ /// always be an UnresolvedUsingValueDecl or an UnresolvedUsingTypenameDecl
+ /// that is a pack expansion.
+ NamedDecl *getInstantiatedFromUsingDecl() { return InstantiatedFrom; }
+
+ /// Get the set of using declarations that this pack expanded into. Note that
+ /// some of these may still be unresolved.
+ ArrayRef<NamedDecl *> expansions() const {
+ return llvm::makeArrayRef(getTrailingObjects<NamedDecl *>(), NumExpansions);
+ }
+
+ static UsingPackDecl *Create(ASTContext &C, DeclContext *DC,
+ NamedDecl *InstantiatedFrom,
+ ArrayRef<NamedDecl *> UsingDecls);
+
+ static UsingPackDecl *CreateDeserialized(ASTContext &C, unsigned ID,
+ unsigned NumExpansions);
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
+ return InstantiatedFrom->getSourceRange();
+ }
+
+ UsingPackDecl *getCanonicalDecl() override { return getFirstDecl(); }
+ const UsingPackDecl *getCanonicalDecl() const { return getFirstDecl(); }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == UsingPack; }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+ friend TrailingObjects;
+};
+
/// \brief Represents a dependent using declaration which was not marked with
/// \c typename.
///
@@ -3189,6 +3229,9 @@ class UnresolvedUsingValueDecl : public ValueDecl,
/// \brief The source location of the 'using' keyword
SourceLocation UsingLocation;
+ /// \brief If this is a pack expansion, the location of the '...'.
+ SourceLocation EllipsisLoc;
+
/// \brief The nested-name-specifier that precedes the name.
NestedNameSpecifierLoc QualifierLoc;
@@ -3199,11 +3242,12 @@ class UnresolvedUsingValueDecl : public ValueDecl,
UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
SourceLocation UsingLoc,
NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo)
+ const DeclarationNameInfo &NameInfo,
+ SourceLocation EllipsisLoc)
: ValueDecl(UnresolvedUsingValue, DC,
NameInfo.getLoc(), NameInfo.getName(), Ty),
- UsingLocation(UsingLoc), QualifierLoc(QualifierLoc),
- DNLoc(NameInfo.getInfo())
+ UsingLocation(UsingLoc), EllipsisLoc(EllipsisLoc),
+ QualifierLoc(QualifierLoc), DNLoc(NameInfo.getInfo())
{ }
public:
@@ -3229,10 +3273,20 @@ public:
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
+ /// \brief Determine whether this is a pack expansion.
+ bool isPackExpansion() const {
+ return EllipsisLoc.isValid();
+ }
+
+ /// \brief Get the location of the ellipsis if this is a pack expansion.
+ SourceLocation getEllipsisLoc() const {
+ return EllipsisLoc;
+ }
+
static UnresolvedUsingValueDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo);
+ const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc);
static UnresolvedUsingValueDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
@@ -3273,6 +3327,9 @@ class UnresolvedUsingTypenameDecl
/// \brief The source location of the 'typename' keyword
SourceLocation TypenameLocation;
+ /// \brief If this is a pack expansion, the location of the '...'.
+ SourceLocation EllipsisLoc;
+
/// \brief The nested-name-specifier that precedes the name.
NestedNameSpecifierLoc QualifierLoc;
@@ -3280,10 +3337,12 @@ class UnresolvedUsingTypenameDecl
SourceLocation TypenameLoc,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TargetNameLoc,
- IdentifierInfo *TargetName)
+ IdentifierInfo *TargetName,
+ SourceLocation EllipsisLoc)
: TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName,
UsingLoc),
- TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { }
+ TypenameLocation(TypenameLoc), EllipsisLoc(EllipsisLoc),
+ QualifierLoc(QualifierLoc) { }
friend class ASTDeclReader;
@@ -3303,10 +3362,25 @@ public:
return QualifierLoc.getNestedNameSpecifier();
}
+ DeclarationNameInfo getNameInfo() const {
+ return DeclarationNameInfo(getDeclName(), getLocation());
+ }
+
+ /// \brief Determine whether this is a pack expansion.
+ bool isPackExpansion() const {
+ return EllipsisLoc.isValid();
+ }
+
+ /// \brief Get the location of the ellipsis if this is a pack expansion.
+ SourceLocation getEllipsisLoc() const {
+ return EllipsisLoc;
+ }
+
static UnresolvedUsingTypenameDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TargetNameLoc, DeclarationName TargetName);
+ SourceLocation TargetNameLoc, DeclarationName TargetName,
+ SourceLocation EllipsisLoc);
static UnresolvedUsingTypenameDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
@@ -3364,6 +3438,104 @@ public:
friend class ASTDeclReader;
};
+/// A binding in a decomposition declaration. For instance, given:
+///
+/// int n[3];
+/// auto &[a, b, c] = n;
+///
+/// a, b, and c are BindingDecls, whose bindings are the expressions
+/// x[0], x[1], and x[2] respectively, where x is the implicit
+/// DecompositionDecl of type 'int (&)[3]'.
+class BindingDecl : public ValueDecl {
+ void anchor() override;
+
+ /// The binding represented by this declaration. References to this
+ /// declaration are effectively equivalent to this expression (except
+ /// that it is only evaluated once at the point of declaration of the
+ /// binding).
+ Expr *Binding;
+
+ BindingDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id)
+ : ValueDecl(Decl::Binding, DC, IdLoc, Id, QualType()), Binding(nullptr) {}
+
+public:
+ static BindingDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation IdLoc, IdentifierInfo *Id);
+ static BindingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ /// Get the expression to which this declaration is bound. This may be null
+ /// in two different cases: while parsing the initializer for the
+ /// decomposition declaration, and when the initializer is type-dependent.
+ Expr *getBinding() const { return Binding; }
+
+ /// Get the variable (if any) that holds the value of evaluating the binding.
+ /// Only present for user-defined bindings for tuple-like types.
+ VarDecl *getHoldingVar() const;
+
+ /// Set the binding for this BindingDecl, along with its declared type (which
+ /// should be a possibly-cv-qualified form of the type of the binding, or a
+ /// reference to such a type).
+ void setBinding(QualType DeclaredType, Expr *Binding) {
+ setType(DeclaredType);
+ this->Binding = Binding;
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == Decl::Binding; }
+
+ friend class ASTDeclReader;
+};
+
+/// A decomposition declaration. For instance, given:
+///
+/// int n[3];
+/// auto &[a, b, c] = n;
+///
+/// the second line declares a DecompositionDecl of type 'int (&)[3]', and
+/// three BindingDecls (named a, b, and c). An instance of this class is always
+/// unnamed, but behaves in almost all other respects like a VarDecl.
+class DecompositionDecl final
+ : public VarDecl,
+ private llvm::TrailingObjects<DecompositionDecl, BindingDecl *> {
+ void anchor() override;
+
+ /// The number of BindingDecl*s following this object.
+ unsigned NumBindings;
+
+ DecompositionDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation LSquareLoc, QualType T,
+ TypeSourceInfo *TInfo, StorageClass SC,
+ ArrayRef<BindingDecl *> Bindings)
+ : VarDecl(Decomposition, C, DC, StartLoc, LSquareLoc, nullptr, T, TInfo,
+ SC),
+ NumBindings(Bindings.size()) {
+ std::uninitialized_copy(Bindings.begin(), Bindings.end(),
+ getTrailingObjects<BindingDecl *>());
+ }
+
+public:
+ static DecompositionDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation StartLoc,
+ SourceLocation LSquareLoc,
+ QualType T, TypeSourceInfo *TInfo,
+ StorageClass S,
+ ArrayRef<BindingDecl *> Bindings);
+ static DecompositionDecl *CreateDeserialized(ASTContext &C, unsigned ID,
+ unsigned NumBindings);
+
+ ArrayRef<BindingDecl *> bindings() const {
+ return llvm::makeArrayRef(getTrailingObjects<BindingDecl *>(), NumBindings);
+ }
+
+ void printName(raw_ostream &os) const override;
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == Decomposition; }
+
+ friend TrailingObjects;
+ friend class ASTDeclReader;
+};
+
/// An instance of this class represents the declaration of a property
/// member. This is a Microsoft extension to C++, first introduced in
/// Visual Studio .NET 2003 as a parallel to similar features in C#
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 5b2e2d9915eb..172c46a44ac1 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -82,6 +82,7 @@ private:
FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
: Decl(Decl::Friend, Empty), NextFriend(),
+ UnsupportedFriend(false),
NumTPLists(NumFriendTypeTPLists) { }
FriendDecl *getNextFriend() {
@@ -166,6 +167,7 @@ public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
+ friend class ASTNodeImporter;
friend TrailingObjects;
};
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
index c84bb5e60481..6353b26f7bf5 100644
--- a/include/clang/AST/DeclGroup.h
+++ b/include/clang/AST/DeclGroup.h
@@ -84,7 +84,7 @@ public:
bool isDeclGroup() const { return getKind() == DeclGroupKind; }
Decl *getSingleDecl() {
- assert(isSingleDecl() && "Isn't a declgroup");
+ assert(isSingleDecl() && "Isn't a single decl");
return D;
}
const Decl *getSingleDecl() const {
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index ad9b5a26b7c8..f5098f06a9f6 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -394,7 +394,7 @@ public:
/// createImplicitParams - Used to lazily create the self and cmd
/// implict parameters. This must be called prior to using getSelfDecl()
- /// or getCmdDecl(). The call is ignored if the implicit paramters
+ /// or getCmdDecl(). The call is ignored if the implicit parameters
/// have already been created.
void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
@@ -463,6 +463,9 @@ public:
ImplementationControl getImplementationControl() const {
return ImplementationControl(DeclImplementation);
}
+ bool isOptional() const {
+ return getImplementationControl() == Optional;
+ }
/// Returns true if this specific method declaration is marked with the
/// designated initializer attribute.
@@ -870,6 +873,9 @@ public:
PropertyControl getPropertyImplementation() const {
return PropertyControl(PropertyImplementation);
}
+ bool isOptional() const {
+ return getPropertyImplementation() == PropertyControl::Optional;
+ }
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
PropertyIvarDecl = Ivar;
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index 1975bc551ca5..30ca79e9d005 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -173,18 +173,21 @@ class OMPCapturedExprDecl final : public VarDecl {
void anchor() override;
OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
- QualType Type)
- : VarDecl(OMPCapturedExpr, C, DC, SourceLocation(), SourceLocation(), Id,
- Type, nullptr, SC_None) {
+ QualType Type, SourceLocation StartLoc)
+ : VarDecl(OMPCapturedExpr, C, DC, StartLoc, SourceLocation(), Id, Type,
+ nullptr, SC_None) {
setImplicit();
}
public:
static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC,
- IdentifierInfo *Id, QualType T);
+ IdentifierInfo *Id, QualType T,
+ SourceLocation StartLoc);
static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+ SourceRange getSourceRange() const override LLVM_READONLY;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index d553e739c388..2af95c02c460 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -21,7 +21,6 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
-#include <limits>
#include <utility>
namespace clang {
@@ -49,7 +48,8 @@ NamedDecl *getAsNamedDecl(TemplateParameter P);
/// \brief Stores a list of template parameters for a TemplateDecl and its
/// derived classes.
class TemplateParameterList final
- : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *> {
+ : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
+ Expr *> {
/// The location of the 'template' keyword.
SourceLocation TemplateLoc;
@@ -59,26 +59,35 @@ class TemplateParameterList final
/// The number of template parameters in this template
/// parameter list.
- unsigned NumParams : 31;
+ unsigned NumParams : 30;
/// Whether this template parameter list contains an unexpanded parameter
/// pack.
unsigned ContainsUnexpandedParameterPack : 1;
+ /// Whether this template parameter list has an associated requires-clause
+ unsigned HasRequiresClause : 1;
+
protected:
size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
return NumParams;
}
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return HasRequiresClause;
+ }
+
TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
- ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc);
+ ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc,
+ Expr *RequiresClause);
public:
static TemplateParameterList *Create(const ASTContext &C,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
ArrayRef<NamedDecl *> Params,
- SourceLocation RAngleLoc);
+ SourceLocation RAngleLoc,
+ Expr *RequiresClause);
/// \brief Iterates through the template parameters in this list.
typedef NamedDecl** iterator;
@@ -130,6 +139,16 @@ public:
return ContainsUnexpandedParameterPack;
}
+ /// \brief The constraint-expression of the associated requires-clause.
+ Expr *getRequiresClause() {
+ return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr;
+ }
+
+ /// \brief The constraint-expression of the associated requires-clause.
+ const Expr *getRequiresClause() const {
+ return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr;
+ }
+
SourceLocation getTemplateLoc() const { return TemplateLoc; }
SourceLocation getLAngleLoc() const { return LAngleLoc; }
SourceLocation getRAngleLoc() const { return RAngleLoc; }
@@ -139,36 +158,37 @@ public:
}
friend TrailingObjects;
- template <size_t N> friend class FixedSizeTemplateParameterListStorage;
+
+ template <size_t N, bool HasRequiresClause>
+ friend class FixedSizeTemplateParameterListStorage;
+
+public:
+ // FIXME: workaround for MSVC 2013; remove when no longer needed
+ using FixedSizeStorageOwner = TrailingObjects::FixedSizeStorageOwner;
};
-/// \brief Stores a list of template parameters for a TemplateDecl and its
-/// derived classes. Suitable for creating on the stack.
-template <size_t N> class FixedSizeTemplateParameterListStorage {
- // This is kinda ugly: TemplateParameterList usually gets allocated
- // in a block of memory with NamedDecls appended to it. Here, to get
- // it stack allocated, we include the params as a separate
- // variable. After allocation, the TemplateParameterList object
- // treats them as part of itself.
- TemplateParameterList List;
- NamedDecl *Params[N];
+/// \brief Stores a list of template parameters and the associated
+/// requires-clause (if any) for a TemplateDecl and its derived classes.
+/// Suitable for creating on the stack.
+template <size_t N, bool HasRequiresClause>
+class FixedSizeTemplateParameterListStorage
+ : public TemplateParameterList::FixedSizeStorageOwner {
+ typename TemplateParameterList::FixedSizeStorage<
+ NamedDecl *, Expr *>::with_counts<
+ N, HasRequiresClause ? 1u : 0u
+ >::type storage;
public:
FixedSizeTemplateParameterListStorage(SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
ArrayRef<NamedDecl *> Params,
- SourceLocation RAngleLoc)
- : List(TemplateLoc, LAngleLoc, Params, RAngleLoc) {
- // Because we're doing an evil layout hack above, have some
- // asserts, just to double-check everything is laid out like
- // expected.
- assert(sizeof(*this) ==
- TemplateParameterList::totalSizeToAlloc<NamedDecl *>(N) &&
- "Object layout not as expected");
- assert(this->Params == List.getTrailingObjects<NamedDecl *>() &&
- "Object layout not as expected");
- }
- TemplateParameterList *get() { return &List; }
+ SourceLocation RAngleLoc,
+ Expr *RequiresClause)
+ : FixedSizeStorageOwner(
+ (assert(N == Params.size()),
+ assert(HasRequiresClause == static_cast<bool>(RequiresClause)),
+ new (static_cast<void *>(&storage)) TemplateParameterList(
+ TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
};
/// \brief A template argument list.
@@ -356,6 +376,11 @@ public:
return TemplateParams;
}
+ /// Get the constraint-expression from the associated requires-clause (if any)
+ const Expr *getRequiresClause() const {
+ return TemplateParams ? TemplateParams->getRequiresClause() : nullptr;
+ }
+
/// Get the underlying, templated declaration.
NamedDecl *getTemplatedDecl() const { return TemplatedDecl.getPointer(); }
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 9179c7736a9a..41ae6d2b721e 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -445,6 +445,11 @@ public:
return const_cast<Expr*>(this)->getSourceBitField();
}
+ Decl *getReferencedDeclOfCallee();
+ const Decl *getReferencedDeclOfCallee() const {
+ return const_cast<Expr*>(this)->getReferencedDeclOfCallee();
+ }
+
/// \brief If this expression is an l-value for an Objective C
/// property, find the underlying property reference expression.
const ObjCPropertyRefExpr *getObjCProperty() const;
@@ -823,12 +828,22 @@ public:
/// behavior if the object isn't dynamically of the derived type.
const CXXRecordDecl *getBestDynamicClassType() const;
+ /// \brief Get the inner expression that determines the best dynamic class.
+ /// If this is a prvalue, we guarantee that it is of the most-derived type
+ /// for the object itself.
+ const Expr *getBestDynamicClassTypeExpr() const;
+
/// Walk outwards from an expression we want to bind a reference to and
/// find the expression whose lifetime needs to be extended. Record
/// the LHSs of comma expressions and adjustments needed along the path.
const Expr *skipRValueSubobjectAdjustments(
SmallVectorImpl<const Expr *> &CommaLHS,
SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
+ const Expr *skipRValueSubobjectAdjustments() const {
+ SmallVector<const Expr *, 8> CommaLHSs;
+ SmallVector<SubobjectAdjustment, 8> Adjustments;
+ return skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
+ }
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstExprConstant &&
@@ -2406,8 +2421,8 @@ public:
/// \brief Retrieve the member declaration to which this expression refers.
///
- /// The returned declaration will either be a FieldDecl or (in C++)
- /// a CXXMethodDecl.
+ /// The returned declaration will be a FieldDecl or (in C++) a VarDecl (for
+ /// static data members), a CXXMethodDecl, or an EnumConstantDecl.
ValueDecl *getMemberDecl() const { return MemberDecl; }
void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
@@ -3771,17 +3786,26 @@ public:
/// \brief Build an empty initializer list.
explicit InitListExpr(EmptyShell Empty)
- : Expr(InitListExprClass, Empty) { }
+ : Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
unsigned getNumInits() const { return InitExprs.size(); }
/// \brief Retrieve the set of initializers.
Expr **getInits() { return reinterpret_cast<Expr **>(InitExprs.data()); }
+ /// \brief Retrieve the set of initializers.
+ Expr * const *getInits() const {
+ return reinterpret_cast<Expr * const *>(InitExprs.data());
+ }
+
ArrayRef<Expr *> inits() {
return llvm::makeArrayRef(getInits(), getNumInits());
}
+ ArrayRef<Expr *> inits() const {
+ return llvm::makeArrayRef(getInits(), getNumInits());
+ }
+
const Expr *getInit(unsigned Init) const {
assert(Init < getNumInits() && "Initializer access out of range!");
return cast_or_null<Expr>(InitExprs[Init]);
@@ -3862,7 +3886,7 @@ public:
// Explicit InitListExpr's originate from source code (and have valid source
// locations). Implicit InitListExpr's are created by the semantic analyzer.
- bool isExplicit() {
+ bool isExplicit() const {
return LBraceLoc.isValid() && RBraceLoc.isValid();
}
@@ -3870,6 +3894,11 @@ public:
// literal or an @encode?
bool isStringLiteralInit() const;
+ /// Is this a transparent initializer list (that is, an InitListExpr that is
+ /// purely syntactic, and whose semantics are that of the sole contained
+ /// initializer)?
+ bool isTransparent() const;
+
SourceLocation getLBraceLoc() const { return LBraceLoc; }
void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
@@ -4304,6 +4333,98 @@ public:
}
};
+/// \brief Represents a loop initializing the elements of an array.
+///
+/// The need to initialize the elements of an array occurs in a number of
+/// contexts:
+///
+/// * in the implicit copy/move constructor for a class with an array member
+/// * when a lambda-expression captures an array by value
+/// * when a decomposition declaration decomposes an array
+///
+/// There are two subexpressions: a common expression (the source array)
+/// that is evaluated once up-front, and a per-element initializer that
+/// runs once for each array element.
+///
+/// Within the per-element initializer, the common expression may be referenced
+/// via an OpaqueValueExpr, and the current index may be obtained via an
+/// ArrayInitIndexExpr.
+class ArrayInitLoopExpr : public Expr {
+ Stmt *SubExprs[2];
+
+ explicit ArrayInitLoopExpr(EmptyShell Empty)
+ : Expr(ArrayInitLoopExprClass, Empty), SubExprs{} {}
+
+public:
+ explicit ArrayInitLoopExpr(QualType T, Expr *CommonInit, Expr *ElementInit)
+ : Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary, false,
+ CommonInit->isValueDependent() || ElementInit->isValueDependent(),
+ T->isInstantiationDependentType(),
+ CommonInit->containsUnexpandedParameterPack() ||
+ ElementInit->containsUnexpandedParameterPack()),
+ SubExprs{CommonInit, ElementInit} {}
+
+ /// Get the common subexpression shared by all initializations (the source
+ /// array).
+ OpaqueValueExpr *getCommonExpr() const {
+ return cast<OpaqueValueExpr>(SubExprs[0]);
+ }
+
+ /// Get the initializer to use for each array element.
+ Expr *getSubExpr() const { return cast<Expr>(SubExprs[1]); }
+
+ llvm::APInt getArraySize() const {
+ return cast<ConstantArrayType>(getType()->castAsArrayTypeUnsafe())
+ ->getSize();
+ }
+
+ static bool classof(const Stmt *S) {
+ return S->getStmtClass() == ArrayInitLoopExprClass;
+ }
+
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getCommonExpr()->getLocStart();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return getCommonExpr()->getLocEnd();
+ }
+
+ child_range children() {
+ return child_range(SubExprs, SubExprs + 2);
+ }
+
+ friend class ASTReader;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+};
+
+/// \brief Represents the index of the current element of an array being
+/// initialized by an ArrayInitLoopExpr. This can only appear within the
+/// subexpression of an ArrayInitLoopExpr.
+class ArrayInitIndexExpr : public Expr {
+ explicit ArrayInitIndexExpr(EmptyShell Empty)
+ : Expr(ArrayInitIndexExprClass, Empty) {}
+
+public:
+ explicit ArrayInitIndexExpr(QualType T)
+ : Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary,
+ false, false, false, false) {}
+
+ static bool classof(const Stmt *S) {
+ return S->getStmtClass() == ArrayInitIndexExprClass;
+ }
+
+ SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ friend class ASTReader;
+ friend class ASTStmtReader;
+};
+
/// \brief Represents an implicitly-generated value initialization of
/// an object of a given type.
///
@@ -4447,11 +4568,19 @@ public:
return cast<Expr>(SubExprs[END_EXPR+i]);
}
Expr *getAssocExpr(unsigned i) { return cast<Expr>(SubExprs[END_EXPR+i]); }
-
+ ArrayRef<Expr *> getAssocExprs() const {
+ return NumAssocs
+ ? llvm::makeArrayRef(
+ &reinterpret_cast<Expr **>(SubExprs)[END_EXPR], NumAssocs)
+ : None;
+ }
const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const {
return AssocTypes[i];
}
TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; }
+ ArrayRef<TypeSourceInfo *> getAssocTypeSourceInfos() const {
+ return NumAssocs ? llvm::makeArrayRef(&AssocTypes[0], NumAssocs) : None;
+ }
QualType getAssocType(unsigned i) const {
if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i))
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 86cbfb2cd0b4..37e59771a723 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -76,6 +76,19 @@ public:
/// expression refers to.
OverloadedOperatorKind getOperator() const { return Operator; }
+ static bool isAssignmentOp(OverloadedOperatorKind Opc) {
+ return Opc == OO_Equal || Opc == OO_StarEqual ||
+ Opc == OO_SlashEqual || Opc == OO_PercentEqual ||
+ Opc == OO_PlusEqual || Opc == OO_MinusEqual ||
+ Opc == OO_LessLessEqual || Opc == OO_GreaterGreaterEqual ||
+ Opc == OO_AmpEqual || Opc == OO_CaretEqual ||
+ Opc == OO_PipeEqual;
+ }
+ bool isAssignmentOp() const { return isAssignmentOp(getOperator()); }
+
+ /// \brief Is this written as an infix binary operator?
+ bool isInfixBinaryOp() const;
+
/// \brief Returns the location of the operator symbol in the expression.
///
/// When \c getOperator()==OO_Call, this is the location of the right
@@ -1500,9 +1513,8 @@ public:
/// C++1y introduces a new form of "capture" called an init-capture that
/// includes an initializing expression (rather than capturing a variable),
/// and which can never occur implicitly.
-class LambdaExpr final
- : public Expr,
- private llvm::TrailingObjects<LambdaExpr, Stmt *, unsigned, VarDecl *> {
+class LambdaExpr final : public Expr,
+ private llvm::TrailingObjects<LambdaExpr, Stmt *> {
/// \brief The source range that covers the lambda introducer ([...]).
SourceRange IntroducerRange;
@@ -1523,10 +1535,6 @@ class LambdaExpr final
/// \brief Whether this lambda had the result type explicitly specified.
unsigned ExplicitResultType : 1;
- /// \brief Whether there are any array index variables stored at the end of
- /// this lambda expression.
- unsigned HasArrayIndexVars : 1;
-
/// \brief The location of the closing brace ('}') that completes
/// the lambda.
///
@@ -1537,28 +1545,19 @@ class LambdaExpr final
/// module file just to determine the source range.
SourceLocation ClosingBrace;
- size_t numTrailingObjects(OverloadToken<Stmt *>) const {
- return NumCaptures + 1;
- }
-
- size_t numTrailingObjects(OverloadToken<unsigned>) const {
- return HasArrayIndexVars ? NumCaptures + 1 : 0;
- }
-
/// \brief Construct a lambda expression.
LambdaExpr(QualType T, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
bool ExplicitParams, bool ExplicitResultType,
- ArrayRef<Expr *> CaptureInits, ArrayRef<VarDecl *> ArrayIndexVars,
- ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
+ ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace,
bool ContainsUnexpandedParameterPack);
/// \brief Construct an empty lambda expression.
- LambdaExpr(EmptyShell Empty, unsigned NumCaptures, bool HasArrayIndexVars)
+ LambdaExpr(EmptyShell Empty, unsigned NumCaptures)
: Expr(LambdaExprClass, Empty),
NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
- ExplicitResultType(false), HasArrayIndexVars(true) {
+ ExplicitResultType(false) {
getStoredStmts()[NumCaptures] = nullptr;
}
@@ -1566,21 +1565,6 @@ class LambdaExpr final
Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
- /// \brief Retrieve the mapping from captures to the first array index
- /// variable.
- unsigned *getArrayIndexStarts() { return getTrailingObjects<unsigned>(); }
-
- const unsigned *getArrayIndexStarts() const {
- return getTrailingObjects<unsigned>();
- }
-
- /// \brief Retrieve the complete set of array-index variables.
- VarDecl **getArrayIndexVars() { return getTrailingObjects<VarDecl *>(); }
-
- VarDecl *const *getArrayIndexVars() const {
- return getTrailingObjects<VarDecl *>();
- }
-
public:
/// \brief Construct a new lambda expression.
static LambdaExpr *
@@ -1588,15 +1572,12 @@ public:
LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc,
ArrayRef<LambdaCapture> Captures, bool ExplicitParams,
bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
- ArrayRef<VarDecl *> ArrayIndexVars,
- ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
- bool ContainsUnexpandedParameterPack);
+ SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack);
/// \brief Construct a new lambda expression that will be deserialized from
/// an external source.
static LambdaExpr *CreateDeserialized(const ASTContext &C,
- unsigned NumCaptures,
- unsigned NumArrayIndexVars);
+ unsigned NumCaptures);
/// \brief Determine the default capture kind for this lambda.
LambdaCaptureDefault getCaptureDefault() const {
@@ -1695,14 +1676,6 @@ public:
return capture_init_begin() + NumCaptures;
}
- /// \brief Retrieve the set of index variables used in the capture
- /// initializer of an array captured by copy.
- ///
- /// \param Iter The iterator that points at the capture initializer for
- /// which we are extracting the corresponding index variables.
- ArrayRef<VarDecl *>
- getCaptureInitIndexVars(const_capture_init_iterator Iter) const;
-
/// \brief Retrieve the source range covering the lambda introducer,
/// which contains the explicit capture list surrounded by square
/// brackets ([...]).
@@ -1828,11 +1801,13 @@ class CXXNewExpr : public Expr {
unsigned GlobalNew : 1;
/// Do we allocate an array? If so, the first SubExpr is the size expression.
unsigned Array : 1;
+ /// Should the alignment be passed to the allocation function?
+ unsigned PassAlignment : 1;
/// If this is an array allocation, does the usual deallocation
/// function for the allocated type want to know the allocated size?
unsigned UsualArrayDeleteWantsSize : 1;
/// The number of placement new arguments.
- unsigned NumPlacementArgs : 13;
+ unsigned NumPlacementArgs : 26;
/// What kind of initializer do we have? Could be none, parens, or braces.
/// In storage, we distinguish between "none, and no initializer expr", and
/// "none, but an implicit initializer expr".
@@ -1848,8 +1823,8 @@ public:
};
CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
- FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize,
- ArrayRef<Expr*> placementArgs,
+ FunctionDecl *operatorDelete, bool PassAlignment,
+ bool usualArrayDeleteWantsSize, ArrayRef<Expr*> placementArgs,
SourceRange typeIdParens, Expr *arraySize,
InitializationStyle initializationStyle, Expr *initializer,
QualType ty, TypeSourceInfo *AllocatedTypeInfo,
@@ -1937,10 +1912,16 @@ public:
}
/// \brief Returns the CXXConstructExpr from this new-expression, or null.
- const CXXConstructExpr* getConstructExpr() const {
+ const CXXConstructExpr *getConstructExpr() const {
return dyn_cast_or_null<CXXConstructExpr>(getInitializer());
}
+ /// Indicates whether the required alignment should be implicitly passed to
+ /// the allocation function.
+ bool passAlignment() const {
+ return PassAlignment;
+ }
+
/// Answers whether the usual array deallocation function for the
/// allocated type expects the size of the allocation as a
/// parameter.
@@ -4011,6 +3992,12 @@ public:
// within a default initializer.
if (isa<FieldDecl>(ExtendingDecl))
return SD_Automatic;
+ // FIXME: This only works because storage class specifiers are not allowed
+ // on decomposition declarations.
+ if (isa<BindingDecl>(ExtendingDecl))
+ return ExtendingDecl->getDeclContext()->isFunctionOrMethod()
+ ? SD_Automatic
+ : SD_Static;
return cast<VarDecl>(ExtendingDecl)->getStorageDuration();
}
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index 5f9623db2416..cd9381758618 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -90,7 +90,7 @@ public:
/// ObjCBoxedExpr - used for generalized expression boxing.
/// as in: @(strdup("hello world")), @(random()) or @(view.frame)
/// Also used for boxing non-parenthesized numeric literals;
-/// as in: @42 or \@true (c++/objc++) or \@__yes (c/objc).
+/// as in: @42 or \@true (c++/objc++) or \@__objc_yes (c/objc).
class ObjCBoxedExpr : public Expr {
Stmt *SubExpr;
ObjCMethodDecl *BoxingMethod;
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index 6e3ef9da0c3d..7a45d88c23c8 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -14,14 +14,14 @@
#ifndef LLVM_CLANG_AST_MANGLE_H
#define LLVM_CLANG_AST_MANGLE_H
-#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/ABI.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+ class raw_ostream;
+}
namespace clang {
class ASTContext;
diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h
index 7a818557fdb7..869221dbf31b 100644
--- a/include/clang/AST/MangleNumberingContext.h
+++ b/include/clang/AST/MangleNumberingContext.h
@@ -16,7 +16,6 @@
#define LLVM_CLANG_AST_MANGLENUMBERINGCONTEXT_H
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
namespace clang {
@@ -30,7 +29,7 @@ class VarDecl;
/// \brief Keeps track of the mangled names of lambda expressions and block
/// literals within a particular context.
-class MangleNumberingContext : public RefCountedBase<MangleNumberingContext> {
+class MangleNumberingContext {
public:
virtual ~MangleNumberingContext() {}
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index 43988cd864bb..3e4c4bc7ea40 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -4228,50 +4228,153 @@ public:
/// 'use_device_ptr' with the variables 'a' and 'b'.
///
class OMPUseDevicePtrClause final
- : public OMPVarListClause<OMPUseDevicePtrClause>,
- private llvm::TrailingObjects<OMPUseDevicePtrClause, Expr *> {
+ : public OMPMappableExprListClause<OMPUseDevicePtrClause>,
+ private llvm::TrailingObjects<
+ OMPUseDevicePtrClause, Expr *, ValueDecl *, unsigned,
+ OMPClauseMappableExprCommon::MappableComponent> {
friend TrailingObjects;
friend OMPVarListClause;
+ friend OMPMappableExprListClause;
friend class OMPClauseReader;
- /// Build clause with number of variables \a N.
+
+ /// Define the sizes of each trailing object array except the last one. This
+ /// is required for TrailingObjects to work properly.
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return 3 * varlist_size();
+ }
+ size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
+ return getUniqueDeclarationsNum();
+ }
+ size_t numTrailingObjects(OverloadToken<unsigned>) const {
+ return getUniqueDeclarationsNum() + getTotalComponentListNum();
+ }
+
+ /// Build clause with number of variables \a NumVars.
///
/// \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.
+ /// \param NumVars Number of expressions listed in this clause.
+ /// \param NumUniqueDeclarations Number of unique base declarations in this
+ /// clause.
+ /// \param NumComponentLists Number of component lists in this clause.
+ /// \param NumComponents Total number of expression components in the clause.
///
- OMPUseDevicePtrClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPUseDevicePtrClause>(OMPC_use_device_ptr, StartLoc,
- LParenLoc, EndLoc, N) {}
+ explicit OMPUseDevicePtrClause(SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned NumVars,
+ unsigned NumUniqueDeclarations,
+ unsigned NumComponentLists,
+ unsigned NumComponents)
+ : OMPMappableExprListClause(OMPC_use_device_ptr, StartLoc, LParenLoc,
+ EndLoc, NumVars, NumUniqueDeclarations,
+ NumComponentLists, NumComponents) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
- /// \param N Number of variables.
+ /// \param NumVars Number of expressions listed in this clause.
+ /// \param NumUniqueDeclarations Number of unique base declarations in this
+ /// clause.
+ /// \param NumComponentLists Number of component lists in this clause.
+ /// \param NumComponents Total number of expression components in the clause.
///
- explicit OMPUseDevicePtrClause(unsigned N)
- : OMPVarListClause<OMPUseDevicePtrClause>(
- OMPC_use_device_ptr, SourceLocation(), SourceLocation(),
- SourceLocation(), N) {}
+ explicit OMPUseDevicePtrClause(unsigned NumVars,
+ unsigned NumUniqueDeclarations,
+ unsigned NumComponentLists,
+ unsigned NumComponents)
+ : OMPMappableExprListClause(OMPC_use_device_ptr, SourceLocation(),
+ SourceLocation(), SourceLocation(), NumVars,
+ NumUniqueDeclarations, NumComponentLists,
+ NumComponents) {}
+
+ /// Sets the list of references to private copies with initializers for new
+ /// private variables.
+ /// \param VL List of references.
+ void setPrivateCopies(ArrayRef<Expr *> VL);
+
+ /// 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());
+ }
+
+ /// Sets the list of references to initializer variables for new private
+ /// variables.
+ /// \param VL List of references.
+ void setInits(ArrayRef<Expr *> VL);
+
+ /// 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:
- /// Creates clause with a list of variables \a VL.
+ /// Creates clause with a list of variables \a Vars.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
+ /// \param Vars The original expression used in the clause.
+ /// \param PrivateVars Expressions referring to private copies.
+ /// \param Inits Expressions referring to private copy initializers.
+ /// \param Declarations Declarations used in the clause.
+ /// \param ComponentLists Component lists used in the clause.
///
static OMPUseDevicePtrClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL);
- /// Creates an empty clause with the place for \a N variables.
+ SourceLocation EndLoc, ArrayRef<Expr *> Vars,
+ ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
+ ArrayRef<ValueDecl *> Declarations,
+ MappableExprComponentListsRef ComponentLists);
+
+ /// Creates an empty clause with the place for \a NumVars variables.
///
/// \param C AST context.
- /// \param N The number of variables.
+ /// \param NumVars Number of expressions listed in the clause.
+ /// \param NumUniqueDeclarations Number of unique base declarations in this
+ /// clause.
+ /// \param NumComponentLists Number of unique base declarations in this
+ /// clause.
+ /// \param NumComponents Total number of expression components in the clause.
///
- static OMPUseDevicePtrClause *CreateEmpty(const ASTContext &C, unsigned N);
+ static OMPUseDevicePtrClause *CreateEmpty(const ASTContext &C,
+ unsigned NumVars,
+ unsigned NumUniqueDeclarations,
+ unsigned NumComponentLists,
+ unsigned NumComponents);
+
+ typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
+ typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
+ typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
+ typedef llvm::iterator_range<private_copies_const_iterator>
+ private_copies_const_range;
+
+ private_copies_range private_copies() {
+ return private_copies_range(getPrivateCopies().begin(),
+ getPrivateCopies().end());
+ }
+ private_copies_const_range private_copies() const {
+ return private_copies_const_range(getPrivateCopies().begin(),
+ getPrivateCopies().end());
+ }
+
+ typedef MutableArrayRef<Expr *>::iterator inits_iterator;
+ typedef ArrayRef<const Expr *>::iterator inits_const_iterator;
+ typedef llvm::iterator_range<inits_iterator> inits_range;
+ typedef llvm::iterator_range<inits_const_iterator> inits_const_range;
+
+ inits_range inits() {
+ return inits_range(getInits().begin(), getInits().end());
+ }
+ inits_const_range inits() const {
+ return inits_const_range(getInits().begin(), getInits().end());
+ }
child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
@@ -4293,50 +4396,94 @@ public:
/// 'is_device_ptr' with the variables 'a' and 'b'.
///
class OMPIsDevicePtrClause final
- : public OMPVarListClause<OMPIsDevicePtrClause>,
- private llvm::TrailingObjects<OMPIsDevicePtrClause, Expr *> {
+ : public OMPMappableExprListClause<OMPIsDevicePtrClause>,
+ private llvm::TrailingObjects<
+ OMPIsDevicePtrClause, Expr *, ValueDecl *, unsigned,
+ OMPClauseMappableExprCommon::MappableComponent> {
friend TrailingObjects;
friend OMPVarListClause;
+ friend OMPMappableExprListClause;
friend class OMPClauseReader;
- /// Build clause with number of variables \a N.
+
+ /// Define the sizes of each trailing object array except the last one. This
+ /// is required for TrailingObjects to work properly.
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return varlist_size();
+ }
+ size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
+ return getUniqueDeclarationsNum();
+ }
+ size_t numTrailingObjects(OverloadToken<unsigned>) const {
+ return getUniqueDeclarationsNum() + getTotalComponentListNum();
+ }
+ /// Build clause with number of variables \a NumVars.
///
/// \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.
+ /// \param NumVars Number of expressions listed in this clause.
+ /// \param NumUniqueDeclarations Number of unique base declarations in this
+ /// clause.
+ /// \param NumComponentLists Number of component lists in this clause.
+ /// \param NumComponents Total number of expression components in the clause.
///
- OMPIsDevicePtrClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPIsDevicePtrClause>(OMPC_is_device_ptr, StartLoc,
- LParenLoc, EndLoc, N) {}
+ explicit OMPIsDevicePtrClause(SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc,
+ unsigned NumVars,
+ unsigned NumUniqueDeclarations,
+ unsigned NumComponentLists,
+ unsigned NumComponents)
+ : OMPMappableExprListClause(OMPC_is_device_ptr, StartLoc, LParenLoc,
+ EndLoc, NumVars, NumUniqueDeclarations,
+ NumComponentLists, NumComponents) {}
/// Build an empty clause.
///
- /// \param N Number of variables.
+ /// \param NumVars Number of expressions listed in this clause.
+ /// \param NumUniqueDeclarations Number of unique base declarations in this
+ /// clause.
+ /// \param NumComponentLists Number of component lists in this clause.
+ /// \param NumComponents Total number of expression components in the clause.
///
- explicit OMPIsDevicePtrClause(unsigned N)
- : OMPVarListClause<OMPIsDevicePtrClause>(
- OMPC_is_device_ptr, SourceLocation(), SourceLocation(),
- SourceLocation(), N) {}
+ explicit OMPIsDevicePtrClause(unsigned NumVars,
+ unsigned NumUniqueDeclarations,
+ unsigned NumComponentLists,
+ unsigned NumComponents)
+ : OMPMappableExprListClause(OMPC_is_device_ptr, SourceLocation(),
+ SourceLocation(), SourceLocation(), NumVars,
+ NumUniqueDeclarations, NumComponentLists,
+ NumComponents) {}
public:
- /// Creates clause with a list of variables \a VL.
+ /// Creates clause with a list of variables \a Vars.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
+ /// \param Vars The original expression used in the clause.
+ /// \param Declarations Declarations used in the clause.
+ /// \param ComponentLists Component lists used in the clause.
///
static OMPIsDevicePtrClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL);
- /// Creates an empty clause with the place for \a N variables.
+ SourceLocation EndLoc, ArrayRef<Expr *> Vars,
+ ArrayRef<ValueDecl *> Declarations,
+ MappableExprComponentListsRef ComponentLists);
+
+ /// Creates an empty clause with the place for \a NumVars variables.
///
/// \param C AST context.
- /// \param N The number of variables.
+ /// \param NumVars Number of expressions listed in the clause.
+ /// \param NumUniqueDeclarations Number of unique base declarations in this
+ /// clause.
+ /// \param NumComponentLists Number of unique base declarations in this
+ /// clause.
+ /// \param NumComponents Total number of expression components in the clause.
///
- static OMPIsDevicePtrClause *CreateEmpty(const ASTContext &C, unsigned N);
+ static OMPIsDevicePtrClause *CreateEmpty(const ASTContext &C,
+ unsigned NumVars,
+ unsigned NumUniqueDeclarations,
+ unsigned NumComponentLists,
+ unsigned NumComponents);
child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
diff --git a/include/clang/AST/OperationKinds.def b/include/clang/AST/OperationKinds.def
index 82f494bec995..2d48a7df47b7 100644
--- a/include/clang/AST/OperationKinds.def
+++ b/include/clang/AST/OperationKinds.def
@@ -321,9 +321,14 @@ CAST_OPERATION(BuiltinFnToFnPtr)
// Convert a zero value for OpenCL event_t initialization.
CAST_OPERATION(ZeroToOCLEvent)
+// Convert a zero value for OpenCL queue_t initialization.
+CAST_OPERATION(ZeroToOCLQueue)
+
// Convert a pointer to a different address space.
CAST_OPERATION(AddressSpaceConversion)
+// Convert an integer initializer to an OpenCL sampler.
+CAST_OPERATION(IntToOCLSampler)
//===- Binary Operations -------------------------------------------------===//
// Operators listed in order of precedence.
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index f918b830d421..c0b0400cb88c 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -14,10 +14,10 @@
#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
-#include <type_traits>
-
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
@@ -27,7 +27,9 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
+#include "clang/AST/LambdaCapture.h"
#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
@@ -36,6 +38,15 @@
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/OpenMPKinds.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+#include <algorithm>
+#include <cstddef>
+#include <type_traits>
// The following three macros are used for meta programming. The code
// using them is responsible for defining macro OPERATOR().
@@ -70,7 +81,7 @@ namespace clang {
do { \
if (!getDerived().CALL_EXPR) \
return false; \
- } while (0)
+ } while (false)
/// \brief A class that does preordor or postorder
/// depth-first traversal on the entire Clang AST and visits each node.
@@ -264,10 +275,12 @@ public:
/// \returns false if the visitation was terminated early, true otherwise.
bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
- /// \brief Recursively visit a lambda capture.
+ /// \brief Recursively visit a lambda capture. \c Init is the expression that
+ /// will be used to initialize the capture.
///
/// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
+ bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
+ Expr *Init);
/// \brief Recursively visit the body of a lambda expression.
///
@@ -327,7 +340,7 @@ private:
do { \
if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) \
return false; \
- } while (0)
+ } while (false)
public:
// Declare Traverse*() for all concrete Stmt classes.
@@ -355,7 +368,8 @@ public:
#define OPERATOR(NAME) \
bool TraverseUnary##NAME(UnaryOperator *S, \
DataRecursionQueue *Queue = nullptr) { \
- TRY_TO(WalkUpFromUnary##NAME(S)); \
+ if (!getDerived().shouldTraversePostOrder()) \
+ TRY_TO(WalkUpFromUnary##NAME(S)); \
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSubExpr()); \
return true; \
} \
@@ -480,6 +494,11 @@ public:
private:
// These are helper methods used by more than one Traverse* method.
bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
+
+ // Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
+ template <typename T>
+ bool TraverseDeclTemplateParameterLists(T *D);
+
#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \
bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
DEF_TRAVERSE_TMPL_INST(Class)
@@ -565,7 +584,6 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
#undef DISPATCH_STMT
-
template <typename Derived>
bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
switch (S->getStmtClass()) {
@@ -754,7 +772,6 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
case DeclarationName::CXXConversionFunctionName:
if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
-
break;
case DeclarationName::Identifier:
@@ -869,25 +886,18 @@ bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
TRY_TO(TraverseStmt(Init->getInit()));
- if (getDerived().shouldVisitImplicitCode())
- // The braces for this one-line loop are required for MSVC2013. It
- // refuses to compile
- // for (int i : int_vec)
- // do {} while(false);
- // without braces on the for loop.
- for (VarDecl *VD : Init->getArrayIndices()) {
- TRY_TO(TraverseDecl(VD));
- }
-
return true;
}
template <typename Derived>
bool
RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
- const LambdaCapture *C) {
+ const LambdaCapture *C,
+ Expr *Init) {
if (LE->isInitCapture(C))
TRY_TO(TraverseDecl(C->getCapturedVar()));
+ else
+ TRY_TO(TraverseStmt(Init));
return true;
}
@@ -1034,6 +1044,8 @@ DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
+DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
+
DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
DEF_TRAVERSE_TYPE(ObjCObjectType, {
@@ -1265,6 +1277,8 @@ DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
DEF_TRAVERSE_TYPELOC(PackExpansionType,
{ TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
+DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {})
+
DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
@@ -1383,6 +1397,8 @@ DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
+DEF_TRAVERSE_DECL(ExportDecl, {})
+
DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
})
@@ -1489,6 +1505,8 @@ DEF_TRAVERSE_DECL(UsingDecl, {
TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
})
+DEF_TRAVERSE_DECL(UsingPackDecl, {})
+
DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
})
@@ -1527,6 +1545,16 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
}
template <typename Derived>
+template <typename T>
+bool RecursiveASTVisitor<Derived>::TraverseDeclTemplateParameterLists(T *D) {
+ for (unsigned i = 0; i < D->getNumTemplateParameterLists(); i++) {
+ TemplateParameterList *TPL = D->getTemplateParameterList(i);
+ TraverseTemplateParameterListHelper(TPL);
+ }
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
ClassTemplateDecl *D) {
for (auto *SD : D->specializations()) {
@@ -1687,6 +1715,8 @@ DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
})
DEF_TRAVERSE_DECL(EnumDecl, {
+ TRY_TO(TraverseDeclTemplateParameterLists(D));
+
if (D->getTypeForDecl())
TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
@@ -1701,6 +1731,7 @@ bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
// We shouldn't traverse D->getTypeForDecl(); it's a result of
// declaring the type, not something that was written in the source.
+ TRY_TO(TraverseDeclTemplateParameterLists(D));
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
return true;
}
@@ -1795,6 +1826,7 @@ DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
+ TRY_TO(TraverseDeclTemplateParameterLists(D));
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
if (D->getTypeSourceInfo())
TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
@@ -1803,6 +1835,18 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
return true;
}
+DEF_TRAVERSE_DECL(DecompositionDecl, {
+ TRY_TO(TraverseVarHelper(D));
+ for (auto *Binding : D->bindings()) {
+ TRY_TO(TraverseDecl(Binding));
+ }
+})
+
+DEF_TRAVERSE_DECL(BindingDecl, {
+ if (getDerived().shouldVisitImplicitCode())
+ TRY_TO(TraverseStmt(D->getBinding()));
+})
+
DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
DEF_TRAVERSE_DECL(FieldDecl, {
@@ -1829,6 +1873,7 @@ DEF_TRAVERSE_DECL(ObjCIvarDecl, {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
+ TRY_TO(TraverseDeclTemplateParameterLists(D));
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
@@ -2041,6 +2086,7 @@ DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
+
DEF_TRAVERSE_STMT(CXXForRangeStmt, {
if (!getDerived().shouldVisitImplicitCode()) {
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
@@ -2050,10 +2096,12 @@ DEF_TRAVERSE_STMT(CXXForRangeStmt, {
ShouldVisitChildren = false;
}
})
+
DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
})
+
DEF_TRAVERSE_STMT(ReturnStmt, {})
DEF_TRAVERSE_STMT(SwitchStmt, {})
DEF_TRAVERSE_STMT(WhileStmt, {})
@@ -2249,10 +2297,11 @@ DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
// Walk only the visible parts of lambda expressions.
DEF_TRAVERSE_STMT(LambdaExpr, {
- for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
- CEnd = S->explicit_capture_end();
- C != CEnd; ++C) {
- TRY_TO(TraverseLambdaCapture(S, C));
+ for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
+ const LambdaCapture *C = S->capture_begin() + I;
+ if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
+ TRY_TO(TraverseLambdaCapture(S, C, S->capture_init_begin()[I]));
+ }
}
TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
@@ -2300,23 +2349,31 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
DEF_TRAVERSE_STMT(AddrLabelExpr, {})
DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
DEF_TRAVERSE_STMT(OMPArraySectionExpr, {})
+
DEF_TRAVERSE_STMT(BlockExpr, {
TRY_TO(TraverseDecl(S->getBlockDecl()));
return true; // no child statements to loop through.
})
+
DEF_TRAVERSE_STMT(ChooseExpr, {})
DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
})
DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
-DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
+
+DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {
+ if (getDerived().shouldVisitImplicitCode())
+ TRY_TO(TraverseStmt(S->getExpr()));
+})
+
DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
DEF_TRAVERSE_STMT(ExprWithCleanups, {})
DEF_TRAVERSE_STMT(CXXInheritedCtorInitExpr, {})
DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
+
DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
@@ -2324,6 +2381,7 @@ DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
})
+
DEF_TRAVERSE_STMT(CXXThisExpr, {})
DEF_TRAVERSE_STMT(CXXThrowExpr, {})
DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
@@ -2333,25 +2391,38 @@ DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
DEF_TRAVERSE_STMT(GNUNullExpr, {})
DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
DEF_TRAVERSE_STMT(NoInitExpr, {})
+DEF_TRAVERSE_STMT(ArrayInitLoopExpr, {
+ // FIXME: The source expression of the OVE should be listed as
+ // a child of the ArrayInitLoopExpr.
+ if (OpaqueValueExpr *OVE = S->getCommonExpr())
+ TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(OVE->getSourceExpr());
+})
+DEF_TRAVERSE_STMT(ArrayInitIndexExpr, {})
DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
+
DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
})
+
DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
+
DEF_TRAVERSE_STMT(ObjCMessageExpr, {
if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
})
+
DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
+
DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
})
+
DEF_TRAVERSE_STMT(ObjCAvailabilityCheckExpr, {})
DEF_TRAVERSE_STMT(ParenExpr, {})
DEF_TRAVERSE_STMT(ParenListExpr, {})
@@ -2574,6 +2645,30 @@ DEF_TRAVERSE_STMT(OMPDistributeSimdDirective,
DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPTargetSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTeamsDistributeDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTeamsDistributeSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetTeamsDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
// OpenMP clauses.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index eaa22f8d0102..cd5f186a2086 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -15,7 +15,6 @@
#define LLVM_CLANG_AST_REDECLARABLE_H
#include "clang/AST/ExternalASTSource.h"
-#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Casting.h"
#include <iterator>
@@ -280,6 +279,68 @@ public:
bool isFirstDecl() const { return getFirstDecl() == this; }
};
-}
+/// A wrapper class around a pointer that always points to its canonical
+/// declaration.
+///
+/// CanonicalDeclPtr<decl_type> behaves just like decl_type*, except we call
+/// decl_type::getCanonicalDecl() on construction.
+///
+/// This is useful for hashtables that you want to be keyed on a declaration's
+/// canonical decl -- if you use CanonicalDeclPtr as the key, you don't need to
+/// remember to call getCanonicalDecl() everywhere.
+template <typename decl_type> class CanonicalDeclPtr {
+public:
+ CanonicalDeclPtr() : Ptr(nullptr) {}
+ CanonicalDeclPtr(decl_type *Ptr)
+ : Ptr(Ptr ? Ptr->getCanonicalDecl() : nullptr) {}
+ CanonicalDeclPtr(const CanonicalDeclPtr &) = default;
+ CanonicalDeclPtr &operator=(const CanonicalDeclPtr &) = default;
+
+ operator decl_type *() { return Ptr; }
+ operator const decl_type *() const { return Ptr; }
+
+ decl_type *operator->() { return Ptr; }
+ const decl_type *operator->() const { return Ptr; }
+
+ decl_type &operator*() { return *Ptr; }
+ const decl_type &operator*() const { return *Ptr; }
+
+private:
+ friend struct llvm::DenseMapInfo<CanonicalDeclPtr<decl_type>>;
+
+ decl_type *Ptr;
+};
+} // namespace clang
+
+namespace llvm {
+template <typename decl_type>
+struct DenseMapInfo<clang::CanonicalDeclPtr<decl_type>> {
+ using CanonicalDeclPtr = clang::CanonicalDeclPtr<decl_type>;
+ using BaseInfo = DenseMapInfo<decl_type *>;
+
+ static CanonicalDeclPtr getEmptyKey() {
+ // Construct our CanonicalDeclPtr this way because the regular constructor
+ // would dereference P.Ptr, which is not allowed.
+ CanonicalDeclPtr P;
+ P.Ptr = BaseInfo::getEmptyKey();
+ return P;
+ }
+
+ static CanonicalDeclPtr getTombstoneKey() {
+ CanonicalDeclPtr P;
+ P.Ptr = BaseInfo::getTombstoneKey();
+ return P;
+ }
+
+ static unsigned getHashValue(const CanonicalDeclPtr &P) {
+ return BaseInfo::getHashValue(P);
+ }
+
+ static bool isEqual(const CanonicalDeclPtr &LHS,
+ const CanonicalDeclPtr &RHS) {
+ return BaseInfo::isEqual(LHS, RHS);
+ }
+};
+} // namespace llvm
#endif
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 96847cf88f96..e28675d6a828 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -56,7 +56,7 @@ namespace clang {
/// Stmt - This represents one statement.
///
-class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt {
+class alignas(void *) Stmt {
public:
enum StmtClass {
NoStmtClass = 0,
@@ -71,10 +71,10 @@ public:
// Make vanilla 'new' and 'delete' illegal for Stmts.
protected:
- void *operator new(size_t bytes) LLVM_NOEXCEPT {
+ void *operator new(size_t bytes) noexcept {
llvm_unreachable("Stmts cannot be allocated with regular 'new'.");
}
- void operator delete(void *data) LLVM_NOEXCEPT {
+ void operator delete(void *data) noexcept {
llvm_unreachable("Stmts cannot be released with regular 'delete'.");
}
@@ -284,12 +284,12 @@ public:
return operator new(bytes, *C, alignment);
}
- void *operator new(size_t bytes, void *mem) LLVM_NOEXCEPT { return mem; }
+ void *operator new(size_t bytes, void *mem) noexcept { return mem; }
- void operator delete(void *, const ASTContext &, unsigned) LLVM_NOEXCEPT {}
- void operator delete(void *, const ASTContext *, unsigned) LLVM_NOEXCEPT {}
- void operator delete(void *, size_t) LLVM_NOEXCEPT {}
- void operator delete(void *, void *) LLVM_NOEXCEPT {}
+ void operator delete(void *, const ASTContext &, unsigned) noexcept {}
+ void operator delete(void *, const ASTContext *, unsigned) noexcept {}
+ void operator delete(void *, size_t) noexcept {}
+ void operator delete(void *, void *) noexcept {}
public:
/// \brief A placeholder type used to construct an empty shell of a
@@ -340,7 +340,7 @@ protected:
public:
Stmt(StmtClass SC) {
- static_assert(sizeof(*this) % llvm::AlignOf<void *>::Alignment == 0,
+ static_assert(sizeof(*this) % alignof(void *) == 0,
"Insufficient alignment!");
StmtBits.sClass = SC;
if (StatisticsEnabled) Stmt::addStmtClass(SC);
@@ -387,6 +387,9 @@ public:
/// Skip past any implicit AST nodes which might surround this
/// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
Stmt *IgnoreImplicit();
+ const Stmt *IgnoreImplicit() const {
+ return const_cast<Stmt *>(this)->IgnoreImplicit();
+ }
/// \brief Skip no-op (attributed, compound) container stmts and skip captured
/// stmt at the top, if \a IgnoreCaptured is true.
@@ -933,6 +936,8 @@ public:
bool isConstexpr() const { return IfStmtBits.IsConstexpr; }
void setConstexpr(bool C) { IfStmtBits.IsConstexpr = C; }
+ bool isObjCAvailabilityCheck() const;
+
SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; }
SourceLocation getLocEnd() const LLVM_READONLY {
if (SubExprs[ELSE])
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index 1d29c228a4b3..8eef34cb21b3 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -304,6 +304,8 @@ class CoroutineBodyStmt : public Stmt {
FinalSuspend, ///< The final suspend statement, run after the body.
OnException, ///< Handler for exceptions thrown in the body.
OnFallthrough, ///< Handler for control flow falling off the body.
+ Allocate, ///< Coroutine frame memory allocation.
+ Deallocate, ///< Coroutine frame memory deallocation.
ReturnValue, ///< Return value for thunk function.
FirstParamMove ///< First offset for move construction of parameter copies.
};
@@ -313,6 +315,7 @@ class CoroutineBodyStmt : public Stmt {
public:
CoroutineBodyStmt(Stmt *Body, Stmt *Promise, Stmt *InitSuspend,
Stmt *FinalSuspend, Stmt *OnException, Stmt *OnFallthrough,
+ Expr *Allocate, Stmt *Deallocate,
Expr *ReturnValue, ArrayRef<Expr *> ParamMoves)
: Stmt(CoroutineBodyStmtClass) {
SubStmts[CoroutineBodyStmt::Body] = Body;
@@ -321,6 +324,8 @@ public:
SubStmts[CoroutineBodyStmt::FinalSuspend] = FinalSuspend;
SubStmts[CoroutineBodyStmt::OnException] = OnException;
SubStmts[CoroutineBodyStmt::OnFallthrough] = OnFallthrough;
+ SubStmts[CoroutineBodyStmt::Allocate] = Allocate;
+ SubStmts[CoroutineBodyStmt::Deallocate] = Deallocate;
SubStmts[CoroutineBodyStmt::ReturnValue] = ReturnValue;
// FIXME: Tail-allocate space for parameter move expressions and store them.
assert(ParamMoves.empty() && "not implemented yet");
@@ -345,6 +350,9 @@ public:
return SubStmts[SubStmt::OnFallthrough];
}
+ Expr *getAllocate() const { return cast<Expr>(SubStmts[SubStmt::Allocate]); }
+ Stmt *getDeallocate() const { return SubStmts[SubStmt::Deallocate]; }
+
Expr *getReturnValueInit() const {
return cast<Expr>(SubStmts[SubStmt::ReturnValue]);
}
@@ -405,10 +413,13 @@ public:
SourceLocation getLocStart() const LLVM_READONLY { return CoreturnLoc; }
SourceLocation getLocEnd() const LLVM_READONLY {
- return getOperand()->getLocEnd();
+ return getOperand() ? getOperand()->getLocEnd() : getLocStart();
}
child_range children() {
+ if (!getOperand())
+ return child_range(SubStmts + SubStmt::PromiseCall,
+ SubStmts + SubStmt::Count);
return child_range(SubStmts, SubStmts + SubStmt::Count);
}
diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h
index dac4495c6a0f..92eb64430f73 100644
--- a/include/clang/AST/StmtGraphTraits.h
+++ b/include/clang/AST/StmtGraphTraits.h
@@ -25,19 +25,18 @@ namespace llvm {
template <> struct GraphTraits<clang::Stmt*> {
- typedef clang::Stmt NodeType;
typedef clang::Stmt * NodeRef;
typedef clang::Stmt::child_iterator ChildIteratorType;
typedef llvm::df_iterator<clang::Stmt*> nodes_iterator;
- static NodeType* getEntryNode(clang::Stmt* S) { return S; }
+ static NodeRef getEntryNode(clang::Stmt *S) { return S; }
- static inline ChildIteratorType child_begin(NodeType* N) {
+ static ChildIteratorType child_begin(NodeRef N) {
if (N) return N->child_begin();
else return ChildIteratorType();
}
- static inline ChildIteratorType child_end(NodeType* N) {
+ static ChildIteratorType child_end(NodeRef N) {
if (N) return N->child_end();
else return ChildIteratorType();
}
@@ -53,19 +52,18 @@ template <> struct GraphTraits<clang::Stmt*> {
template <> struct GraphTraits<const clang::Stmt*> {
- typedef const clang::Stmt NodeType;
typedef const clang::Stmt * NodeRef;
typedef clang::Stmt::const_child_iterator ChildIteratorType;
typedef llvm::df_iterator<const clang::Stmt*> nodes_iterator;
- static NodeType* getEntryNode(const clang::Stmt* S) { return S; }
+ static NodeRef getEntryNode(const clang::Stmt *S) { return S; }
- static inline ChildIteratorType child_begin(NodeType* N) {
+ static ChildIteratorType child_begin(NodeRef N) {
if (N) return N->child_begin();
else return ChildIteratorType();
}
- static inline ChildIteratorType child_end(NodeType* N) {
+ static ChildIteratorType child_end(NodeRef N) {
if (N) return N->child_end();
else return ChildIteratorType();
}
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index 1e357263461e..80300dae80df 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -70,7 +70,7 @@ protected:
: Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
NumChildren(NumChildren),
- ClausesOffset(llvm::alignTo(sizeof(T), llvm::alignOf<OMPClause *>())) {}
+ ClausesOffset(llvm::alignTo(sizeof(T), alignof(OMPClause *))) {}
/// \brief Sets the list of variables for this clause.
///
@@ -773,7 +773,12 @@ public:
T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
- T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
+ T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
+ T->getStmtClass() == OMPTargetSimdDirectiveClass ||
+ T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
+ T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
+ T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass ||
+ T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
}
};
@@ -3090,6 +3095,549 @@ public:
}
};
+/// This represents '#pragma omp target simd' directive.
+///
+/// \code
+/// #pragma omp target simd private(a) map(b) safelen(c)
+/// \endcode
+/// In this example directive '#pragma omp target simd' has clauses 'private'
+/// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
+/// the variable 'c'.
+///
+class OMPTargetSimdDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+
+ /// 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.
+ ///
+ OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPTargetSimdDirectiveClass,
+ OMPD_target_simd, StartLoc, EndLoc, CollapsedNum,
+ NumClauses) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTargetSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPTargetSimdDirectiveClass, OMPD_target_simd,
+ SourceLocation(),SourceLocation(), CollapsedNum,
+ NumClauses) {}
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTargetSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// 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 OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTargetSimdDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp teams distribute' directive.
+///
+/// \code
+/// #pragma omp teams distribute private(a,b)
+/// \endcode
+/// In this example directive '#pragma omp teams distribute' has clauses
+/// 'private' with the variables 'a' and 'b'
+///
+class OMPTeamsDistributeDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+
+ /// 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.
+ ///
+ OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass,
+ OMPD_teams_distribute, StartLoc, EndLoc,
+ CollapsedNum, NumClauses) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTeamsDistributeDirective(unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass,
+ OMPD_teams_distribute, SourceLocation(),
+ SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTeamsDistributeDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// 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 OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp teams distribute simd'
+/// combined directive.
+///
+/// \code
+/// #pragma omp teams distribute simd private(a,b)
+/// \endcode
+/// In this example directive '#pragma omp teams distribute simd'
+/// has clause 'private' with the variables 'a' and 'b'
+///
+class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+
+ /// 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.
+ ///
+ OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc, unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass,
+ OMPD_teams_distribute_simd, StartLoc, EndLoc,
+ CollapsedNum, NumClauses) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass,
+ OMPD_teams_distribute_simd, SourceLocation(),
+ SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTeamsDistributeSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// 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 OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp teams distribute parallel for simd' composite
+/// directive.
+///
+/// \code
+/// #pragma omp teams distribute parallel for simd private(x)
+/// \endcode
+/// In this example directive '#pragma omp teams distribute parallel for simd'
+/// has clause 'private' with the variables 'x'
+///
+class OMPTeamsDistributeParallelForSimdDirective final
+ : public OMPLoopDirective {
+ friend class ASTStmtReader;
+
+ /// 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.
+ ///
+ OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass,
+ OMPD_teams_distribute_parallel_for_simd, StartLoc,
+ EndLoc, CollapsedNum, NumClauses) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass,
+ OMPD_teams_distribute_parallel_for_simd,
+ SourceLocation(), SourceLocation(), CollapsedNum,
+ NumClauses) {}
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTeamsDistributeParallelForSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// 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 OMPTeamsDistributeParallelForSimdDirective *
+ CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp teams distribute parallel for' composite
+/// directive.
+///
+/// \code
+/// #pragma omp teams distribute parallel for private(x)
+/// \endcode
+/// In this example directive '#pragma omp teams distribute parallel for'
+/// has clause 'private' with the variables 'x'
+///
+class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+
+ /// 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.
+ ///
+ OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
+ OMPD_teams_distribute_parallel_for, StartLoc, EndLoc,
+ CollapsedNum, NumClauses) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
+ OMPD_teams_distribute_parallel_for, SourceLocation(),
+ SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTeamsDistributeParallelForDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// 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 OMPTeamsDistributeParallelForDirective *
+ CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp target teams' directive.
+///
+/// \code
+/// #pragma omp target teams if(a>0)
+/// \endcode
+/// In this example directive '#pragma omp target teams' has clause 'if' with
+/// condition 'a>0'.
+///
+class OMPTargetTeamsDirective final : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// 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.
+ ///
+ OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass,
+ OMPD_target_teams, StartLoc, EndLoc, NumClauses,
+ 1) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTargetTeamsDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass,
+ OMPD_target_teams, SourceLocation(),
+ SourceLocation(), NumClauses, 1) {}
+
+public:
+ /// 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 OMPTargetTeamsDirective *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt);
+
+ /// Creates an empty directive with the place for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp target teams distribute' combined directive.
+///
+/// \code
+/// #pragma omp target teams distribute private(x)
+/// \endcode
+/// In this example directive '#pragma omp target teams distribute' has clause
+/// 'private' with the variables 'x'
+///
+class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+
+ /// 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.
+ ///
+ OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass,
+ OMPD_target_teams_distribute, StartLoc, EndLoc,
+ CollapsedNum, NumClauses) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass,
+ OMPD_target_teams_distribute, SourceLocation(),
+ SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTargetTeamsDistributeDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// 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 OMPTargetTeamsDistributeDirective *
+ CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp target teams distribute parallel for' combined
+/// directive.
+///
+/// \code
+/// #pragma omp target teams distribute parallel for private(x)
+/// \endcode
+/// In this example directive '#pragma omp target teams distribute parallel
+/// for' has clause 'private' with the variables 'x'
+///
+class OMPTargetTeamsDistributeParallelForDirective final
+ : public OMPLoopDirective {
+ friend class ASTStmtReader;
+
+ /// 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.
+ ///
+ OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this,
+ OMPTargetTeamsDistributeParallelForDirectiveClass,
+ OMPD_target_teams_distribute_parallel_for, StartLoc,
+ EndLoc, CollapsedNum, NumClauses) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(
+ this, OMPTargetTeamsDistributeParallelForDirectiveClass,
+ OMPD_target_teams_distribute_parallel_for, SourceLocation(),
+ SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTargetTeamsDistributeParallelForDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// 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 OMPTargetTeamsDistributeParallelForDirective *
+ CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() ==
+ OMPTargetTeamsDistributeParallelForDirectiveClass;
+ }
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index b9c2c08943e9..7f289862578d 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -301,6 +301,10 @@ public:
Integer.Type = T.getAsOpaquePtr();
}
+ /// \brief If this is a non-type template argument, get its type. Otherwise,
+ /// returns a null QualType.
+ QualType getNonTypeTemplateArgumentType() const;
+
/// \brief Retrieve the template argument as an expression.
Expr *getAsExpr() const {
assert(getKind() == Expression && "Unexpected kind");
@@ -326,8 +330,8 @@ public:
/// \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());
+ ArrayRef<TemplateArgument> pack_elements() const {
+ return llvm::makeArrayRef(pack_begin(), pack_end());
}
/// \brief The number of template arguments in the given template argument
@@ -592,6 +596,10 @@ public:
return getTrailingObjects<TemplateArgumentLoc>();
}
+ llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
+ return llvm::makeArrayRef(getTemplateArgs(), NumTemplateArgs);
+ }
+
const TemplateArgumentLoc &operator[](unsigned I) const {
return getTemplateArgs()[I];
}
@@ -607,7 +615,7 @@ public:
/// as such, doesn't contain the array of TemplateArgumentLoc itself,
/// but expects the containing object to also provide storage for
/// that.
-struct LLVM_ALIGNAS(LLVM_PTR_SIZE) ASTTemplateKWAndArgsInfo {
+struct alignas(void *) ASTTemplateKWAndArgsInfo {
/// \brief The source location of the left angle bracket ('<').
SourceLocation LAngleLoc;
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 1067c086c764..744a408e5796 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -88,6 +88,7 @@ namespace clang {
class ObjCInterfaceDecl;
class ObjCProtocolDecl;
class ObjCMethodDecl;
+ class ObjCTypeParamDecl;
class UnresolvedUsingTypenameDecl;
class Expr;
class Stmt;
@@ -984,6 +985,7 @@ public:
void dump(const char *s) const;
void dump() const;
+ void dump(llvm::raw_ostream &OS) const;
void Profile(llvm::FoldingSetNodeID &ID) const {
ID.AddPointer(getAsOpaquePtr());
@@ -1377,7 +1379,7 @@ protected:
/// Extra information which affects how the function is called, like
/// regparm and the calling convention.
- unsigned ExtInfo : 9;
+ unsigned ExtInfo : 10;
/// Used only by FunctionProtoType, put here to pack with the
/// other bitfields.
@@ -1728,7 +1730,8 @@ public:
bool isObjCARCBridgableType() const;
bool isCARCBridgableType() const;
bool isTemplateTypeParmType() const; // C++ template type parameter
- bool isNullPtrType() const; // C++0x nullptr_t
+ bool isNullPtrType() const; // C++11 std::nullptr_t
+ bool isAlignValT() const; // C++17 std::align_val_t
bool isAtomicType() const; // C11 _Atomic()
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
@@ -2003,6 +2006,7 @@ public:
}
CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
void dump() const;
+ void dump(llvm::raw_ostream &OS) const;
friend class ASTReader;
friend class ASTWriter;
@@ -2262,19 +2266,15 @@ public:
/// Represents a pointer type decayed from an array or function type.
class DecayedType : public AdjustedType {
- DecayedType(QualType OriginalType, QualType DecayedPtr, QualType CanonicalPtr)
- : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) {
- assert(isa<PointerType>(getAdjustedType()));
- }
+ inline
+ DecayedType(QualType OriginalType, QualType Decayed, QualType Canonical);
friend class ASTContext; // ASTContext creates these.
public:
QualType getDecayedType() const { return getAdjustedType(); }
- QualType getPointeeType() const {
- return cast<PointerType>(getDecayedType())->getPointeeType();
- }
+ inline QualType getPointeeType() const;
static bool classof(const Type *T) { return T->getTypeClass() == Decayed; }
};
@@ -2812,7 +2812,8 @@ public:
/// __attribute__((ext_vector_type(n)), where "n" is the number of elements.
/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This
/// class enables syntactic extensions, like Vector Components for accessing
-/// points, colors, and textures (modeled after OpenGL Shading Language).
+/// points (as .xyzw), colors (as .rgba), and textures (modeled after OpenGL
+/// Shading Language).
class ExtVectorType : public VectorType {
ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {}
@@ -2821,10 +2822,10 @@ public:
static int getPointAccessorIdx(char c) {
switch (c) {
default: return -1;
- case 'x': return 0;
- case 'y': return 1;
- case 'z': return 2;
- case 'w': return 3;
+ case 'x': case 'r': return 0;
+ case 'y': case 'g': return 1;
+ case 'z': case 'b': return 2;
+ case 'w': case 'a': return 3;
}
}
static int getNumericAccessorIdx(char c) {
@@ -2855,13 +2856,15 @@ public:
}
}
- static int getAccessorIdx(char c) {
- if (int idx = getPointAccessorIdx(c)+1) return idx-1;
- return getNumericAccessorIdx(c);
+ static int getAccessorIdx(char c, bool isNumericAccessor) {
+ if (isNumericAccessor)
+ return getNumericAccessorIdx(c);
+ else
+ return getPointAccessorIdx(c);
}
- bool isAccessorWithinNumElements(char c) const {
- if (int idx = getAccessorIdx(c)+1)
+ bool isAccessorWithinNumElements(char c, bool isNumericAccessor) const {
+ if (int idx = getAccessorIdx(c, isNumericAccessor)+1)
return unsigned(idx-1) < getNumElements();
return false;
}
@@ -2902,19 +2905,19 @@ class FunctionType : public Type {
// * AST read and write
// * Codegen
class ExtInfo {
- // Feel free to rearrange or add bits, but if you go over 9,
+ // Feel free to rearrange or add bits, but if you go over 10,
// you'll need to adjust both the Bits field below and
// Type::FunctionTypeBitfields.
// | CC |noreturn|produces|regparm|
- // |0 .. 3| 4 | 5 | 6 .. 8|
+ // |0 .. 4| 5 | 6 | 7 .. 9|
//
// regparm is either 0 (no regparm attribute) or the regparm value+1.
- enum { CallConvMask = 0xF };
- enum { NoReturnMask = 0x10 };
- enum { ProducesResultMask = 0x20 };
+ enum { CallConvMask = 0x1F };
+ enum { NoReturnMask = 0x20 };
+ enum { ProducesResultMask = 0x40 };
enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask),
- RegParmOffset = 6 }; // Assumed to be the last field
+ RegParmOffset = 7 }; // Assumed to be the last field
uint16_t Bits;
@@ -3318,6 +3321,9 @@ public:
}
/// Return whether this function has a dependent exception spec.
bool hasDependentExceptionSpec() const;
+ /// Return whether this function has an instantiation-dependent exception
+ /// spec.
+ bool hasInstantiationDependentExceptionSpec() const;
/// Result type of getNoexceptSpec().
enum NoexceptResult {
NR_NoNoexcept, ///< There is no noexcept specifier.
@@ -3359,9 +3365,15 @@ public:
return reinterpret_cast<FunctionDecl *const *>(param_type_end())[1];
}
/// Determine whether this function type has a non-throwing exception
+ /// specification.
+ CanThrowResult canThrow(const ASTContext &Ctx) const;
+ /// Determine whether this function type has a non-throwing exception
/// specification. If this depends on template arguments, returns
/// \c ResultIfDependent.
- bool isNothrow(const ASTContext &Ctx, bool ResultIfDependent = false) const;
+ bool isNothrow(const ASTContext &Ctx, bool ResultIfDependent = false) const {
+ return ResultIfDependent ? canThrow(Ctx) != CT_Can
+ : canThrow(Ctx) == CT_Cannot;
+ }
bool isVariadic() const { return Variadic; }
@@ -3462,7 +3474,8 @@ public:
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
param_type_iterator ArgTys, unsigned NumArgs,
- const ExtProtoInfo &EPI, const ASTContext &Context);
+ const ExtProtoInfo &EPI, const ASTContext &Context,
+ bool Canonical);
};
/// \brief Represents the dependent type named by a dependently-scoped
@@ -3788,6 +3801,7 @@ public:
attr_fastcall,
attr_stdcall,
attr_thiscall,
+ attr_regcall,
attr_pascal,
attr_swiftcall,
attr_vectorcall,
@@ -4078,18 +4092,22 @@ public:
/// \brief Represents a C++11 auto or C++14 decltype(auto) type.
///
/// These types are usually a placeholder for a deduced type. However, before
-/// the initializer is attached, or if the initializer is type-dependent, there
-/// is no deduced type and an auto type is canonical. In the latter case, it is
-/// also a dependent type.
+/// the initializer is attached, or (usually) if the initializer is
+/// type-dependent, there is no deduced type and an auto type is canonical. In
+/// the latter case, it is also a dependent type.
class AutoType : public Type, public llvm::FoldingSetNode {
AutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent)
: Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
/*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent,
- /*VariablyModified=*/false,
- /*ContainsParameterPack=*/DeducedType.isNull()
- ? false : DeducedType->containsUnexpandedParameterPack()) {
- assert((DeducedType.isNull() || !IsDependent) &&
- "auto deduced to dependent type");
+ /*VariablyModified=*/false, /*ContainsParameterPack=*/false) {
+ if (!DeducedType.isNull()) {
+ if (DeducedType->isDependentType())
+ setDependent();
+ if (DeducedType->isInstantiationDependentType())
+ setInstantiationDependent();
+ if (DeducedType->containsUnexpandedParameterPack())
+ setContainsUnexpandedParameterPack();
+ }
AutoTypeBits.Keyword = (unsigned)Keyword;
}
@@ -4696,6 +4714,102 @@ public:
}
};
+/// This class wraps the list of protocol qualifiers. For types that can
+/// take ObjC protocol qualifers, they can subclass this class.
+template <class T>
+class ObjCProtocolQualifiers {
+protected:
+ ObjCProtocolQualifiers() {}
+ ObjCProtocolDecl * const *getProtocolStorage() const {
+ return const_cast<ObjCProtocolQualifiers*>(this)->getProtocolStorage();
+ }
+
+ ObjCProtocolDecl **getProtocolStorage() {
+ return static_cast<T*>(this)->getProtocolStorageImpl();
+ }
+ void setNumProtocols(unsigned N) {
+ static_cast<T*>(this)->setNumProtocolsImpl(N);
+ }
+ void initialize(ArrayRef<ObjCProtocolDecl *> protocols) {
+ setNumProtocols(protocols.size());
+ assert(getNumProtocols() == protocols.size() &&
+ "bitfield overflow in protocol count");
+ if (!protocols.empty())
+ memcpy(getProtocolStorage(), protocols.data(),
+ protocols.size() * sizeof(ObjCProtocolDecl*));
+ }
+
+public:
+ typedef ObjCProtocolDecl * const *qual_iterator;
+ typedef llvm::iterator_range<qual_iterator> qual_range;
+
+ qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
+ qual_iterator qual_begin() const { return getProtocolStorage(); }
+ qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
+
+ bool qual_empty() const { return getNumProtocols() == 0; }
+
+ /// Return the number of qualifying protocols in this type, or 0 if
+ /// there are none.
+ unsigned getNumProtocols() const {
+ return static_cast<const T*>(this)->getNumProtocolsImpl();
+ }
+
+ /// Fetch a protocol by index.
+ ObjCProtocolDecl *getProtocol(unsigned I) const {
+ assert(I < getNumProtocols() && "Out-of-range protocol access");
+ return qual_begin()[I];
+ }
+
+ /// Retrieve all of the protocol qualifiers.
+ ArrayRef<ObjCProtocolDecl *> getProtocols() const {
+ return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols());
+ }
+};
+
+/// Represents a type parameter type in Objective C. It can take
+/// a list of protocols.
+class ObjCTypeParamType : public Type,
+ public ObjCProtocolQualifiers<ObjCTypeParamType>,
+ public llvm::FoldingSetNode {
+ friend class ASTContext;
+ friend class ObjCProtocolQualifiers<ObjCTypeParamType>;
+
+ /// The number of protocols stored on this type.
+ unsigned NumProtocols : 6;
+
+ ObjCTypeParamDecl *OTPDecl;
+ /// The protocols are stored after the ObjCTypeParamType node. In the
+ /// canonical type, the list of protocols are sorted alphabetically
+ /// and uniqued.
+ ObjCProtocolDecl **getProtocolStorageImpl();
+ /// Return the number of qualifying protocols in this interface type,
+ /// or 0 if there are none.
+ unsigned getNumProtocolsImpl() const {
+ return NumProtocols;
+ }
+ void setNumProtocolsImpl(unsigned N) {
+ NumProtocols = N;
+ }
+ ObjCTypeParamType(const ObjCTypeParamDecl *D,
+ QualType can,
+ ArrayRef<ObjCProtocolDecl *> protocols);
+public:
+ bool isSugared() const { return true; }
+ QualType desugar() const { return getCanonicalTypeInternal(); }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == ObjCTypeParam;
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID);
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ const ObjCTypeParamDecl *OTPDecl,
+ ArrayRef<ObjCProtocolDecl *> protocols);
+
+ ObjCTypeParamDecl *getDecl() const { return OTPDecl; }
+};
+
/// Represents a class type in Objective C.
///
/// Every Objective C type is a combination of a base type, a set of
@@ -4724,7 +4838,9 @@ public:
/// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType
/// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually
/// this should get its own sugar class to better represent the source.
-class ObjCObjectType : public Type {
+class ObjCObjectType : public Type,
+ public ObjCProtocolQualifiers<ObjCObjectType> {
+ friend class ObjCProtocolQualifiers<ObjCObjectType>;
// ObjCObjectType.NumTypeArgs - the number of type arguments stored
// after the ObjCObjectPointerType node.
// ObjCObjectType.NumProtocols - the number of protocols stored
@@ -4744,16 +4860,20 @@ class ObjCObjectType : public Type {
mutable llvm::PointerIntPair<const ObjCObjectType *, 1, bool>
CachedSuperClassType;
- ObjCProtocolDecl * const *getProtocolStorage() const {
- return const_cast<ObjCObjectType*>(this)->getProtocolStorage();
- }
-
QualType *getTypeArgStorage();
const QualType *getTypeArgStorage() const {
return const_cast<ObjCObjectType *>(this)->getTypeArgStorage();
}
- ObjCProtocolDecl **getProtocolStorage();
+ ObjCProtocolDecl **getProtocolStorageImpl();
+ /// Return the number of qualifying protocols in this interface type,
+ /// or 0 if there are none.
+ unsigned getNumProtocolsImpl() const {
+ return ObjCObjectTypeBits.NumProtocols;
+ }
+ void setNumProtocolsImpl(unsigned N) {
+ ObjCObjectTypeBits.NumProtocols = N;
+ }
protected:
ObjCObjectType(QualType Canonical, QualType Base,
@@ -4830,30 +4950,6 @@ public:
ObjCObjectTypeBits.NumTypeArgs);
}
- typedef ObjCProtocolDecl * const *qual_iterator;
- typedef llvm::iterator_range<qual_iterator> qual_range;
-
- qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
- qual_iterator qual_begin() const { return getProtocolStorage(); }
- qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
-
- bool qual_empty() const { return getNumProtocols() == 0; }
-
- /// Return the number of qualifying protocols in this interface type,
- /// or 0 if there are none.
- unsigned getNumProtocols() const { return ObjCObjectTypeBits.NumProtocols; }
-
- /// Fetch a protocol by index.
- ObjCProtocolDecl *getProtocol(unsigned I) const {
- assert(I < getNumProtocols() && "Out-of-range protocol access");
- return qual_begin()[I];
- }
-
- /// Retrieve all of the protocol qualifiers.
- ArrayRef<ObjCProtocolDecl *> getProtocols() const {
- return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols());
- }
-
/// Whether this is a "__kindof" type as written.
bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; }
@@ -4916,11 +5012,16 @@ inline QualType *ObjCObjectType::getTypeArgStorage() {
return reinterpret_cast<QualType *>(static_cast<ObjCObjectTypeImpl*>(this)+1);
}
-inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() {
+inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorageImpl() {
return reinterpret_cast<ObjCProtocolDecl**>(
getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs);
}
+inline ObjCProtocolDecl **ObjCTypeParamType::getProtocolStorageImpl() {
+ return reinterpret_cast<ObjCProtocolDecl**>(
+ static_cast<ObjCTypeParamType*>(this)+1);
+}
+
/// Interfaces are the core concept in Objective-C for object oriented design.
/// They basically correspond to C++ classes. There are two kinds of interface
/// types: normal interfaces like `NSString`, and qualified interfaces, which
@@ -5189,17 +5290,17 @@ class AtomicType : public Type, public llvm::FoldingSetNode {
/// PipeType - OpenCL20.
class PipeType : public Type, public llvm::FoldingSetNode {
QualType ElementType;
+ bool isRead;
- PipeType(QualType elemType, QualType CanonicalPtr) :
+ PipeType(QualType elemType, QualType CanonicalPtr, bool isRead) :
Type(Pipe, CanonicalPtr, elemType->isDependentType(),
elemType->isInstantiationDependentType(),
elemType->isVariablyModifiedType(),
elemType->containsUnexpandedParameterPack()),
- ElementType(elemType) {}
+ ElementType(elemType), isRead(isRead) {}
friend class ASTContext; // ASTContext creates these.
public:
-
QualType getElementType() const { return ElementType; }
bool isSugared() const { return false; }
@@ -5207,18 +5308,19 @@ public:
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType());
+ Profile(ID, getElementType(), isReadOnly());
}
- static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType T, bool isRead) {
ID.AddPointer(T.getAsOpaquePtr());
+ ID.AddBoolean(isRead);
}
-
static bool classof(const Type *T) {
return T->getTypeClass() == Pipe;
}
+ bool isReadOnly() const { return isRead; }
};
/// A qualifier set is used to build a set of qualifiers.
@@ -5696,8 +5798,8 @@ inline bool Type::isNullPtrType() const {
return false;
}
-extern bool IsEnumDeclComplete(EnumDecl *);
-extern bool IsEnumDeclScoped(EnumDecl *);
+bool IsEnumDeclComplete(EnumDecl *);
+bool IsEnumDeclScoped(EnumDecl *);
inline bool Type::isIntegerType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
@@ -5807,17 +5909,15 @@ inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
// Helper class template that is used by Type::getAs to ensure that one does
// not try to look through a qualified type to get to an array type.
-template <typename T, bool isArrayType = (std::is_same<T, ArrayType>::value ||
- std::is_base_of<ArrayType, T>::value)>
-struct ArrayType_cannot_be_used_with_getAs {};
-
-template<typename T>
-struct ArrayType_cannot_be_used_with_getAs<T, true>;
+template <typename T>
+using TypeIsArrayType =
+ std::integral_constant<bool, std::is_same<T, ArrayType>::value ||
+ std::is_base_of<ArrayType, T>::value>;
// Member-template getAs<specific type>'.
template <typename T> const T *Type::getAs() const {
- ArrayType_cannot_be_used_with_getAs<T> at;
- (void)at;
+ static_assert(!TypeIsArrayType<T>::value,
+ "ArrayType cannot be used with getAs!");
// If this is directly a T type, return it.
if (const T *Ty = dyn_cast<T>(this))
@@ -5847,8 +5947,8 @@ inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
}
template <typename T> const T *Type::castAs() const {
- ArrayType_cannot_be_used_with_getAs<T> at;
- (void) at;
+ static_assert(!TypeIsArrayType<T>::value,
+ "ArrayType cannot be used with castAs!");
if (const T *ty = dyn_cast<T>(this)) return ty;
assert(isa<T>(CanonicalType));
@@ -5861,6 +5961,23 @@ inline const ArrayType *Type::castAsArrayTypeUnsafe() const {
return cast<ArrayType>(getUnqualifiedDesugaredType());
}
+DecayedType::DecayedType(QualType OriginalType, QualType DecayedPtr,
+ QualType CanonicalPtr)
+ : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) {
+#ifndef NDEBUG
+ QualType Adjusted = getAdjustedType();
+ (void)AttributedType::stripOuterNullability(Adjusted);
+ assert(isa<PointerType>(Adjusted));
+#endif
+}
+
+QualType DecayedType::getPointeeType() const {
+ QualType Decayed = getDecayedType();
+ (void)AttributedType::stripOuterNullability(Decayed);
+ return cast<PointerType>(Decayed)->getPointeeType();
+}
+
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 67adf4a638bc..7de666838d44 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -347,7 +347,7 @@ class ConcreteTypeLoc : public Base {
public:
unsigned getLocalDataAlignment() const {
- return std::max(llvm::alignOf<LocalData>(),
+ return std::max(unsigned(alignof(LocalData)),
asDerived()->getExtraLocalDataAlignment());
}
unsigned getLocalDataSize() const {
@@ -487,8 +487,10 @@ class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
Type,
TypeSpecLocInfo> {
public:
- enum { LocalDataSize = sizeof(TypeSpecLocInfo),
- LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment };
+ enum {
+ LocalDataSize = sizeof(TypeSpecLocInfo),
+ LocalDataAlignment = alignof(TypeSpecLocInfo)
+ };
SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc;
@@ -510,7 +512,7 @@ private:
struct BuiltinLocInfo {
- SourceLocation BuiltinLoc;
+ SourceRange BuiltinRange;
};
/// \brief Wrapper for source info for builtin types.
@@ -520,10 +522,19 @@ class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
BuiltinLocInfo> {
public:
SourceLocation getBuiltinLoc() const {
- return getLocalData()->BuiltinLoc;
+ return getLocalData()->BuiltinRange.getBegin();
}
void setBuiltinLoc(SourceLocation Loc) {
- getLocalData()->BuiltinLoc = Loc;
+ getLocalData()->BuiltinRange = Loc;
+ }
+ void expandBuiltinRange(SourceRange Range) {
+ SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
+ if (!BuiltinRange.getBegin().isValid()) {
+ BuiltinRange = Range;
+ } else {
+ BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin()));
+ BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd()));
+ }
}
SourceLocation getNameLoc() const { return getBuiltinLoc(); }
@@ -548,11 +559,11 @@ public:
}
unsigned getExtraLocalDataAlignment() const {
- return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>() : 1;
+ return needsExtraLocalData() ? alignof(WrittenBuiltinSpecs) : 1;
}
SourceRange getLocalSourceRange() const {
- return SourceRange(getBuiltinLoc(), getBuiltinLoc());
+ return getLocalData()->BuiltinRange;
}
TypeSpecifierSign getWrittenSignSpec() const {
@@ -693,6 +704,91 @@ public:
TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
};
+struct ObjCTypeParamTypeLocInfo {
+ SourceLocation NameLoc;
+};
+
+/// ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for
+/// protocol qualifiers are stored after Info.
+class ObjCTypeParamTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ ObjCTypeParamTypeLoc,
+ ObjCTypeParamType,
+ ObjCTypeParamTypeLocInfo> {
+ // SourceLocations are stored after Info, one for each protocol qualifier.
+ SourceLocation *getProtocolLocArray() const {
+ return (SourceLocation*)this->getExtraLocalData() + 2;
+ }
+
+public:
+ ObjCTypeParamDecl *getDecl() const { return getTypePtr()->getDecl(); }
+
+ SourceLocation getNameLoc() const {
+ return this->getLocalData()->NameLoc;
+ }
+
+ void setNameLoc(SourceLocation Loc) {
+ this->getLocalData()->NameLoc = Loc;
+ }
+
+ SourceLocation getProtocolLAngleLoc() const {
+ return getNumProtocols() ?
+ *((SourceLocation*)this->getExtraLocalData()) :
+ SourceLocation();
+ }
+ void setProtocolLAngleLoc(SourceLocation Loc) {
+ *((SourceLocation*)this->getExtraLocalData()) = Loc;
+ }
+
+ SourceLocation getProtocolRAngleLoc() const {
+ return getNumProtocols() ?
+ *((SourceLocation*)this->getExtraLocalData() + 1) :
+ SourceLocation();
+ }
+ void setProtocolRAngleLoc(SourceLocation Loc) {
+ *((SourceLocation*)this->getExtraLocalData() + 1) = Loc;
+ }
+
+ unsigned getNumProtocols() const {
+ return this->getTypePtr()->getNumProtocols();
+ }
+
+ SourceLocation getProtocolLoc(unsigned i) const {
+ assert(i < getNumProtocols() && "Index is out of bounds!");
+ return getProtocolLocArray()[i];
+ }
+ void setProtocolLoc(unsigned i, SourceLocation Loc) {
+ assert(i < getNumProtocols() && "Index is out of bounds!");
+ getProtocolLocArray()[i] = Loc;
+ }
+
+ ObjCProtocolDecl *getProtocol(unsigned i) const {
+ assert(i < getNumProtocols() && "Index is out of bounds!");
+ return *(this->getTypePtr()->qual_begin() + i);
+ }
+
+ ArrayRef<SourceLocation> getProtocolLocs() const {
+ return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
+ }
+
+ void initializeLocal(ASTContext &Context, SourceLocation Loc);
+
+ unsigned getExtraLocalDataSize() const {
+ if (!this->getNumProtocols()) return 0;
+ // When there are protocol qualifers, we have LAngleLoc and RAngleLoc
+ // as well.
+ return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ;
+ }
+ unsigned getExtraLocalDataAlignment() const {
+ return alignof(SourceLocation);
+ }
+ SourceRange getLocalSourceRange() const {
+ SourceLocation start = getNameLoc();
+ SourceLocation end = getProtocolRAngleLoc();
+ if (end.isInvalid()) return SourceRange(start, start);
+ return SourceRange(start, end);
+ }
+};
+
/// \brief Wrapper for substituted template type parameters.
class SubstTemplateTypeParmTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
@@ -960,10 +1056,9 @@ public:
}
unsigned getExtraLocalDataAlignment() const {
- assert(llvm::alignOf<ObjCObjectTypeLoc>()
- >= llvm::alignOf<TypeSourceInfo *>() &&
- "not enough alignment for tail-allocated data");
- return llvm::alignOf<TypeSourceInfo *>();
+ static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *),
+ "not enough alignment for tail-allocated data");
+ return alignof(TypeSourceInfo *);
}
QualType getInnerType() const {
@@ -1329,9 +1424,7 @@ public:
return getNumParams() * sizeof(ParmVarDecl *);
}
- unsigned getExtraLocalDataAlignment() const {
- return llvm::alignOf<ParmVarDecl*>();
- }
+ unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }
QualType getInnerType() const { return getTypePtr()->getReturnType(); }
};
@@ -1525,7 +1618,7 @@ public:
}
unsigned getExtraLocalDataAlignment() const {
- return llvm::alignOf<TemplateArgumentLocInfo>();
+ return alignof(TemplateArgumentLocInfo);
}
private:
@@ -1935,7 +2028,7 @@ public:
}
unsigned getExtraLocalDataAlignment() const {
- return llvm::alignOf<TemplateArgumentLocInfo>();
+ return alignof(TemplateArgumentLocInfo);
}
private:
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 8caf1024142d..27ab21bf7fcb 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -101,6 +101,7 @@ DEPENDENT_TYPE(InjectedClassName, Type)
DEPENDENT_TYPE(DependentName, Type)
DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(PackExpansion, Type)
+NON_CANONICAL_TYPE(ObjCTypeParam, Type)
TYPE(ObjCObject, Type)
TYPE(ObjCInterface, ObjCObjectType)
TYPE(ObjCObjectPointer, Type)
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index c1be2aa0f201..b63c6eb21769 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -17,7 +17,6 @@
#include "clang/AST/DeclAccessPair.h"
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
@@ -39,7 +38,9 @@ class UnresolvedSetIterator : public llvm::iterator_adaptor_base<
: iterator_adaptor_base(const_cast<DeclAccessPair *>(Iter)) {}
public:
- UnresolvedSetIterator() {}
+ // Work around a bug in MSVC 2013 where explicitly default constructed
+ // temporaries with defaulted ctors are not zero initialized.
+ UnresolvedSetIterator() : iterator_adaptor_base(nullptr) {}
NamedDecl *getDecl() const { return I->getDecl(); }
void setDecl(NamedDecl *ND) const { return I->setDecl(ND); }
diff --git a/include/clang/AST/VTTBuilder.h b/include/clang/AST/VTTBuilder.h
index 727bf5109ad4..b4a6fe3bdb94 100644
--- a/include/clang/AST/VTTBuilder.h
+++ b/include/clang/AST/VTTBuilder.h
@@ -20,7 +20,6 @@
#include "clang/AST/GlobalDecl.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/ABI.h"
-#include "llvm/ADT/SetVector.h"
#include <utility>
namespace clang {
diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h
index 481fd11d6afb..5cbcf51dd69b 100644
--- a/include/clang/AST/VTableBuilder.h
+++ b/include/clang/AST/VTableBuilder.h
@@ -20,7 +20,6 @@
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/ABI.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SetVector.h"
#include <memory>
#include <utility>
@@ -219,76 +218,76 @@ private:
class VTableLayout {
public:
typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
-
- typedef const VTableComponent *vtable_component_iterator;
- typedef const VTableThunkTy *vtable_thunk_iterator;
- typedef llvm::iterator_range<vtable_component_iterator>
- vtable_component_range;
-
- typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
+ struct AddressPointLocation {
+ unsigned VTableIndex, AddressPointIndex;
+ };
+ typedef llvm::DenseMap<BaseSubobject, AddressPointLocation>
+ AddressPointsMapTy;
private:
- uint64_t NumVTableComponents;
- std::unique_ptr<VTableComponent[]> VTableComponents;
+ // Stores the component indices of the first component of each virtual table in
+ // the virtual table group. To save a little memory in the common case where
+ // the vtable group contains a single vtable, an empty vector here represents
+ // the vector {0}.
+ OwningArrayRef<size_t> VTableIndices;
+
+ OwningArrayRef<VTableComponent> VTableComponents;
/// \brief Contains thunks needed by vtables, sorted by indices.
- uint64_t NumVTableThunks;
- std::unique_ptr<VTableThunkTy[]> VTableThunks;
+ OwningArrayRef<VTableThunkTy> VTableThunks;
/// \brief Address points for all vtables.
AddressPointsMapTy AddressPoints;
- bool IsMicrosoftABI;
-
public:
- VTableLayout(uint64_t NumVTableComponents,
- const VTableComponent *VTableComponents,
- uint64_t NumVTableThunks,
- const VTableThunkTy *VTableThunks,
- const AddressPointsMapTy &AddressPoints,
- bool IsMicrosoftABI);
+ VTableLayout(ArrayRef<size_t> VTableIndices,
+ ArrayRef<VTableComponent> VTableComponents,
+ ArrayRef<VTableThunkTy> VTableThunks,
+ const AddressPointsMapTy &AddressPoints);
~VTableLayout();
- uint64_t getNumVTableComponents() const {
- return NumVTableComponents;
+ ArrayRef<VTableComponent> vtable_components() const {
+ return VTableComponents;
}
- vtable_component_range vtable_components() const {
- return vtable_component_range(vtable_component_begin(),
- vtable_component_end());
+ ArrayRef<VTableThunkTy> vtable_thunks() const {
+ return VTableThunks;
}
- vtable_component_iterator vtable_component_begin() const {
- return VTableComponents.get();
+ AddressPointLocation getAddressPoint(BaseSubobject Base) const {
+ assert(AddressPoints.count(Base) && "Did not find address point!");
+ return AddressPoints.find(Base)->second;
}
- vtable_component_iterator vtable_component_end() const {
- return VTableComponents.get() + NumVTableComponents;
+ const AddressPointsMapTy &getAddressPoints() const {
+ return AddressPoints;
}
- uint64_t getNumVTableThunks() const { return NumVTableThunks; }
-
- vtable_thunk_iterator vtable_thunk_begin() const {
- return VTableThunks.get();
+ size_t getNumVTables() const {
+ if (VTableIndices.empty())
+ return 1;
+ return VTableIndices.size();
}
- vtable_thunk_iterator vtable_thunk_end() const {
- return VTableThunks.get() + NumVTableThunks;
+ size_t getVTableOffset(size_t i) const {
+ if (VTableIndices.empty()) {
+ assert(i == 0);
+ return 0;
+ }
+ return VTableIndices[i];
}
- uint64_t getAddressPoint(BaseSubobject Base) const {
- assert(AddressPoints.count(Base) &&
- "Did not find address point!");
-
- uint64_t AddressPoint = AddressPoints.lookup(Base);
- assert(AddressPoint != 0 || IsMicrosoftABI);
- (void)IsMicrosoftABI;
+ size_t getVTableSize(size_t i) const {
+ if (VTableIndices.empty()) {
+ assert(i == 0);
+ return vtable_components().size();
+ }
- return AddressPoint;
- }
-
- const AddressPointsMapTy &getAddressPoints() const {
- return AddressPoints;
+ size_t thisIndex = VTableIndices[i];
+ size_t nextIndex = (i + 1 == VTableIndices.size())
+ ? vtable_components().size()
+ : VTableIndices[i + 1];
+ return nextIndex - thisIndex;
}
};
@@ -339,8 +338,9 @@ private:
typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
MethodVTableIndicesTy MethodVTableIndices;
- typedef llvm::DenseMap<const CXXRecordDecl *, const VTableLayout *>
- VTableLayoutMapTy;
+ typedef llvm::DenseMap<const CXXRecordDecl *,
+ std::unique_ptr<const VTableLayout>>
+ VTableLayoutMapTy;
VTableLayoutMapTy VTableLayouts;
typedef std::pair<const CXXRecordDecl *,
@@ -367,11 +367,9 @@ public:
return *VTableLayouts[RD];
}
- VTableLayout *
- createConstructionVTableLayout(const CXXRecordDecl *MostDerivedClass,
- CharUnits MostDerivedClassOffset,
- bool MostDerivedClassIsVirtual,
- const CXXRecordDecl *LayoutClass);
+ std::unique_ptr<VTableLayout> createConstructionVTableLayout(
+ const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset,
+ bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass);
/// \brief Locate a virtual function in the vtable.
///
@@ -399,21 +397,21 @@ struct VPtrInfo {
typedef SmallVector<const CXXRecordDecl *, 1> BasePath;
VPtrInfo(const CXXRecordDecl *RD)
- : ReusingBase(RD), BaseWithVPtr(RD), NextBaseToMangle(RD) {}
+ : ObjectWithVPtr(RD), IntroducingObject(RD), NextBaseToMangle(RD) {}
+
+ /// This is the most derived class that has this vptr at offset zero. When
+ /// single inheritance is used, this is always the most derived class. If
+ /// multiple inheritance is used, it may be any direct or indirect base.
+ const CXXRecordDecl *ObjectWithVPtr;
- /// The vtable will hold all of the virtual bases or virtual methods of
- /// ReusingBase. This may or may not be the same class as VPtrSubobject.Base.
- /// A derived class will reuse the vptr of the first non-virtual base
- /// subobject that has one.
- const CXXRecordDecl *ReusingBase;
+ /// This is the class that introduced the vptr by declaring new virtual
+ /// methods or virtual bases.
+ const CXXRecordDecl *IntroducingObject;
- /// BaseWithVPtr is at this offset from its containing complete object or
+ /// IntroducingObject is at this offset from its containing complete object or
/// virtual base.
CharUnits NonVirtualOffset;
- /// The vptr is stored inside this subobject.
- const CXXRecordDecl *BaseWithVPtr;
-
/// The bases from the inheritance path that got used to mangle the vbtable
/// name. This is not really a full path like a CXXBasePath. It holds the
/// subset of records that need to be mangled into the vbtable symbol name in
@@ -432,7 +430,7 @@ struct VPtrInfo {
/// This holds the base classes path from the complete type to the first base
/// with the given vfptr offset, in the base-to-derived order. Only used for
/// vftables.
- BasePath PathToBaseWithVPtr;
+ BasePath PathToIntroducingObject;
/// Static offset from the top of the most derived class to this vfptr,
/// including any virtual base offset. Only used for vftables.
@@ -444,14 +442,12 @@ struct VPtrInfo {
}
};
-typedef SmallVector<VPtrInfo *, 2> VPtrInfoVector;
+typedef SmallVector<std::unique_ptr<VPtrInfo>, 2> VPtrInfoVector;
/// All virtual base related information about a given record decl. Includes
/// information on all virtual base tables and the path components that are used
/// to mangle them.
struct VirtualBaseInfo {
- ~VirtualBaseInfo() { llvm::DeleteContainerPointers(VBPtrPaths); }
-
/// A map from virtual base to vbtable index for doing a conversion from the
/// the derived class to the a base.
llvm::DenseMap<const CXXRecordDecl *, unsigned> VBTableIndices;
@@ -504,15 +500,17 @@ private:
MethodVFTableLocationsTy;
MethodVFTableLocationsTy MethodVFTableLocations;
- typedef llvm::DenseMap<const CXXRecordDecl *, VPtrInfoVector *>
- VFPtrLocationsMapTy;
+ typedef llvm::DenseMap<const CXXRecordDecl *, VPtrInfoVector>
+ VFPtrLocationsMapTy;
VFPtrLocationsMapTy VFPtrLocations;
typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
- typedef llvm::DenseMap<VFTableIdTy, const VTableLayout *> VFTableLayoutMapTy;
+ typedef llvm::DenseMap<VFTableIdTy, std::unique_ptr<const VTableLayout>>
+ VFTableLayoutMapTy;
VFTableLayoutMapTy VFTableLayouts;
- llvm::DenseMap<const CXXRecordDecl *, VirtualBaseInfo *> VBaseInfo;
+ llvm::DenseMap<const CXXRecordDecl *, std::unique_ptr<VirtualBaseInfo>>
+ VBaseInfo;
void enumerateVFPtrs(const CXXRecordDecl *ForClass, VPtrInfoVector &Result);
@@ -522,7 +520,7 @@ private:
const MethodVFTableLocationsTy &NewMethods,
raw_ostream &);
- const VirtualBaseInfo *
+ const VirtualBaseInfo &
computeVBTableRelatedInformation(const CXXRecordDecl *RD);
void computeVTablePaths(bool ForVBTables, const CXXRecordDecl *RD,
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
index 042408859c9d..389af1b6e259 100644
--- a/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -158,6 +158,8 @@ public:
MatchCallback *Action);
void addMatcher(const TypeLocMatcher &NodeMatch,
MatchCallback *Action);
+ void addMatcher(const CXXCtorInitializerMatcher &NodeMatch,
+ MatchCallback *Action);
/// @}
/// \brief Adds a matcher to execute when running over the AST.
@@ -208,6 +210,7 @@ public:
std::vector<std::pair<NestedNameSpecifierLocMatcher, MatchCallback *>>
NestedNameSpecifierLoc;
std::vector<std::pair<TypeLocMatcher, MatchCallback *>> TypeLoc;
+ std::vector<std::pair<CXXCtorInitializerMatcher, MatchCallback *>> CtorInit;
/// \brief All the callbacks in one container to simplify iteration.
llvm::SmallPtrSet<MatchCallback *, 16> AllCallbacks;
};
@@ -229,6 +232,10 @@ private:
/// Multiple results occur when using matchers like \c forEachDescendant,
/// which generate a result for each sub-match.
///
+/// If you want to find all matches on the sub-tree rooted at \c Node (rather
+/// than only the matches on \c Node itself), surround the \c Matcher with a
+/// \c findAll().
+///
/// \see selectFirst
/// @{
template <typename MatcherT, typename NodeT>
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index aef4b4eafd9a..6a5224febab5 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -51,7 +51,6 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/Support/Regex.h"
#include <iterator>
@@ -76,18 +75,6 @@ public:
return MyBoundNodes.getNodeAs<T>(ID);
}
- /// \brief Deprecated. Please use \c getNodeAs instead.
- /// @{
- template <typename T>
- const T *getDeclAs(StringRef ID) const {
- return getNodeAs<T>(ID);
- }
- template <typename T>
- const T *getStmtAs(StringRef ID) const {
- return getNodeAs<T>(ID);
- }
- /// @}
-
/// \brief Type of mapping from binding identifiers to bound nodes. This type
/// is an associative container with a key type of \c std::string and a value
/// type of \c clang::ast_type_traits::DynTypedNode
@@ -126,6 +113,7 @@ typedef internal::Matcher<QualType> TypeMatcher;
typedef internal::Matcher<TypeLoc> TypeLocMatcher;
typedef internal::Matcher<NestedNameSpecifier> NestedNameSpecifierMatcher;
typedef internal::Matcher<NestedNameSpecifierLoc> NestedNameSpecifierLocMatcher;
+typedef internal::Matcher<CXXCtorInitializer> CXXCtorInitializerMatcher;
/// @}
/// \brief Matches any node.
@@ -447,6 +435,17 @@ const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;
/// matches 'int' in C<int>.
const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
+/// \brief Matches template name.
+///
+/// Given
+/// \code
+/// template <typename T> class X { };
+/// X<int> xi;
+/// \endcode
+/// templateName()
+/// matches 'X' in X<int>.
+const internal::VariadicAllOfMatcher<TemplateName> templateName;
+
/// \brief Matches non-type template parameter declarations.
///
/// Given
@@ -534,7 +533,8 @@ AST_MATCHER(FieldDecl, isBitField) {
return Node.isBitField();
}
-/// \brief Matches non-static data members that are bit-fields.
+/// \brief Matches non-static data members that are bit-fields of the specified
+/// bit width.
///
/// Given
/// \code
@@ -544,35 +544,66 @@ AST_MATCHER(FieldDecl, isBitField) {
/// int c : 2;
/// };
/// \endcode
-/// fieldDecl(isBitField())
+/// fieldDecl(hasBitWidth(2))
/// matches 'int a;' and 'int c;' but not 'int b;'.
AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) {
return Node.isBitField() &&
Node.getBitWidthValue(Finder->getASTContext()) == Width;
}
+/// \brief Matches non-static data members that have an in-class initializer.
+///
+/// Given
+/// \code
+/// class C {
+/// int a = 2;
+/// int b = 3;
+/// int c;
+/// };
+/// \endcode
+/// fieldDecl(hasInClassInitializer(integerLiteral(equals(2))))
+/// matches 'int a;' but not 'int b;'.
+/// fieldDecl(hasInClassInitializer(anything()))
+/// matches 'int a;' and 'int b;' but not 'int c;'.
+AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher<Expr>,
+ InnerMatcher) {
+ const Expr *Initializer = Node.getInClassInitializer();
+ return (Initializer != nullptr &&
+ InnerMatcher.matches(*Initializer, Finder, Builder));
+}
+
/// \brief Matches a declaration that has been implicitly added
/// by the compiler (eg. implicit default/copy constructors).
AST_MATCHER(Decl, isImplicit) {
return Node.isImplicit();
}
-/// \brief Matches classTemplateSpecializations that have at least one
-/// TemplateArgument matching the given InnerMatcher.
+/// \brief Matches classTemplateSpecializations, templateSpecializationType and
+/// functionDecl that have at least one TemplateArgument matching the given
+/// InnerMatcher.
///
/// Given
/// \code
/// template<typename T> class A {};
/// template<> class A<double> {};
/// A<int> a;
+///
+/// template<typename T> f() {};
+/// void func() { f<int>(); };
+/// \endcode
+///
/// \endcode
/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
/// refersToType(asString("int"))))
/// matches the specialization \c A<int>
+///
+/// functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
+/// matches the specialization \c f<int>
AST_POLYMORPHIC_MATCHER_P(
hasAnyTemplateArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
- TemplateSpecializationType),
+ TemplateSpecializationType,
+ FunctionDecl),
internal::Matcher<TemplateArgument>, InnerMatcher) {
ArrayRef<TemplateArgument> List =
internal::getTemplateSpecializationArgs(Node);
@@ -699,22 +730,29 @@ AST_MATCHER_P(QualType, ignoringParens,
return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
}
-/// \brief Matches classTemplateSpecializations where the n'th TemplateArgument
-/// matches the given InnerMatcher.
+/// \brief Matches classTemplateSpecializations, templateSpecializationType and
+/// functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
///
/// Given
/// \code
/// template<typename T, typename U> class A {};
/// A<bool, int> b;
/// A<int, bool> c;
+///
+/// template<typename T> f() {};
+/// void func() { f<int>(); };
/// \endcode
/// classTemplateSpecializationDecl(hasTemplateArgument(
/// 1, refersToType(asString("int"))))
/// matches the specialization \c A<bool, int>
+///
+/// functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
+/// matches the specialization \c f<int>
AST_POLYMORPHIC_MATCHER_P2(
hasTemplateArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
- TemplateSpecializationType),
+ TemplateSpecializationType,
+ FunctionDecl),
unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
ArrayRef<TemplateArgument> List =
internal::getTemplateSpecializationArgs(Node);
@@ -758,6 +796,24 @@ AST_MATCHER_P(TemplateArgument, refersToType,
return InnerMatcher.matches(Node.getAsType(), Finder, Builder);
}
+/// \brief Matches a TemplateArgument that refers to a certain template.
+///
+/// Given
+/// \code
+/// template<template <typename> class S> class X {};
+/// template<typename T> class Y {};"
+/// X<Y> xi;
+/// \endcode
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
+/// refersToTemplate(templateName())))
+/// matches the specialization \c X<Y>
+AST_MATCHER_P(TemplateArgument, refersToTemplate,
+ internal::Matcher<TemplateName>, InnerMatcher) {
+ if (Node.getKind() != TemplateArgument::Template)
+ return false;
+ return InnerMatcher.matches(Node.getAsTemplate(), Finder, Builder);
+}
+
/// \brief Matches a canonical TemplateArgument that refers to a certain
/// declaration.
///
@@ -1863,7 +1919,7 @@ const internal::VariadicDynCastAllOfMatcher<
/// \brief Matches a C-style cast expression.
///
-/// Example: Matches (int*) 2.2f in
+/// Example: Matches (int) 2.2f in
/// \code
/// int i = (int) 2.2f;
/// \endcode
@@ -2404,16 +2460,18 @@ const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
/// - for CallExpr, the declaration of the callee
/// - for MemberExpr, the declaration of the referenced member
/// - for CXXConstructExpr, the declaration of the constructor
+/// - for CXXNewExpr, the declaration of the operator new
///
/// Also usable as Matcher<T> for any T supporting the getDecl() member
/// function. e.g. various subtypes of clang::Type and various expressions.
///
-/// Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
-/// Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
-/// Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
-/// Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
-/// Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
-/// Matcher<TypedefType>, Matcher<UnresolvedUsingType>
+/// Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>,
+/// Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>,
+/// Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<LabelStmt>,
+/// Matcher<MemberExpr>, Matcher<QualType>, Matcher<RecordType>,
+/// Matcher<TagType>, Matcher<TemplateSpecializationType>,
+/// Matcher<TemplateTypeParmType>, Matcher<TypedefType>,
+/// Matcher<UnresolvedUsingType>
inline internal::PolymorphicMatcherWithParam1<
internal::HasDeclarationMatcher, internal::Matcher<Decl>,
void(internal::HasDeclarationSupportedTypes)>
@@ -2423,6 +2481,25 @@ hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
void(internal::HasDeclarationSupportedTypes)>(InnerMatcher);
}
+/// \brief Matches a \c NamedDecl whose underlying declaration matches the given
+/// matcher.
+///
+/// Given
+/// \code
+/// namespace N { template<class T> void f(T t); }
+/// template <class T> void g() { using N::f; f(T()); }
+/// \endcode
+/// \c unresolvedLookupExpr(hasAnyDeclaration(
+/// namedDecl(hasUnderlyingDecl(hasName("::N::f")))))
+/// matches the use of \c f in \c g() .
+AST_MATCHER_P(NamedDecl, hasUnderlyingDecl, internal::Matcher<NamedDecl>,
+ InnerMatcher) {
+ const NamedDecl *UnderlyingDecl = Node.getUnderlyingDecl();
+
+ return UnderlyingDecl != nullptr &&
+ InnerMatcher.matches(*UnderlyingDecl, Finder, Builder);
+}
+
/// \brief Matches on the implicit object argument of a member call expression.
///
/// Example matches y.x()
@@ -2671,6 +2748,22 @@ AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>,
.matches(Node, Finder, Builder);
}
+/// \brief Matches if the matched type matches the unqualified desugared
+/// type of the matched node.
+///
+/// For example, in:
+/// \code
+/// class A {};
+/// using B = A;
+/// \endcode
+/// The matcher type(hasUniqualifeidDesugaredType(recordType())) matches
+/// both B and A.
+AST_MATCHER_P(Type, hasUnqualifiedDesugaredType, internal::Matcher<Type>,
+ InnerMatcher) {
+ return InnerMatcher.matches(*Node.getUnqualifiedDesugaredType(), Finder,
+ Builder);
+}
+
/// \brief Matches if the matched type is a reference type and the referenced
/// type matches the specified matcher.
///
@@ -2778,6 +2871,27 @@ AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
return false;
}
+/// \brief Matches an \c OverloadExpr if any of the declarations in the set of
+/// overloads matches the given matcher.
+///
+/// Given
+/// \code
+/// template <typename T> void foo(T);
+/// template <typename T> void bar(T);
+/// template <typename T> void baz(T t) {
+/// foo(t);
+/// bar(t);
+/// }
+/// \endcode
+/// unresolvedLookupExpr(hasAnyDeclaration(
+/// functionTemplateDecl(hasName("foo"))))
+/// matches \c foo in \c foo(t); but not \c bar in \c bar(t);
+AST_MATCHER_P(OverloadExpr, hasAnyDeclaration, internal::Matcher<Decl>,
+ InnerMatcher) {
+ return matchesFirstInPointerRange(InnerMatcher, Node.decls_begin(),
+ Node.decls_end(), Finder, Builder);
+}
+
/// \brief Matches the Decl of a DeclStmt which has a single declaration.
///
/// Given
@@ -2857,9 +2971,9 @@ AST_MATCHER(VarDecl, hasAutomaticStorageDuration) {
}
/// \brief Matches a variable declaration that has static storage duration.
+/// It includes the variable declared at namespace scope and those declared
+/// with "static" and "extern" storage class specifiers.
///
-/// Example matches y and a, but not x or z.
-/// (matcher = varDecl(hasStaticStorageDuration())
/// \code
/// void f() {
/// int x;
@@ -2867,6 +2981,10 @@ AST_MATCHER(VarDecl, hasAutomaticStorageDuration) {
/// thread_local int z;
/// }
/// int a;
+/// static int b;
+/// extern int c;
+/// varDecl(hasStaticStorageDuration())
+/// matches the function declaration y, a, b and c.
/// \endcode
AST_MATCHER(VarDecl, hasStaticStorageDuration) {
return Node.getStorageDuration() == SD_Static;
@@ -3297,10 +3415,31 @@ AST_MATCHER_P(FunctionDecl, returns,
/// \endcode
/// functionDecl(isExternC())
/// matches the declaration of f and g, but not the declaration h
-AST_MATCHER(FunctionDecl, isExternC) {
+AST_POLYMORPHIC_MATCHER(isExternC, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+ VarDecl)) {
return Node.isExternC();
}
+/// \brief Matches variable/function declarations that have "static" storage
+/// class specifier ("static" keyword) written in the source.
+///
+/// Given:
+/// \code
+/// static void f() {}
+/// static int i = 0;
+/// extern int j;
+/// int k;
+/// \endcode
+/// functionDecl(isStaticStorageClass())
+/// matches the function declaration f.
+/// varDecl(isStaticStorageClass())
+/// matches the variable declaration i.
+AST_POLYMORPHIC_MATCHER(isStaticStorageClass,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+ VarDecl)) {
+ return Node.getStorageClass() == SC_Static;
+}
+
/// \brief Matches deleted function declarations.
///
/// Given:
@@ -4075,7 +4214,7 @@ AST_MATCHER(QualType, isInteger) {
/// void b(unsigned long);
/// void c(double);
/// \endcode
-/// functionDecl(hasAnyParameter(hasType(isInteger())))
+/// functionDecl(hasAnyParameter(hasType(isUnsignedInteger())))
/// matches "b(unsigned long)", but not "a(int)" and "c(double)".
AST_MATCHER(QualType, isUnsignedInteger) {
return Node->isUnsignedIntegerType();
@@ -4089,7 +4228,7 @@ AST_MATCHER(QualType, isUnsignedInteger) {
/// void b(unsigned long);
/// void c(double);
/// \endcode
-/// functionDecl(hasAnyParameter(hasType(isInteger())))
+/// functionDecl(hasAnyParameter(hasType(isSignedInteger())))
/// matches "a(int)", but not "b(unsigned long)" and "c(double)".
AST_MATCHER(QualType, isSignedInteger) {
return Node->isSignedIntegerType();
@@ -4890,6 +5029,22 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
/// \c substTemplateTypeParmType() matches the type of 't' but not '1'
AST_TYPE_MATCHER(SubstTemplateTypeParmType, substTemplateTypeParmType);
+/// \brief Matches template type parameter substitutions that have a replacement
+/// type that matches the provided matcher.
+///
+/// Given
+/// \code
+/// template <typename T>
+/// double F(T t);
+/// int i;
+/// double j = F(i);
+/// \endcode
+///
+/// \c substTemplateTypeParmType(hasReplacementType(type())) matches int
+AST_TYPE_TRAVERSE_MATCHER(
+ hasReplacementType, getReplacementType,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(SubstTemplateTypeParmType));
+
/// \brief Matches template type parameter types.
///
/// Example matches T, but not int.
@@ -5390,6 +5545,30 @@ AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>,
return false;
}
+/// \brief Matches a declaration that has external formal linkage.
+///
+/// Example matches only z (matcher = varDecl(hasExternalFormalLinkage()))
+/// \code
+/// void f() {
+/// int x;
+/// static int y;
+/// }
+/// int z;
+/// \endcode
+///
+/// Example matches f() because it has external formal linkage despite being
+/// unique to the translation unit as though it has internal likage
+/// (matcher = functionDecl(hasExternalFormalLinkage()))
+///
+/// \code
+/// namespace {
+/// void f() {}
+/// }
+/// \endcode
+AST_MATCHER(NamedDecl, hasExternalFormalLinkage) {
+ return Node.hasExternalFormalLinkage();
+}
+
} // end namespace ast_matchers
} // end namespace clang
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index c2c01fbd78ea..bc75e807ced9 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -787,6 +787,14 @@ private:
return matchesDecl(Node.getConstructor(), Finder, Builder);
}
+ /// \brief Extracts the operator new of the new call and returns whether the
+ /// inner matcher matches on it.
+ bool matchesSpecialized(const CXXNewExpr &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ return matchesDecl(Node.getOperatorNew(), Finder, Builder);
+ }
+
/// \brief Extracts the \c ValueDecl a \c MemberExpr refers to and returns
/// whether the inner matcher matches on it.
bool matchesSpecialized(const MemberExpr &Node,
@@ -1007,11 +1015,11 @@ typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
TypeLoc, QualType> AdaptativeDefaultToTypes;
/// \brief All types that are supported by HasDeclarationMatcher above.
-typedef TypeList<CallExpr, CXXConstructExpr, DeclRefExpr, EnumType,
+typedef TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
InjectedClassNameType, LabelStmt, AddrLabelExpr, MemberExpr,
QualType, RecordType, TagType, TemplateSpecializationType,
- TemplateTypeParmType, TypedefType,
- UnresolvedUsingType> HasDeclarationSupportedTypes;
+ TemplateTypeParmType, TypedefType, UnresolvedUsingType>
+ HasDeclarationSupportedTypes;
/// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by
/// "adapting" a \c To into a \c T.
@@ -1413,18 +1421,18 @@ private:
template <>
inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
const FloatingLiteral &Node) const {
- if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle)
+ if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
return Node.getValue().convertToFloat() == ExpectedValue;
- if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble)
+ if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
return Node.getValue().convertToDouble() == ExpectedValue;
return false;
}
template <>
inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
const FloatingLiteral &Node) const {
- if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle)
+ if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
return Node.getValue().convertToFloat() == ExpectedValue;
- if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble)
+ if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
return Node.getValue().convertToDouble() == ExpectedValue;
return false;
}
@@ -1638,6 +1646,13 @@ getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
return llvm::makeArrayRef(T.getArgs(), T.getNumArgs());
}
+inline ArrayRef<TemplateArgument>
+getTemplateSpecializationArgs(const FunctionDecl &FD) {
+ if (const auto* TemplateArgs = FD.getTemplateSpecializationArgs())
+ return TemplateArgs->asArray();
+ return ArrayRef<TemplateArgument>();
+}
+
struct NotEqualsBoundNodePredicate {
bool operator()(const internal::BoundNodesMap &Nodes) const {
return Nodes.getNode(ID) != Node;
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h
index 8ad0c16ef83a..ddc48378e714 100644
--- a/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ b/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -97,7 +97,7 @@
class matcher_##DefineMatcher##Matcher \
: public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
public: \
- explicit matcher_##DefineMatcher##Matcher() {} \
+ explicit matcher_##DefineMatcher##Matcher() = default; \
bool matches(const Type &Node, \
::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
::clang::ast_matchers::internal::BoundNodesTreeBuilder \
@@ -401,4 +401,4 @@
ReturnTypesF>::Func MatcherName##Loc; \
AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
-#endif
+#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
index 3808adb11e7f..7bba95dbffea 100644
--- a/include/clang/ASTMatchers/Dynamic/Registry.h
+++ b/include/clang/ASTMatchers/Dynamic/Registry.h
@@ -1,4 +1,4 @@
-//===--- Registry.h - Matcher registry -----*- C++ -*-===//
+//===--- Registry.h - Matcher registry --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,28 +19,36 @@
#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
-#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <utility>
+#include <vector>
namespace clang {
namespace ast_matchers {
namespace dynamic {
namespace internal {
+
class MatcherDescriptor;
-}
+
+} // end namespace internal
typedef const internal::MatcherDescriptor *MatcherCtor;
struct MatcherCompletion {
- MatcherCompletion() {}
+ MatcherCompletion() = default;
MatcherCompletion(StringRef TypedText, StringRef MatcherDecl,
unsigned Specificity)
: TypedText(TypedText), MatcherDecl(MatcherDecl),
Specificity(Specificity) {}
+ bool operator==(const MatcherCompletion &Other) const {
+ return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
+ }
+
/// \brief The text to type to select this matcher.
std::string TypedText;
@@ -53,14 +61,12 @@ struct MatcherCompletion {
/// matcher that will either always or never match.
/// Such matchers are excluded from code completion results.
unsigned Specificity;
-
- bool operator==(const MatcherCompletion &Other) const {
- return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
- }
};
class Registry {
public:
+ Registry() = delete;
+
/// \brief Look up a matcher in the registry by name,
///
/// \return An opaque value which may be used to refer to the matcher
@@ -121,13 +127,10 @@ public:
StringRef BindID,
ArrayRef<ParserValue> Args,
Diagnostics *Error);
-
-private:
- Registry() = delete;
};
-} // namespace dynamic
-} // namespace ast_matchers
-} // namespace clang
+} // end namespace dynamic
+} // end namespace ast_matchers
+} // end namespace clang
-#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
+#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h
index c391b24a3330..9f694d0ce434 100644
--- a/include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -21,7 +21,6 @@
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/Twine.h"
#include <memory>
#include <vector>
@@ -120,9 +119,9 @@ class VariantMatcher {
/// \brief Payload interface to be specialized by each matcher type.
///
/// It follows a similar interface as VariantMatcher itself.
- class Payload : public RefCountedBaseVPTR {
+ class Payload : public RefCountedBase<Payload> {
public:
- ~Payload() override;
+ virtual ~Payload();
virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
virtual std::string getTypeAsString() const = 0;
virtual llvm::Optional<DynTypedMatcher>
diff --git a/include/clang/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h
index 1f5aa12111c1..c0fc02724f09 100644
--- a/include/clang/Analysis/Analyses/Consumed.h
+++ b/include/clang/Analysis/Analyses/Consumed.h
@@ -201,11 +201,6 @@ namespace consumed {
public:
ConsumedBlockInfo() = default;
- ConsumedBlockInfo &operator=(ConsumedBlockInfo &&Other) {
- StateMapsArray = std::move(Other.StateMapsArray);
- VisitOrder = std::move(Other.VisitOrder);
- return *this;
- }
ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph)
: StateMapsArray(NumBlocks), VisitOrder(NumBlocks, 0) {
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
index c64a3ca2551d..1229f8a8efac 100644
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -167,43 +167,37 @@ private:
///
namespace llvm {
template <> struct GraphTraits< ::clang::DomTreeNode* > {
- typedef ::clang::DomTreeNode NodeType;
typedef ::clang::DomTreeNode *NodeRef;
- typedef NodeType::iterator ChildIteratorType;
+ typedef ::clang::DomTreeNode::iterator ChildIteratorType;
- static NodeType *getEntryNode(NodeType *N) {
- return N;
- }
- static inline ChildIteratorType child_begin(NodeType *N) {
- return N->begin();
- }
- static inline ChildIteratorType child_end(NodeType *N) {
- return N->end();
- }
+ static NodeRef getEntryNode(NodeRef N) { return N; }
+ static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
+ static ChildIteratorType child_end(NodeRef N) { return N->end(); }
- typedef df_iterator< ::clang::DomTreeNode* > nodes_iterator;
+ typedef llvm::pointer_iterator<df_iterator<::clang::DomTreeNode *>>
+ nodes_iterator;
static nodes_iterator nodes_begin(::clang::DomTreeNode *N) {
- return df_begin(getEntryNode(N));
+ return nodes_iterator(df_begin(getEntryNode(N)));
}
static nodes_iterator nodes_end(::clang::DomTreeNode *N) {
- return df_end(getEntryNode(N));
+ return nodes_iterator(df_end(getEntryNode(N)));
}
};
template <> struct GraphTraits< ::clang::DominatorTree* >
: public GraphTraits< ::clang::DomTreeNode* > {
- static NodeType *getEntryNode(::clang::DominatorTree *DT) {
+ static NodeRef getEntryNode(::clang::DominatorTree *DT) {
return DT->getRootNode();
}
static nodes_iterator nodes_begin(::clang::DominatorTree *N) {
- return df_begin(getEntryNode(N));
+ return nodes_iterator(df_begin(getEntryNode(N)));
}
static nodes_iterator nodes_end(::clang::DominatorTree *N) {
- return df_end(getEntryNode(N));
+ return nodes_iterator(df_end(getEntryNode(N)));
}
};
} // end namespace llvm
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
index 74803a295d71..8c531d638cc2 100644
--- a/include/clang/Analysis/Analyses/FormatString.h
+++ b/include/clang/Analysis/Analyses/FormatString.h
@@ -35,7 +35,7 @@ class OptionalFlag {
public:
OptionalFlag(const char *Representation)
: representation(Representation), flag(false) {}
- bool isSet() { return flag; }
+ bool isSet() const { return flag; }
void set() { flag = true; }
void clear() { flag = false; }
void setPosition(const char *position) {
@@ -122,12 +122,13 @@ class ConversionSpecifier {
public:
enum Kind {
InvalidSpecifier = 0,
- // C99 conversion specifiers.
+ // C99 conversion specifiers.
cArg,
dArg,
DArg, // Apple extension
iArg,
- IntArgBeg = dArg, IntArgEnd = iArg,
+ IntArgBeg = dArg,
+ IntArgEnd = iArg,
oArg,
OArg, // Apple extension
@@ -135,7 +136,8 @@ public:
UArg, // Apple extension
xArg,
XArg,
- UIntArgBeg = oArg, UIntArgEnd = XArg,
+ UIntArgBeg = oArg,
+ UIntArgEnd = XArg,
fArg,
FArg,
@@ -145,7 +147,8 @@ public:
GArg,
aArg,
AArg,
- DoubleArgBeg = fArg, DoubleArgEnd = AArg,
+ DoubleArgBeg = fArg,
+ DoubleArgEnd = AArg,
sArg,
pArg,
@@ -154,13 +157,19 @@ public:
CArg,
SArg,
+ // Apple extension: P specifies to os_log that the data being pointed to is
+ // to be copied by os_log. The precision indicates the number of bytes to
+ // copy.
+ PArg,
+
// ** Printf-specific **
ZArg, // MS extension
// Objective-C specific specifiers.
- ObjCObjArg, // '@'
- ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg,
+ ObjCObjArg, // '@'
+ ObjCBeg = ObjCObjArg,
+ ObjCEnd = ObjCObjArg,
// FreeBSD kernel specific specifiers.
FreeBSDbArg,
@@ -169,13 +178,15 @@ public:
FreeBSDyArg,
// GlibC specific specifiers.
- PrintErrno, // 'm'
+ PrintErrno, // 'm'
- PrintfConvBeg = ObjCObjArg, PrintfConvEnd = PrintErrno,
+ PrintfConvBeg = ObjCObjArg,
+ PrintfConvEnd = PrintErrno,
// ** Scanf-specific **
ScanListArg, // '['
- ScanfConvBeg = ScanListArg, ScanfConvEnd = ScanListArg
+ ScanfConvBeg = ScanListArg,
+ ScanfConvEnd = ScanListArg
};
ConversionSpecifier(bool isPrintf = true)
@@ -200,6 +211,8 @@ public:
return false;
case PercentArg:
return false;
+ case InvalidSpecifier:
+ return false;
default:
return true;
}
@@ -437,13 +450,15 @@ class PrintfSpecifier : public analyze_format_string::FormatSpecifier {
OptionalFlag HasAlternativeForm; // '#'
OptionalFlag HasLeadingZeroes; // '0'
OptionalFlag HasObjCTechnicalTerm; // '[tt]'
+ OptionalFlag IsPrivate; // '{private}'
+ OptionalFlag IsPublic; // '{public}'
OptionalAmount Precision;
public:
- PrintfSpecifier() :
- FormatSpecifier(/* isPrintf = */ true),
- HasThousandsGrouping("'"), IsLeftJustified("-"), HasPlusPrefix("+"),
- HasSpacePrefix(" "), HasAlternativeForm("#"), HasLeadingZeroes("0"),
- HasObjCTechnicalTerm("tt") {}
+ PrintfSpecifier()
+ : FormatSpecifier(/* isPrintf = */ true), HasThousandsGrouping("'"),
+ IsLeftJustified("-"), HasPlusPrefix("+"), HasSpacePrefix(" "),
+ HasAlternativeForm("#"), HasLeadingZeroes("0"),
+ HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public") {}
static PrintfSpecifier Parse(const char *beg, const char *end);
@@ -472,6 +487,8 @@ public:
void setHasObjCTechnicalTerm(const char *position) {
HasObjCTechnicalTerm.setPosition(position);
}
+ void setIsPrivate(const char *position) { IsPrivate.setPosition(position); }
+ void setIsPublic(const char *position) { IsPublic.setPosition(position); }
void setUsesPositionalArg() { UsesPositionalArg = true; }
// Methods for querying the format specifier.
@@ -509,6 +526,8 @@ public:
const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; }
const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; }
const OptionalFlag &hasObjCTechnicalTerm() const { return HasObjCTechnicalTerm; }
+ const OptionalFlag &isPrivate() const { return IsPrivate; }
+ const OptionalFlag &isPublic() const { return IsPublic; }
bool usesPositionalArg() const { return UsesPositionalArg; }
/// Changes the specifier and length according to a QualType, retaining any
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index e17f73a61f81..8db4b0a58f86 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -16,7 +16,6 @@
#include "clang/AST/Decl.h"
#include "clang/Analysis/AnalysisContext.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ImmutableSet.h"
namespace clang {
diff --git a/include/clang/Analysis/Analyses/OSLog.h b/include/clang/Analysis/Analyses/OSLog.h
new file mode 100644
index 000000000000..1e60a237b770
--- /dev/null
+++ b/include/clang/Analysis/Analyses/OSLog.h
@@ -0,0 +1,155 @@
+//= OSLog.h - Analysis of calls to os_log builtins --*- C++ -*-===============//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines APIs for determining the layout of the data buffer for
+// os_log() and os_trace().
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+
+namespace clang {
+namespace analyze_os_log {
+
+/// An OSLogBufferItem represents a single item in the data written by a call
+/// to os_log() or os_trace().
+class OSLogBufferItem {
+public:
+ enum Kind {
+ // The item is a scalar (int, float, raw pointer, etc.). No further copying
+ // is required. This is the only kind allowed by os_trace().
+ ScalarKind = 0,
+
+ // The item is a count, which describes the length of the following item to
+ // be copied. A count may only be followed by an item of kind StringKind,
+ // WideStringKind, or PointerKind.
+ CountKind,
+
+ // The item is a pointer to a C string. If preceded by a count 'n',
+ // os_log() will copy at most 'n' bytes from the pointer.
+ StringKind,
+
+ // The item is a pointer to a block of raw data. This item must be preceded
+ // by a count 'n'. os_log() will copy exactly 'n' bytes from the pointer.
+ PointerKind,
+
+ // The item is a pointer to an Objective-C object. os_log() may retain the
+ // object for later processing.
+ ObjCObjKind,
+
+ // The item is a pointer to wide-char string.
+ WideStringKind,
+
+ // The item is corresponding to the '%m' format specifier, no value is
+ // populated in the buffer and the runtime is loading the errno value.
+ ErrnoKind
+ };
+
+ enum {
+ // The item is marked "private" in the format string.
+ IsPrivate = 0x1,
+
+ // The item is marked "public" in the format string.
+ IsPublic = 0x2
+ };
+
+private:
+ Kind TheKind = ScalarKind;
+ const Expr *TheExpr = nullptr;
+ CharUnits ConstValue;
+ CharUnits Size; // size of the data, not including the header bytes
+ unsigned Flags = 0;
+
+public:
+ OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags)
+ : TheKind(kind), TheExpr(expr), Size(size), Flags(flags) {}
+
+ OSLogBufferItem(ASTContext &Ctx, CharUnits value, unsigned flags)
+ : TheKind(CountKind), ConstValue(value),
+ Size(Ctx.getTypeSizeInChars(Ctx.IntTy)), Flags(flags) {}
+
+ unsigned char getDescriptorByte() const {
+ unsigned char result = 0;
+ if (getIsPrivate())
+ result |= IsPrivate;
+ if (getIsPublic())
+ result |= IsPublic;
+ result |= ((unsigned)getKind()) << 4;
+ return result;
+ }
+
+ unsigned char getSizeByte() const { return size().getQuantity(); }
+
+ Kind getKind() const { return TheKind; }
+ bool getIsPrivate() const { return (Flags & IsPrivate) != 0; }
+ bool getIsPublic() const { return (Flags & IsPublic) != 0; }
+
+ const Expr *getExpr() const { return TheExpr; }
+ CharUnits getConstValue() const { return ConstValue; }
+ CharUnits size() const { return Size; }
+};
+
+class OSLogBufferLayout {
+public:
+ SmallVector<OSLogBufferItem, 4> Items;
+
+ enum Flags { HasPrivateItems = 1, HasNonScalarItems = 1 << 1 };
+
+ CharUnits size() const {
+ CharUnits result;
+ result += CharUnits::fromQuantity(2); // summary byte, num-args byte
+ for (auto &item : Items) {
+ // descriptor byte, size byte
+ result += item.size() + CharUnits::fromQuantity(2);
+ }
+ return result;
+ }
+
+ bool hasPrivateItems() const {
+ return llvm::any_of(
+ Items, [](const OSLogBufferItem &Item) { return Item.getIsPrivate(); });
+ }
+
+ bool hasPublicItems() const {
+ return llvm::any_of(
+ Items, [](const OSLogBufferItem &Item) { return Item.getIsPublic(); });
+ }
+
+ bool hasNonScalar() const {
+ return llvm::any_of(Items, [](const OSLogBufferItem &Item) {
+ return Item.getKind() != OSLogBufferItem::ScalarKind;
+ });
+ }
+
+ unsigned char getSummaryByte() const {
+ unsigned char result = 0;
+ if (hasPrivateItems())
+ result |= HasPrivateItems;
+ if (hasNonScalar())
+ result |= HasNonScalarItems;
+ return result;
+ }
+
+ unsigned char getNumArgsByte() const { return Items.size(); }
+};
+
+// Given a call 'E' to one of the builtins __builtin_os_log_format() or
+// __builtin_os_log_format_buffer_size(), compute the layout of the buffer that
+// the call will write into and store it in 'layout'. Returns 'false' if there
+// was some error encountered while computing the layout, and 'true' otherwise.
+bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E,
+ OSLogBufferLayout &layout);
+
+} // namespace analyze_os_log
+} // namespace clang
+#endif
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
index e3570130c2c2..8c1d1da554bd 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
@@ -415,25 +415,8 @@ private:
BlockInfo()
: HasBackEdges(false), UnprocessedSuccessors(0),
ProcessedPredecessors(0) {}
- BlockInfo(BlockInfo &&RHS)
- : ExitMap(std::move(RHS.ExitMap)),
- HasBackEdges(RHS.HasBackEdges),
- UnprocessedSuccessors(RHS.UnprocessedSuccessors),
- ProcessedPredecessors(RHS.ProcessedPredecessors) {}
-
- BlockInfo &operator=(BlockInfo &&RHS) {
- if (this != &RHS) {
- ExitMap = std::move(RHS.ExitMap);
- HasBackEdges = RHS.HasBackEdges;
- UnprocessedSuccessors = RHS.UnprocessedSuccessors;
- ProcessedPredecessors = RHS.ProcessedPredecessors;
- }
- return *this;
- }
-
- private:
- BlockInfo(const BlockInfo &) = delete;
- void operator=(const BlockInfo &) = delete;
+ BlockInfo(BlockInfo &&) = default;
+ BlockInfo &operator=(BlockInfo &&) = default;
};
// We implement the CFGVisitor API
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
index 6ea93653b91a..cb80ce5da8d2 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
@@ -45,7 +45,7 @@ public:
MemRegionRef(llvm::BumpPtrAllocator *A) : Allocator(A) {}
void *allocate(size_t Sz) {
- return Allocator->Allocate(Sz, llvm::AlignOf<AlignmentType>::Alignment);
+ return Allocator->Allocate(Sz, alignof(AlignmentType));
}
template <typename T> T *allocateT() { return Allocator->Allocate<T>(); }
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index 4324a0352e3a..f6a47d646d1d 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -406,7 +406,8 @@ private:
};
class AnalysisDeclContextManager {
- typedef llvm::DenseMap<const Decl*, AnalysisDeclContext*> ContextMap;
+ typedef llvm::DenseMap<const Decl *, std::unique_ptr<AnalysisDeclContext>>
+ ContextMap;
ContextMap Contexts;
LocationContextManager LocContexts;
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 293990c88e70..d23ed77ded13 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -22,6 +22,7 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
@@ -522,11 +523,15 @@ public:
typedef AdjacentBlocks::const_iterator const_pred_iterator;
typedef AdjacentBlocks::reverse_iterator pred_reverse_iterator;
typedef AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator;
+ typedef llvm::iterator_range<pred_iterator> pred_range;
+ typedef llvm::iterator_range<const_pred_iterator> pred_const_range;
typedef AdjacentBlocks::iterator succ_iterator;
typedef AdjacentBlocks::const_iterator const_succ_iterator;
typedef AdjacentBlocks::reverse_iterator succ_reverse_iterator;
typedef AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator;
+ typedef llvm::iterator_range<succ_iterator> succ_range;
+ typedef llvm::iterator_range<const_succ_iterator> succ_const_range;
pred_iterator pred_begin() { return Preds.begin(); }
pred_iterator pred_end() { return Preds.end(); }
@@ -538,6 +543,13 @@ public:
const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); }
const_pred_reverse_iterator pred_rend() const { return Preds.rend(); }
+ pred_range preds() {
+ return pred_range(pred_begin(), pred_end());
+ }
+ pred_const_range preds() const {
+ return pred_const_range(pred_begin(), pred_end());
+ }
+
succ_iterator succ_begin() { return Succs.begin(); }
succ_iterator succ_end() { return Succs.end(); }
const_succ_iterator succ_begin() const { return Succs.begin(); }
@@ -548,6 +560,13 @@ public:
const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); }
const_succ_reverse_iterator succ_rend() const { return Succs.rend(); }
+ succ_range succs() {
+ return succ_range(succ_begin(), succ_end());
+ }
+ succ_const_range succs() const {
+ return succ_const_range(succ_begin(), succ_end());
+ }
+
unsigned succ_size() const { return Succs.size(); }
bool succ_empty() const { return Succs.empty(); }
@@ -761,55 +780,6 @@ public:
AddCXXNewAllocator(false), AddCXXDefaultInitExprInCtors(false) {}
};
- /// \brief Provides a custom implementation of the iterator class to have the
- /// same interface as Function::iterator - iterator returns CFGBlock
- /// (not a pointer to CFGBlock).
- class graph_iterator {
- public:
- typedef CFGBlock value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef BumpVector<CFGBlock*>::iterator ImplTy;
-
- graph_iterator(const ImplTy &i) : I(i) {}
-
- bool operator==(const graph_iterator &X) const { return I == X.I; }
- bool operator!=(const graph_iterator &X) const { return I != X.I; }
-
- reference operator*() const { return **I; }
- pointer operator->() const { return *I; }
- operator CFGBlock* () { return *I; }
-
- graph_iterator &operator++() { ++I; return *this; }
- graph_iterator &operator--() { --I; return *this; }
-
- private:
- ImplTy I;
- };
-
- class const_graph_iterator {
- public:
- typedef const CFGBlock value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef BumpVector<CFGBlock*>::const_iterator ImplTy;
-
- const_graph_iterator(const ImplTy &i) : I(i) {}
-
- bool operator==(const const_graph_iterator &X) const { return I == X.I; }
- bool operator!=(const const_graph_iterator &X) const { return I != X.I; }
-
- reference operator*() const { return **I; }
- pointer operator->() const { return *I; }
- operator CFGBlock* () const { return *I; }
-
- const_graph_iterator &operator++() { ++I; return *this; }
- const_graph_iterator &operator--() { --I; return *this; }
-
- private:
- ImplTy I;
- };
-
/// buildCFG - Builds a CFG from an AST.
static std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *AST, ASTContext *C,
const BuildOptions &BO);
@@ -845,14 +815,10 @@ public:
const_iterator begin() const { return Blocks.begin(); }
const_iterator end() const { return Blocks.end(); }
- graph_iterator nodes_begin() { return graph_iterator(Blocks.begin()); }
- graph_iterator nodes_end() { return graph_iterator(Blocks.end()); }
- const_graph_iterator nodes_begin() const {
- return const_graph_iterator(Blocks.begin());
- }
- const_graph_iterator nodes_end() const {
- return const_graph_iterator(Blocks.end());
- }
+ iterator nodes_begin() { return iterator(Blocks.begin()); }
+ iterator nodes_end() { return iterator(Blocks.end()); }
+ const_iterator nodes_begin() const { return const_iterator(Blocks.begin()); }
+ const_iterator nodes_end() const { return const_iterator(Blocks.end()); }
reverse_iterator rbegin() { return Blocks.rbegin(); }
reverse_iterator rend() { return Blocks.rend(); }
@@ -893,6 +859,7 @@ public:
typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator
synthetic_stmt_iterator;
+ typedef llvm::iterator_range<synthetic_stmt_iterator> synthetic_stmt_range;
/// Iterates over synthetic DeclStmts in the CFG.
///
@@ -908,6 +875,11 @@ public:
return SyntheticDeclStmts.end();
}
+ /// \sa synthetic_stmt_begin
+ synthetic_stmt_range synthetic_stmts() const {
+ return synthetic_stmt_range(synthetic_stmt_begin(), synthetic_stmt_end());
+ }
+
//===--------------------------------------------------------------------===//
// Member templates useful for various batch operations over CFGs.
//===--------------------------------------------------------------------===//
@@ -998,59 +970,51 @@ template <> struct simplify_type< ::clang::CFGTerminator> {
// Traits for: CFGBlock
template <> struct GraphTraits< ::clang::CFGBlock *> {
- typedef ::clang::CFGBlock NodeType;
+ typedef ::clang::CFGBlock *NodeRef;
typedef ::clang::CFGBlock::succ_iterator ChildIteratorType;
- static NodeType* getEntryNode(::clang::CFGBlock *BB)
- { return BB; }
+ static NodeRef getEntryNode(::clang::CFGBlock *BB) { return BB; }
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->succ_begin(); }
+ static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->succ_end(); }
+ static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
};
template <> struct GraphTraits< const ::clang::CFGBlock *> {
- typedef const ::clang::CFGBlock NodeType;
+ typedef const ::clang::CFGBlock *NodeRef;
typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType;
- static NodeType* getEntryNode(const clang::CFGBlock *BB)
- { return BB; }
+ static NodeRef getEntryNode(const clang::CFGBlock *BB) { return BB; }
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->succ_begin(); }
+ static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->succ_end(); }
+ static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
};
template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > {
- typedef ::clang::CFGBlock NodeType;
+ typedef ::clang::CFGBlock *NodeRef;
typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
- static NodeType *getEntryNode(Inverse< ::clang::CFGBlock*> G)
- { return G.Graph; }
+ static NodeRef getEntryNode(Inverse<::clang::CFGBlock *> G) {
+ return G.Graph;
+ }
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->pred_begin(); }
+ static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->pred_end(); }
+ static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
};
template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
- typedef const ::clang::CFGBlock NodeType;
+ typedef const ::clang::CFGBlock *NodeRef;
typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
- static NodeType *getEntryNode(Inverse<const ::clang::CFGBlock*> G)
- { return G.Graph; }
+ static NodeRef getEntryNode(Inverse<const ::clang::CFGBlock *> G) {
+ return G.Graph;
+ }
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->pred_begin(); }
+ static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->pred_end(); }
+ static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
};
// Traits for: CFG
@@ -1058,9 +1022,9 @@ template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
template <> struct GraphTraits< ::clang::CFG* >
: public GraphTraits< ::clang::CFGBlock *> {
- typedef ::clang::CFG::graph_iterator nodes_iterator;
+ typedef ::clang::CFG::iterator nodes_iterator;
- static NodeType *getEntryNode(::clang::CFG* F) { return &F->getEntry(); }
+ static NodeRef getEntryNode(::clang::CFG *F) { return &F->getEntry(); }
static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();}
static nodes_iterator nodes_end(::clang::CFG* F) { return F->nodes_end(); }
static unsigned size(::clang::CFG* F) { return F->size(); }
@@ -1069,11 +1033,9 @@ template <> struct GraphTraits< ::clang::CFG* >
template <> struct GraphTraits<const ::clang::CFG* >
: public GraphTraits<const ::clang::CFGBlock *> {
- typedef ::clang::CFG::const_graph_iterator nodes_iterator;
+ typedef ::clang::CFG::const_iterator nodes_iterator;
- static NodeType *getEntryNode( const ::clang::CFG* F) {
- return &F->getEntry();
- }
+ static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getEntry(); }
static nodes_iterator nodes_begin( const ::clang::CFG* F) {
return F->nodes_begin();
}
@@ -1088,9 +1050,9 @@ template <> struct GraphTraits<const ::clang::CFG* >
template <> struct GraphTraits<Inverse< ::clang::CFG*> >
: public GraphTraits<Inverse< ::clang::CFGBlock*> > {
- typedef ::clang::CFG::graph_iterator nodes_iterator;
+ typedef ::clang::CFG::iterator nodes_iterator;
- static NodeType *getEntryNode( ::clang::CFG* F) { return &F->getExit(); }
+ static NodeRef getEntryNode(::clang::CFG *F) { return &F->getExit(); }
static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();}
static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); }
};
@@ -1098,9 +1060,9 @@ template <> struct GraphTraits<Inverse< ::clang::CFG*> >
template <> struct GraphTraits<Inverse<const ::clang::CFG*> >
: public GraphTraits<Inverse<const ::clang::CFGBlock*> > {
- typedef ::clang::CFG::const_graph_iterator nodes_iterator;
+ typedef ::clang::CFG::const_iterator nodes_iterator;
- static NodeType *getEntryNode(const ::clang::CFG* F) { return &F->getExit(); }
+ static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getExit(); }
static nodes_iterator nodes_begin(const ::clang::CFG* F) {
return F->nodes_begin();
}
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h
index eda22a57e8a5..b8ae67cbba49 100644
--- a/include/clang/Analysis/CallGraph.h
+++ b/include/clang/Analysis/CallGraph.h
@@ -34,7 +34,8 @@ class CallGraphNode;
class CallGraph : public RecursiveASTVisitor<CallGraph> {
friend class CallGraphNode;
- typedef llvm::DenseMap<const Decl *, CallGraphNode *> FunctionMapTy;
+ typedef llvm::DenseMap<const Decl *, std::unique_ptr<CallGraphNode>>
+ FunctionMapTy;
/// FunctionMap owns all CallGraphNodes.
FunctionMapTy FunctionMap;
@@ -156,7 +157,7 @@ public:
inline bool empty() const {return CalledFunctions.empty(); }
inline unsigned size() const {return CalledFunctions.size(); }
- void addCallee(CallGraphNode *N, CallGraph *CG) {
+ void addCallee(CallGraphNode *N) {
CalledFunctions.push_back(N);
}
@@ -172,25 +173,21 @@ public:
namespace llvm {
template <> struct GraphTraits<clang::CallGraphNode*> {
typedef clang::CallGraphNode NodeType;
- typedef clang::CallGraphNode::CallRecord CallRecordTy;
- typedef std::pointer_to_unary_function<CallRecordTy,
- clang::CallGraphNode*> CGNDerefFun;
+ typedef clang::CallGraphNode *NodeRef;
+ typedef NodeType::iterator ChildIteratorType;
+
static NodeType *getEntryNode(clang::CallGraphNode *CGN) { return CGN; }
- typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
static inline ChildIteratorType child_begin(NodeType *N) {
- return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
- }
- static inline ChildIteratorType child_end (NodeType *N) {
- return map_iterator(N->end(), CGNDerefFun(CGNDeref));
- }
- static clang::CallGraphNode *CGNDeref(CallRecordTy P) {
- return P;
+ return N->begin();
}
+ static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
};
template <> struct GraphTraits<const clang::CallGraphNode*> {
typedef const clang::CallGraphNode NodeType;
+ typedef const clang::CallGraphNode *NodeRef;
typedef NodeType::const_iterator ChildIteratorType;
+
static NodeType *getEntryNode(const clang::CallGraphNode *CGN) { return CGN; }
static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
@@ -202,19 +199,21 @@ template <> struct GraphTraits<clang::CallGraph*>
static NodeType *getEntryNode(clang::CallGraph *CGN) {
return CGN->getRoot(); // Start at the external node!
}
- typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy;
- typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun;
+
+ static clang::CallGraphNode *
+ CGGetValue(clang::CallGraph::const_iterator::value_type &P) {
+ return P.second.get();
+ }
+
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef mapped_iterator<clang::CallGraph::iterator, DerefFun> nodes_iterator;
+ typedef mapped_iterator<clang::CallGraph::iterator, decltype(&CGGetValue)>
+ nodes_iterator;
static nodes_iterator nodes_begin(clang::CallGraph *CG) {
- return map_iterator(CG->begin(), DerefFun(CGdereference));
+ return nodes_iterator(CG->begin(), &CGGetValue);
}
static nodes_iterator nodes_end (clang::CallGraph *CG) {
- return map_iterator(CG->end(), DerefFun(CGdereference));
- }
- static clang::CallGraphNode &CGdereference(PairTy P) {
- return *(P.second);
+ return nodes_iterator(CG->end(), &CGGetValue);
}
static unsigned size(clang::CallGraph *CG) {
@@ -227,22 +226,23 @@ template <> struct GraphTraits<const clang::CallGraph*> :
static NodeType *getEntryNode(const clang::CallGraph *CGN) {
return CGN->getRoot();
}
- typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy;
- typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun;
+
+ static clang::CallGraphNode *
+ CGGetValue(clang::CallGraph::const_iterator::value_type &P) {
+ return P.second.get();
+ }
+
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
typedef mapped_iterator<clang::CallGraph::const_iterator,
- DerefFun> nodes_iterator;
+ decltype(&CGGetValue)>
+ nodes_iterator;
static nodes_iterator nodes_begin(const clang::CallGraph *CG) {
- return map_iterator(CG->begin(), DerefFun(CGdereference));
+ return nodes_iterator(CG->begin(), &CGGetValue);
}
static nodes_iterator nodes_end(const clang::CallGraph *CG) {
- return map_iterator(CG->end(), DerefFun(CGdereference));
- }
- static clang::CallGraphNode &CGdereference(PairTy P) {
- return *(P.second);
+ return nodes_iterator(CG->end(), &CGGetValue);
}
-
static unsigned size(const clang::CallGraph *CG) {
return CG->size();
}
diff --git a/include/clang/Analysis/CloneDetection.h b/include/clang/Analysis/CloneDetection.h
new file mode 100644
index 000000000000..51cad7a96d6f
--- /dev/null
+++ b/include/clang/Analysis/CloneDetection.h
@@ -0,0 +1,288 @@
+//===--- CloneDetection.h - Finds code clones in an AST ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// /file
+/// This file defines classes for searching and anlyzing source code clones.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_CLONEDETECTION_H
+#define LLVM_CLANG_AST_CLONEDETECTION_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/StringMap.h"
+
+#include <vector>
+
+namespace clang {
+
+class Stmt;
+class Decl;
+class VarDecl;
+class ASTContext;
+class CompoundStmt;
+
+/// \brief Identifies a list of statements.
+///
+/// Can either identify a single arbitrary Stmt object, a continuous sequence of
+/// child statements inside a CompoundStmt or no statements at all.
+class StmtSequence {
+ /// If this object identifies a sequence of statements inside a CompoundStmt,
+ /// S points to this CompoundStmt. If this object only identifies a single
+ /// Stmt, then S is a pointer to this Stmt.
+ const Stmt *S;
+
+ /// The related ASTContext for S.
+ ASTContext *Context;
+
+ /// If EndIndex is non-zero, then S is a CompoundStmt and this StmtSequence
+ /// instance is representing the CompoundStmt children inside the array
+ /// [StartIndex, EndIndex).
+ unsigned StartIndex;
+ unsigned EndIndex;
+
+public:
+ /// \brief Constructs a StmtSequence holding multiple statements.
+ ///
+ /// The resulting StmtSequence identifies a continuous sequence of statements
+ /// in the body of the given CompoundStmt. Which statements of the body should
+ /// be identified needs to be specified by providing a start and end index
+ /// that describe a non-empty sub-array in the body of the given CompoundStmt.
+ ///
+ /// \param Stmt A CompoundStmt that contains all statements in its body.
+ /// \param Context The ASTContext for the given CompoundStmt.
+ /// \param StartIndex The inclusive start index in the children array of
+ /// \p Stmt
+ /// \param EndIndex The exclusive end index in the children array of \p Stmt.
+ StmtSequence(const CompoundStmt *Stmt, ASTContext &Context,
+ unsigned StartIndex, unsigned EndIndex);
+
+ /// \brief Constructs a StmtSequence holding a single statement.
+ ///
+ /// \param Stmt An arbitrary Stmt.
+ /// \param Context The ASTContext for the given Stmt.
+ StmtSequence(const Stmt *Stmt, ASTContext &Context);
+
+ /// \brief Constructs an empty StmtSequence.
+ StmtSequence();
+
+ typedef const Stmt *const *iterator;
+
+ /// Returns an iterator pointing to the first statement in this sequence.
+ iterator begin() const;
+
+ /// Returns an iterator pointing behind the last statement in this sequence.
+ iterator end() const;
+
+ /// Returns the first statement in this sequence.
+ ///
+ /// This method should only be called on a non-empty StmtSequence object.
+ const Stmt *front() const {
+ assert(!empty());
+ return begin()[0];
+ }
+
+ /// Returns the last statement in this sequence.
+ ///
+ /// This method should only be called on a non-empty StmtSequence object.
+ const Stmt *back() const {
+ assert(!empty());
+ return begin()[size() - 1];
+ }
+
+ /// Returns the number of statements this object holds.
+ unsigned size() const {
+ if (holdsSequence())
+ return EndIndex - StartIndex;
+ if (S == nullptr)
+ return 0;
+ return 1;
+ }
+
+ /// Returns true if and only if this StmtSequence contains no statements.
+ bool empty() const { return size() == 0; }
+
+ /// Returns the related ASTContext for the stored Stmts.
+ ASTContext &getASTContext() const {
+ assert(Context);
+ return *Context;
+ }
+
+ /// Returns true if this objects holds a list of statements.
+ bool holdsSequence() const { return EndIndex != 0; }
+
+ /// Returns the start sourcelocation of the first statement in this sequence.
+ ///
+ /// This method should only be called on a non-empty StmtSequence object.
+ SourceLocation getStartLoc() const;
+
+ /// Returns the end sourcelocation of the last statement in this sequence.
+ ///
+ /// This method should only be called on a non-empty StmtSequence object.
+ SourceLocation getEndLoc() const;
+
+ /// Returns the source range of the whole sequence - from the beginning
+ /// of the first statement to the end of the last statement.
+ SourceRange getSourceRange() const;
+
+ bool operator==(const StmtSequence &Other) const {
+ return std::tie(S, StartIndex, EndIndex) ==
+ std::tie(Other.S, Other.StartIndex, Other.EndIndex);
+ }
+
+ bool operator!=(const StmtSequence &Other) const {
+ return std::tie(S, StartIndex, EndIndex) !=
+ std::tie(Other.S, Other.StartIndex, Other.EndIndex);
+ }
+
+ /// Returns true if and only if this sequence covers a source range that
+ /// contains the source range of the given sequence \p Other.
+ ///
+ /// This method should only be called on a non-empty StmtSequence object
+ /// and passed a non-empty StmtSequence object.
+ bool contains(const StmtSequence &Other) const;
+};
+
+/// \brief Searches for clones in source code.
+///
+/// First, this class needs a translation unit which is passed via
+/// \p analyzeTranslationUnit . It will then generate and store search data
+/// for all statements inside the given translation unit.
+/// Afterwards the generated data can be used to find code clones by calling
+/// \p findClones .
+///
+/// This class only searches for clones in exectuable source code
+/// (e.g. function bodies). Other clones (e.g. cloned comments or declarations)
+/// are not supported.
+class CloneDetector {
+public:
+ typedef unsigned DataPiece;
+
+ /// Holds the data about a StmtSequence that is needed during the search for
+ /// code clones.
+ struct CloneSignature {
+ /// \brief The hash code of the StmtSequence.
+ ///
+ /// The initial clone groups that are formed during the search for clones
+ /// consist only of Sequences that share the same hash code. This makes this
+ /// value the central part of this heuristic that is needed to find clones
+ /// in a performant way. For this to work, the type of this variable
+ /// always needs to be small and fast to compare.
+ ///
+ /// Also, StmtSequences that are clones of each others have to share
+ /// the same hash code. StmtSequences that are not clones of each other
+ /// shouldn't share the same hash code, but if they do, it will only
+ /// degrade the performance of the hash search but doesn't influence
+ /// the correctness of the result.
+ size_t Hash;
+
+ /// \brief The complexity of the StmtSequence.
+ ///
+ /// This value gives an approximation on how many direct or indirect child
+ /// statements are contained in the related StmtSequence. In general, the
+ /// greater this value, the greater the amount of statements. However, this
+ /// is only an approximation and the actual amount of statements can be
+ /// higher or lower than this value. Statements that are generated by the
+ /// compiler (e.g. macro expansions) for example barely influence the
+ /// complexity value.
+ ///
+ /// The main purpose of this value is to filter clones that are too small
+ /// and therefore probably not interesting enough for the user.
+ unsigned Complexity;
+
+ /// \brief Creates an empty CloneSignature without any data.
+ CloneSignature() : Complexity(1) {}
+
+ CloneSignature(llvm::hash_code Hash, unsigned Complexity)
+ : Hash(Hash), Complexity(Complexity) {}
+ };
+
+ /// Holds group of StmtSequences that are clones of each other and the
+ /// complexity value (see CloneSignature::Complexity) that all stored
+ /// StmtSequences have in common.
+ struct CloneGroup {
+ std::vector<StmtSequence> Sequences;
+ CloneSignature Signature;
+
+ CloneGroup() {}
+
+ CloneGroup(const StmtSequence &Seq, CloneSignature Signature)
+ : Signature(Signature) {
+ Sequences.push_back(Seq);
+ }
+
+ /// \brief Returns false if and only if this group should be skipped when
+ /// searching for clones.
+ bool isValid() const {
+ // A clone group with only one member makes no sense, so we skip them.
+ return Sequences.size() > 1;
+ }
+ };
+
+ /// \brief Generates and stores search data for all statements in the body of
+ /// the given Decl.
+ void analyzeCodeBody(const Decl *D);
+
+ /// \brief Stores the CloneSignature to allow future querying.
+ void add(const StmtSequence &S, const CloneSignature &Signature);
+
+ /// \brief Searches the provided statements for clones.
+ ///
+ /// \param Result Output parameter that is filled with a list of found
+ /// clone groups. Each group contains multiple StmtSequences
+ /// that were identified to be clones of each other.
+ /// \param MinGroupComplexity Only return clones which have at least this
+ /// complexity value.
+ /// \param CheckPatterns Returns only clone groups in which the referenced
+ /// variables follow the same pattern.
+ void findClones(std::vector<CloneGroup> &Result, unsigned MinGroupComplexity,
+ bool CheckPatterns = true);
+
+ /// \brief Describes two clones that reference their variables in a different
+ /// pattern which could indicate a programming error.
+ struct SuspiciousClonePair {
+ /// \brief Utility class holding the relevant information about a single
+ /// clone in this pair.
+ struct SuspiciousCloneInfo {
+ /// The variable which referencing in this clone was against the pattern.
+ const VarDecl *Variable;
+ /// Where the variable was referenced.
+ const Stmt *Mention;
+ /// The variable that should have been referenced to follow the pattern.
+ /// If Suggestion is a nullptr then it's not possible to fix the pattern
+ /// by referencing a different variable in this clone.
+ const VarDecl *Suggestion;
+ SuspiciousCloneInfo(const VarDecl *Variable, const Stmt *Mention,
+ const VarDecl *Suggestion)
+ : Variable(Variable), Mention(Mention), Suggestion(Suggestion) {}
+ SuspiciousCloneInfo() {}
+ };
+ /// The first clone in the pair which always has a suggested variable.
+ SuspiciousCloneInfo FirstCloneInfo;
+ /// This other clone in the pair which can have a suggested variable.
+ SuspiciousCloneInfo SecondCloneInfo;
+ };
+
+ /// \brief Searches the provided statements for pairs of clones that don't
+ /// follow the same pattern when referencing variables.
+ /// \param Result Output parameter that will contain the clone pairs.
+ /// \param MinGroupComplexity Only clone pairs in which the clones have at
+ /// least this complexity value.
+ void findSuspiciousClones(std::vector<SuspiciousClonePair> &Result,
+ unsigned MinGroupComplexity);
+
+private:
+ /// Stores all encountered StmtSequences alongside their CloneSignature.
+ std::vector<std::pair<CloneSignature, StmtSequence>> Sequences;
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_CLONEDETECTION_H
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 5045194ef864..be5adfb29423 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -622,8 +622,8 @@ private:
class CallExitBegin : public ProgramPoint {
public:
// CallExitBegin uses the callee's location context.
- CallExitBegin(const StackFrameContext *L)
- : ProgramPoint(nullptr, CallExitBeginKind, L, nullptr) {}
+ CallExitBegin(const StackFrameContext *L, const ReturnStmt *RS)
+ : ProgramPoint(RS, CallExitBeginKind, L, nullptr) { }
private:
friend class ProgramPoint;
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 7da1efe5ff40..107a3bdffa65 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -198,6 +198,7 @@ class Spelling<string name, string variety> {
class GNU<string name> : Spelling<name, "GNU">;
class Declspec<string name> : Spelling<name, "Declspec">;
+class Microsoft<string name> : Spelling<name, "Microsoft">;
class CXX11<string namespace, string name, int version = 1>
: Spelling<name, "CXX11"> {
string Namespace = namespace;
@@ -241,6 +242,7 @@ def MicrosoftExt : LangOpt<"MicrosoftExt">;
def Borland : LangOpt<"Borland">;
def CUDA : LangOpt<"CUDA">;
def COnly : LangOpt<"CPlusPlus", 1>;
+def CPlusPlus : LangOpt<"CPlusPlus">;
def OpenCL : LangOpt<"OpenCL">;
def RenderScript : LangOpt<"RenderScript">;
@@ -252,7 +254,7 @@ class TargetArch<list<string> arches> {
list<string> OSes;
list<string> CXXABIs;
}
-def TargetARM : TargetArch<["arm", "thumb"]>;
+def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>;
def TargetMips : TargetArch<["mips", "mipsel"]>;
def TargetMSP430 : TargetArch<["msp430"]>;
def TargetX86 : TargetArch<["x86"]>;
@@ -380,7 +382,7 @@ def Alias : Attr {
let Spellings = [GCC<"alias">];
let Args = [StringArgument<"Aliasee">];
let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
- "ExpectedFunctionGlobalVarMethodOrProperty">;
+ "ExpectedFunctionOrGlobalVar">;
let Documentation = [Undocumented];
}
@@ -778,6 +780,14 @@ def EmptyBases : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
let Documentation = [EmptyBasesDocs];
}
+def AllocSize : InheritableAttr {
+ let Spellings = [GCC<"alloc_size">];
+ let Subjects = SubjectList<[Function]>;
+ let Args = [IntArgument<"ElemSizeParam">, IntArgument<"NumElemsParam", 1>];
+ let TemplateDependent = 1;
+ let Documentation = [AllocSizeDocs];
+}
+
def EnableIf : InheritableAttr {
let Spellings = [GNU<"enable_if">];
let Subjects = SubjectList<[Function]>;
@@ -808,6 +818,11 @@ def FastCall : InheritableAttr {
let Documentation = [FastCallDocs];
}
+def RegCall : InheritableAttr {
+ let Spellings = [GCC<"regcall">, Keyword<"__regcall">];
+ let Documentation = [RegCallDocs];
+}
+
def Final : InheritableAttr {
let Spellings = [Keyword<"final">, Keyword<"sealed">];
let Accessors = [Accessor<"isSpelledAsSealed", [Keyword<"sealed">]>];
@@ -1024,6 +1039,12 @@ def NoDuplicate : InheritableAttr {
let Documentation = [NoDuplicateDocs];
}
+def Convergent : InheritableAttr {
+ let Spellings = [GNU<"convergent">, CXX11<"clang", "convergent">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [ConvergentDocs];
+}
+
def NoInline : InheritableAttr {
let Spellings = [GCC<"noinline">, Declspec<"noinline">];
let Subjects = SubjectList<[Function]>;
@@ -1048,24 +1069,37 @@ def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips> {
//
// FIXME: This provides a sub-optimal error message if you attempt to
// use this in CUDA, since CUDA does not use the same terminology.
-def AMDGPUNumVGPR : InheritableAttr {
- let Spellings = [GNU<"amdgpu_num_vgpr">];
- let Args = [UnsignedArgument<"NumVGPR">];
- let Documentation = [AMDGPUNumVGPRDocs];
-
-// FIXME: This should be for OpenCLKernelFunction, but is not to
+//
+// FIXME: SubjectList should be for OpenCLKernelFunction, but is not to
// workaround needing to see kernel attribute before others to know if
// this should be rejected on non-kernels.
- let Subjects = SubjectList<[Function], ErrorDiag,
- "ExpectedKernelFunction">;
+
+def AMDGPUFlatWorkGroupSize : InheritableAttr {
+ let Spellings = [GNU<"amdgpu_flat_work_group_size">];
+ let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max">];
+ let Documentation = [AMDGPUFlatWorkGroupSizeDocs];
+ let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
+}
+
+def AMDGPUWavesPerEU : InheritableAttr {
+ let Spellings = [GNU<"amdgpu_waves_per_eu">];
+ let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max", 1>];
+ let Documentation = [AMDGPUWavesPerEUDocs];
+ let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
}
def AMDGPUNumSGPR : InheritableAttr {
let Spellings = [GNU<"amdgpu_num_sgpr">];
let Args = [UnsignedArgument<"NumSGPR">];
- let Documentation = [AMDGPUNumSGPRDocs];
- let Subjects = SubjectList<[Function], ErrorDiag,
- "ExpectedKernelFunction">;
+ let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
+ let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
+}
+
+def AMDGPUNumVGPR : InheritableAttr {
+ let Spellings = [GNU<"amdgpu_num_vgpr">];
+ let Args = [UnsignedArgument<"NumVGPR">];
+ let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
+ let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
}
def NoSplitStack : InheritableAttr {
@@ -1270,6 +1304,12 @@ def ObjCRootClass : InheritableAttr {
let Documentation = [Undocumented];
}
+def ObjCSubclassingRestricted : InheritableAttr {
+ let Spellings = [GNU<"objc_subclassing_restricted">];
+ let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
+ let Documentation = [ObjCSubclassingRestrictedDocs];
+}
+
def ObjCExplicitProtocolImpl : InheritableAttr {
let Spellings = [GNU<"objc_protocol_requires_explicit_implementation">];
let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>;
@@ -1380,6 +1420,15 @@ def ReqdWorkGroupSize : InheritableAttr {
let Documentation = [Undocumented];
}
+def RequireConstantInit : InheritableAttr {
+ let Spellings = [GNU<"require_constant_initialization">,
+ CXX11<"clang", "require_constant_initialization">];
+ let Subjects = SubjectList<[GlobalVar], ErrorDiag,
+ "ExpectedStaticOrTLSVar">;
+ let Documentation = [RequireConstantInitDocs];
+ let LangOpts = [CPlusPlus];
+}
+
def WorkGroupSizeHint : InheritableAttr {
let Spellings = [GNU<"work_group_size_hint">];
let Args = [UnsignedArgument<"XDim">,
@@ -1518,7 +1567,8 @@ def Target : InheritableAttr {
def TransparentUnion : InheritableAttr {
let Spellings = [GCC<"transparent_union">];
// let Subjects = SubjectList<[Record, TypedefName]>;
- let Documentation = [Undocumented];
+ let Documentation = [TransparentUnionDocs];
+ let LangOpts = [COnly];
}
def Unavailable : InheritableAttr {
@@ -1574,9 +1624,11 @@ def Used : InheritableAttr {
}
def Uuid : InheritableAttr {
- let Spellings = [Declspec<"uuid">];
+ let Spellings = [Declspec<"uuid">, Microsoft<"uuid">];
let Args = [StringArgument<"Guid">];
-// let Subjects = SubjectList<[CXXRecord]>;
+ let Subjects = SubjectList<[Record, Enum], WarnDiag, "ExpectedEnumOrClass">;
+ // FIXME: Allow expressing logical AND for LangOpts. Our condition should be:
+ // CPlusPlus && (MicrosoftExt || Borland)
let LangOpts = [MicrosoftExt, Borland];
let Documentation = [Undocumented];
}
@@ -1680,7 +1732,8 @@ def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetX86> {
def NoSanitize : InheritableAttr {
let Spellings = [GNU<"no_sanitize">, CXX11<"clang", "no_sanitize">];
let Args = [VariadicStringArgument<"Sanitizers">];
- let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
+ let Subjects = SubjectList<[Function, ObjCMethod, GlobalVar], ErrorDiag,
+ "ExpectedFunctionMethodOrGlobalVar">;
let Documentation = [NoSanitizeDocs];
let AdditionalMembers = [{
SanitizerMask getMask() const {
@@ -1702,7 +1755,8 @@ def NoSanitizeSpecific : InheritableAttr {
GCC<"no_sanitize_address">,
GCC<"no_sanitize_thread">,
GNU<"no_sanitize_memory">];
- let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
+ "ExpectedFunctionOrGlobalVar">;
let Documentation = [NoSanitizeAddressDocs, NoSanitizeThreadDocs,
NoSanitizeMemoryDocs];
let ASTNode = 0;
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index d0342bc6038a..b57833a15f31 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -119,7 +119,7 @@ The ``carries_dependency`` attribute specifies dependency propagation into and
out of functions.
When specified on a function or Objective-C method, the ``carries_dependency``
-attribute means that the return value carries a dependency out of the function,
+attribute means that the return value carries a dependency out of the function,
so that the implementation need not constrain ordering upon return from that
function. Implementations of the function and its caller may choose to preserve
dependencies instead of emitting memory ordering instructions such as fences.
@@ -206,6 +206,44 @@ to enforce the provided alignment assumption.
}];
}
+def AllocSizeDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``alloc_size`` attribute can be placed on functions that return pointers in
+order to hint to the compiler how many bytes of memory will be available at the
+returned poiner. ``alloc_size`` takes one or two arguments.
+
+- ``alloc_size(N)`` implies that argument number N equals the number of
+ available bytes at the returned pointer.
+- ``alloc_size(N, M)`` implies that the product of argument number N and
+ argument number M equals the number of available bytes at the returned
+ pointer.
+
+Argument numbers are 1-based.
+
+An example of how to use ``alloc_size``
+
+.. code-block:: c
+
+ void *my_malloc(int a) __attribute__((alloc_size(1)));
+ void *my_calloc(int a, int b) __attribute__((alloc_size(1, 2)));
+
+ int main() {
+ void *const p = my_malloc(100);
+ assert(__builtin_object_size(p, 0) == 100);
+ void *const a = my_calloc(20, 5);
+ assert(__builtin_object_size(a, 0) == 100);
+ }
+
+.. Note:: This attribute works differently in clang than it does in GCC.
+ Specifically, clang will only trace ``const`` pointers (as above); we give up
+ on pointers that are not marked as ``const``. In the vast majority of cases,
+ this is unimportant, because LLVM has support for the ``alloc_size``
+ attribute. However, this may cause mildly unintuitive behavior when used with
+ other attributes, such as ``enable_if``.
+ }];
+}
+
def EnableIfDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -470,6 +508,12 @@ semantics:
* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T``
and ``U`` are compatible types. This conversion is given "conversion" rank.
+* If no viable candidates are otherwise available, we allow a conversion from a
+ pointer of type ``T*`` to a pointer of type ``U*``, where ``T`` and ``U`` are
+ incompatible. This conversion is ranked below all other types of conversions.
+ Please note: ``U`` lacking qualifiers that are present on ``T`` is sufficient
+ for ``T`` and ``U`` to be incompatible.
+
The declaration of ``overloadable`` functions is restricted to function
declarations and definitions. Most importantly, if any function with a given
name is given the ``overloadable`` attribute, then all function declarations
@@ -600,6 +644,33 @@ of the condition.
}];
}
+def ConvergentDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``convergent`` attribute can be placed on a function declaration. It is
+translated into the LLVM ``convergent`` attribute, which indicates that the call
+instructions of a function with this attribute cannot be made control-dependent
+on any additional values.
+
+In languages designed for SPMD/SIMT programming model, e.g. OpenCL or CUDA,
+the call instructions of a function with this attribute must be executed by
+all work items or threads in a work group or sub group.
+
+This attribute is different from ``noduplicate`` because it allows duplicating
+function calls if it can be proved that the duplicated function calls are
+not made control-dependent on any additional values, e.g., unrolling a loop
+executed by all work items.
+
+Sample usage:
+.. code-block:: c
+
+ void convfunc(void) __attribute__((convergent));
+ // Setting it as a C++11 attribute is also valid in a C++ program.
+ // void convfunc(void) [[clang::convergent]];
+
+ }];
+}
+
def NoSplitStackDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -685,10 +756,10 @@ This attribute specifies that the Objective-C class to which it applies is visib
def ObjCBoxableDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
-Structs and unions marked with the ``objc_boxable`` attribute can be used
+Structs and unions marked with the ``objc_boxable`` attribute can be used
with the Objective-C boxed expression syntax, ``@(...)``.
-**Usage**: ``__attribute__((objc_boxable))``. This attribute
+**Usage**: ``__attribute__((objc_boxable))``. This attribute
can only be placed on a declaration of a trivially-copyable struct or union:
.. code-block:: objc
@@ -829,6 +900,44 @@ When one method overrides another, the overriding method can be more widely avai
}];
}
+
+def RequireConstantInitDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+This attribute specifies that the variable to which it is attached is intended
+to have a `constant initializer <http://en.cppreference.com/w/cpp/language/constant_initialization>`_
+according to the rules of [basic.start.static]. The variable is required to
+have static or thread storage duration. If the initialization of the variable
+is not a constant initializer an error will be produced. This attribute may
+only be used in C++.
+
+Note that in C++03 strict constant expression checking is not done. Instead
+the attribute reports if Clang can emit the variable as a constant, even if it's
+not technically a 'constant initializer'. This behavior is non-portable.
+
+Static storage duration variables with constant initializers avoid hard-to-find
+bugs caused by the indeterminate order of dynamic initialization. They can also
+be safely used during dynamic initialization across translation units.
+
+This attribute acts as a compile time assertion that the requirements
+for constant initialization have been met. Since these requirements change
+between dialects and have subtle pitfalls it's important to fail fast instead
+of silently falling back on dynamic initialization.
+
+.. code-block:: c++
+
+ // -std=c++14
+ #define SAFE_STATIC [[clang::require_constant_initialization]]
+ struct T {
+ constexpr T(int) {}
+ ~T(); // non-trivial
+ };
+ SAFE_STATIC T x = {42}; // Initialization OK. Doesn't check destructor.
+ SAFE_STATIC T y = 42; // error: variable does not have a constant initializer
+ // copy initialization is not a constant expression on a non-literal type.
+ }];
+}
+
def WarnMaybeUnusedDocs : Documentation {
let Category = DocCatVariable;
let Heading = "maybe_unused, unused, gnu::unused";
@@ -845,12 +954,12 @@ variable, a function or method, a function parameter, an enumeration, an
enumerator, a non-static data member, or a label.
.. code-block: c++
- #include <cassert>
-
- [[maybe_unused]] void f([[maybe_unused]] bool thing1,
- [[maybe_unused]] bool thing2) {
- [[maybe_unused]] bool b = thing1 && thing2;
- assert(b);
+ #include <cassert>
+
+ [[maybe_unused]] void f([[maybe_unused]] bool thing1,
+ [[maybe_unused]] bool thing2) {
+ [[maybe_unused]] bool b = thing1 && thing2;
+ assert(b);
}
}];
}
@@ -867,16 +976,16 @@ potentially-evaluated discarded-value expression that is not explicitly cast to
`void`.
.. code-block: c++
- struct [[nodiscard]] error_info { /*...*/ };
- error_info enable_missile_safety_mode();
-
- void launch_missiles();
- void test_missiles() {
- enable_missile_safety_mode(); // diagnoses
- launch_missiles();
- }
- error_info &foo();
- void f() { foo(); } // Does not diagnose, error_info is a reference.
+ struct [[nodiscard]] error_info { /*...*/ };
+ error_info enable_missile_safety_mode();
+
+ void launch_missiles();
+ void test_missiles() {
+ enable_missile_safety_mode(); // diagnoses
+ launch_missiles();
+ }
+ error_info &foo();
+ void f() { foo(); } // Does not diagnose, error_info is a reference.
}];
}
@@ -1032,64 +1141,110 @@ the front end.
}];
}
-def DocCatAMDGPURegisterAttributes :
- DocumentationCategory<"AMD GPU Register Attributes"> {
- let Content = [{
-Clang supports attributes for controlling register usage on AMD GPU
-targets. These attributes may be attached to a kernel function
-definition and is an optimization hint to the backend for the maximum
-number of registers to use. This is useful in cases where register
-limited occupancy is known to be an important factor for the
-performance for the kernel.
-
-The semantics are as follows:
-
-- The backend will attempt to limit the number of used registers to
- the specified value, but the exact number used is not
- guaranteed. The number used may be rounded up to satisfy the
- allocation requirements or ABI constraints of the subtarget. For
- example, on Southern Islands VGPRs may only be allocated in
- increments of 4, so requesting a limit of 39 VGPRs will really
- attempt to use up to 40. Requesting more registers than the
- subtarget supports will truncate to the maximum allowed. The backend
- may also use fewer registers than requested whenever possible.
-
-- 0 implies the default no limit on register usage.
-
-- Ignored on older VLIW subtargets which did not have separate scalar
- and vector registers, R600 through Northern Islands.
-
-}];
-}
+def DocCatAMDGPUAttributes : DocumentationCategory<"AMD GPU Attributes">;
-
-def AMDGPUNumVGPRDocs : Documentation {
- let Category = DocCatAMDGPURegisterAttributes;
- let Content = [{
-Clang supports the
-``__attribute__((amdgpu_num_vgpr(<num_registers>)))`` attribute on AMD
-Southern Islands GPUs and later for controlling the number of vector
-registers. A typical value would be between 4 and 256 in increments
-of 4.
-}];
-}
-
-def AMDGPUNumSGPRDocs : Documentation {
- let Category = DocCatAMDGPURegisterAttributes;
+def AMDGPUFlatWorkGroupSizeDocs : Documentation {
+ let Category = DocCatAMDGPUAttributes;
let Content = [{
+The flat work-group size is the number of work-items in the work-group size
+specified when the kernel is dispatched. It is the product of the sizes of the
+x, y, and z dimension of the work-group.
Clang supports the
-``__attribute__((amdgpu_num_sgpr(<num_registers>)))`` attribute on AMD
-Southern Islands GPUs and later for controlling the number of scalar
-registers. A typical value would be between 8 and 104 in increments of
-8.
-
-Due to common instruction constraints, an additional 2-4 SGPRs are
-typically required for internal use depending on features used. This
-value is a hint for the total number of SGPRs to use, and not the
-number of user SGPRs, so no special consideration needs to be given
-for these.
-}];
+``__attribute__((amdgpu_flat_work_group_size(<min>, <max>)))`` attribute for the
+AMDGPU target. This attribute may be attached to a kernel function definition
+and is an optimization hint.
+
+``<min>`` parameter specifies the minimum flat work-group size, and ``<max>``
+parameter specifies the maximum flat work-group size (must be greater than
+``<min>``) to which all dispatches of the kernel will conform. Passing ``0, 0``
+as ``<min>, <max>`` implies the default behavior (``128, 256``).
+
+If specified, the AMDGPU target backend might be able to produce better machine
+code for barriers and perform scratch promotion by estimating available group
+segment size.
+
+An error will be given if:
+ - Specified values violate subtarget specifications;
+ - Specified values are not compatible with values provided through other
+ attributes.
+ }];
+}
+
+def AMDGPUWavesPerEUDocs : Documentation {
+ let Category = DocCatAMDGPUAttributes;
+ let Content = [{
+A compute unit (CU) is responsible for executing the wavefronts of a work-group.
+It is composed of one or more execution units (EU), which are responsible for
+executing the wavefronts. An EU can have enough resources to maintain the state
+of more than one executing wavefront. This allows an EU to hide latency by
+switching between wavefronts in a similar way to symmetric multithreading on a
+CPU. In order to allow the state for multiple wavefronts to fit on an EU, the
+resources used by a single wavefront have to be limited. For example, the number
+of SGPRs and VGPRs. Limiting such resources can allow greater latency hiding,
+but can result in having to spill some register state to memory.
+
+Clang supports the ``__attribute__((amdgpu_waves_per_eu(<min>[, <max>])))``
+attribute for the AMDGPU target. This attribute may be attached to a kernel
+function definition and is an optimization hint.
+
+``<min>`` parameter specifies the requested minimum number of waves per EU, and
+*optional* ``<max>`` parameter specifies the requested maximum number of waves
+per EU (must be greater than ``<min>`` if specified). If ``<max>`` is omitted,
+then there is no restriction on the maximum number of waves per EU other than
+the one dictated by the hardware for which the kernel is compiled. Passing
+``0, 0`` as ``<min>, <max>`` implies the default behavior (no limits).
+
+If specified, this attribute allows an advanced developer to tune the number of
+wavefronts that are capable of fitting within the resources of an EU. The AMDGPU
+target backend can use this information to limit resources, such as number of
+SGPRs, number of VGPRs, size of available group and private memory segments, in
+such a way that guarantees that at least ``<min>`` wavefronts and at most
+``<max>`` wavefronts are able to fit within the resources of an EU. Requesting
+more wavefronts can hide memory latency but limits available registers which
+can result in spilling. Requesting fewer wavefronts can help reduce cache
+thrashing, but can reduce memory latency hiding.
+
+This attribute controls the machine code generated by the AMDGPU target backend
+to ensure it is capable of meeting the requested values. However, when the
+kernel is executed, there may be other reasons that prevent meeting the request,
+for example, there may be wavefronts from other kernels executing on the EU.
+
+An error will be given if:
+ - Specified values violate subtarget specifications;
+ - Specified values are not compatible with values provided through other
+ attributes;
+ - The AMDGPU target backend is unable to create machine code that can meet the
+ request.
+ }];
+}
+
+def AMDGPUNumSGPRNumVGPRDocs : Documentation {
+ let Category = DocCatAMDGPUAttributes;
+ let Content = [{
+Clang supports the ``__attribute__((amdgpu_num_sgpr(<num_sgpr>)))`` and
+``__attribute__((amdgpu_num_vgpr(<num_vgpr>)))`` attributes for the AMDGPU
+target. These attributes may be attached to a kernel function definition and are
+an optimization hint.
+
+If these attributes are specified, then the AMDGPU target backend will attempt
+to limit the number of SGPRs and/or VGPRs used to the specified value(s). The
+number of used SGPRs and/or VGPRs may further be rounded up to satisfy the
+allocation requirements or constraints of the subtarget. Passing ``0`` as
+``num_sgpr`` and/or ``num_vgpr`` implies the default behavior (no limits).
+
+These attributes can be used to test the AMDGPU target backend. It is
+recommended that the ``amdgpu_waves_per_eu`` attribute be used to control
+resources such as SGPRs and VGPRs since it is aware of the limits for different
+subtargets.
+
+An error will be given if:
+ - Specified values violate subtarget specifications;
+ - Specified values are not compatible with values provided through other
+ attributes;
+ - The AMDGPU target backend is unable to create machine code that can meet the
+ request.
+ }];
}
def DocCatCallingConvs : DocumentationCategory<"Calling Conventions"> {
@@ -1166,6 +1321,18 @@ not require callee-cleanup. See the documentation for `__fastcall`_ on MSDN.
}];
}
+def RegCallDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On x86 targets, this attribute changes the calling convention to
+`__regcall`_ convention. This convention aims to pass as many arguments
+as possible in registers. It also tries to utilize registers for the
+return value whenever it is possible.
+
+.. _`__regcall`: https://software.intel.com/en-us/node/693069
+ }];
+}
+
def ThisCallDocs : Documentation {
let Category = DocCatCallingConvs;
let Content = [{
@@ -1194,7 +1361,7 @@ 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 XMM0-XMM5. Homogeneous 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
@@ -1329,7 +1496,7 @@ def NoSanitizeMemoryDocs : Documentation {
.. _langext-memory_sanitizer:
Use ``__attribute__((no_sanitize_memory))`` on a function declaration to
-specify that checks for uninitialized memory should not be inserted
+specify that checks for uninitialized memory should not be inserted
(e.g. by MemorySanitizer). The function may still be instrumented by the tool
to avoid false positives in other places.
}];
@@ -1338,7 +1505,8 @@ to avoid false positives in other places.
def DocCatTypeSafety : DocumentationCategory<"Type Safety Checking"> {
let Content = [{
Clang supports additional attributes to enable checking type safety properties
-that can't be enforced by the C type system. Use cases include:
+that can't be enforced by the C type system. To see warnings produced by these
+checks, ensure that -Wtype-safety is enabled. Use cases include:
* MPI library implementations, where these attributes enable checking that
the buffer type matches the passed ``MPI_Datatype``;
@@ -1376,18 +1544,31 @@ def ArgumentWithTypeTagDocs : Documentation {
Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx,
type_tag_idx)))`` on a function declaration to specify that the function
accepts a type tag that determines the type of some other argument.
-``arg_kind`` is an identifier that should be used when annotating all
-applicable type tags.
This attribute is primarily useful for checking arguments of variadic functions
(``pointer_with_type_tag`` can be used in most non-variadic cases).
+In the attribute prototype above:
+ * ``arg_kind`` is an identifier that should be used when annotating all
+ applicable type tags.
+ * ``arg_idx`` provides the position of a function argument. The expected type of
+ this function argument will be determined by the function argument specified
+ by ``type_tag_idx``. In the code example below, "3" means that the type of the
+ function's third argument will be determined by ``type_tag_idx``.
+ * ``type_tag_idx`` provides the position of a function argument. This function
+ argument will be a type tag. The type tag will determine the expected type of
+ the argument specified by ``arg_idx``. In the code example below, "2" means
+ that the type tag associated with the function's second argument should agree
+ with the type of the argument specified by ``arg_idx``.
+
For example:
.. code-block:: c++
int fcntl(int fd, int cmd, ...)
__attribute__(( argument_with_type_tag(fcntl,3,2) ));
+ // The function's second argument will be a type tag; this type tag will
+ // determine the expected type of the function's third argument.
}];
}
@@ -1399,85 +1580,140 @@ Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))``
on a function declaration to specify that the function accepts a type tag that
determines the pointee type of some other pointer argument.
+In the attribute prototype above:
+ * ``ptr_kind`` is an identifier that should be used when annotating all
+ applicable type tags.
+ * ``ptr_idx`` provides the position of a function argument; this function
+ argument will have a pointer type. The expected pointee type of this pointer
+ type will be determined by the function argument specified by
+ ``type_tag_idx``. In the code example below, "1" means that the pointee type
+ of the function's first argument will be determined by ``type_tag_idx``.
+ * ``type_tag_idx`` provides the position of a function argument; this function
+ argument will be a type tag. The type tag will determine the expected pointee
+ type of the pointer argument specified by ``ptr_idx``. In the code example
+ below, "3" means that the type tag associated with the function's third
+ argument should agree with the pointee type of the pointer argument specified
+ by ``ptr_idx``.
+
For example:
.. code-block:: c++
+ typedef int MPI_Datatype;
int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
__attribute__(( pointer_with_type_tag(mpi,1,3) ));
+ // The function's 3rd argument will be a type tag; this type tag will
+ // determine the expected pointee type of the function's 1st argument.
}];
}
def TypeTagForDatatypeDocs : Documentation {
let Category = DocCatTypeSafety;
let Content = [{
-Clang supports annotating type tags of two forms.
-
-* **Type tag that is an expression containing a reference to some declared
- identifier.** Use ``__attribute__((type_tag_for_datatype(kind, type)))`` on a
- declaration with that identifier:
-
- .. code-block:: c++
-
- extern struct mpi_datatype mpi_datatype_int
- __attribute__(( type_tag_for_datatype(mpi,int) ));
- #define MPI_INT ((MPI_Datatype) &mpi_datatype_int)
-
-* **Type tag that is an integral literal.** Introduce a ``static const``
- variable with a corresponding initializer value and attach
- ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration,
- for example:
-
- .. code-block:: c++
-
- #define MPI_INT ((MPI_Datatype) 42)
- static const MPI_Datatype mpi_datatype_int
- __attribute__(( type_tag_for_datatype(mpi,int) )) = 42
-
-The attribute also accepts an optional third argument that determines how the
-expression is compared to the type tag. There are two supported flags:
+When declaring a variable, use
+``__attribute__((type_tag_for_datatype(kind, type)))`` to create a type tag that
+is tied to the ``type`` argument given to the attribute.
-* ``layout_compatible`` will cause types to be compared according to
- layout-compatibility rules (C++11 [class.mem] p 17, 18). This is
- implemented to support annotating types like ``MPI_DOUBLE_INT``.
+In the attribute prototype above:
+ * ``kind`` is an identifier that should be used when annotating all applicable
+ type tags.
+ * ``type`` indicates the name of the type.
- For example:
-
- .. code-block:: c++
-
- /* In mpi.h */
- struct internal_mpi_double_int { double d; int i; };
- extern struct mpi_datatype mpi_datatype_double_int
- __attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, layout_compatible) ));
-
- #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int)
-
- /* In user code */
- struct my_pair { double a; int b; };
- struct my_pair *buffer;
- MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning
-
- struct my_int_pair { int a; int b; }
- struct my_int_pair *buffer2;
- MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning: actual buffer element
- // type 'struct my_int_pair'
- // doesn't match specified MPI_Datatype
-
-* ``must_be_null`` specifies that the expression should be a null pointer
- constant, for example:
-
- .. code-block:: c++
-
- /* In mpi.h */
- extern struct mpi_datatype mpi_datatype_null
- __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) ));
-
- #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null)
+Clang supports annotating type tags of two forms.
- /* In user code */
- MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL
- // was specified but buffer
- // is not a null pointer
+ * **Type tag that is a reference to a declared identifier.**
+ Use ``__attribute__((type_tag_for_datatype(kind, type)))`` when declaring that
+ identifier:
+
+ .. code-block:: c++
+
+ typedef int MPI_Datatype;
+ extern struct mpi_datatype mpi_datatype_int
+ __attribute__(( type_tag_for_datatype(mpi,int) ));
+ #define MPI_INT ((MPI_Datatype) &mpi_datatype_int)
+ // &mpi_datatype_int is a type tag. It is tied to type "int".
+
+ * **Type tag that is an integral literal.**
+ Declare a ``static const`` variable with an initializer value and attach
+ ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration:
+
+ .. code-block:: c++
+
+ typedef int MPI_Datatype;
+ static const MPI_Datatype mpi_datatype_int
+ __attribute__(( type_tag_for_datatype(mpi,int) )) = 42;
+ #define MPI_INT ((MPI_Datatype) 42)
+ // The number 42 is a type tag. It is tied to type "int".
+
+
+The ``type_tag_for_datatype`` attribute also accepts an optional third argument
+that determines how the type of the function argument specified by either
+``arg_idx`` or ``ptr_idx`` is compared against the type associated with the type
+tag. (Recall that for the ``argument_with_type_tag`` attribute, the type of the
+function argument specified by ``arg_idx`` is compared against the type
+associated with the type tag. Also recall that for the ``pointer_with_type_tag``
+attribute, the pointee type of the function argument specified by ``ptr_idx`` is
+compared against the type associated with the type tag.) There are two supported
+values for this optional third argument:
+
+ * ``layout_compatible`` will cause types to be compared according to
+ layout-compatibility rules (In C++11 [class.mem] p 17, 18, see the
+ layout-compatibility rules for two standard-layout struct types and for two
+ standard-layout union types). This is useful when creating a type tag
+ associated with a struct or union type. For example:
+
+ .. code-block:: c++
+
+ /* In mpi.h */
+ typedef int MPI_Datatype;
+ struct internal_mpi_double_int { double d; int i; };
+ extern struct mpi_datatype mpi_datatype_double_int
+ __attribute__(( type_tag_for_datatype(mpi,
+ struct internal_mpi_double_int, layout_compatible) ));
+
+ #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int)
+
+ int MPI_Send(void *buf, int count, MPI_Datatype datatype, ...)
+ __attribute__(( pointer_with_type_tag(mpi,1,3) ));
+
+ /* In user code */
+ struct my_pair { double a; int b; };
+ struct my_pair *buffer;
+ MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning because the
+ // layout of my_pair is
+ // compatible with that of
+ // internal_mpi_double_int
+
+ struct my_int_pair { int a; int b; }
+ struct my_int_pair *buffer2;
+ MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning because the
+ // layout of my_int_pair
+ // does not match that of
+ // internal_mpi_double_int
+
+ * ``must_be_null`` specifies that the function argument specified by either
+ ``arg_idx`` (for the ``argument_with_type_tag`` attribute) or ``ptr_idx`` (for
+ the ``pointer_with_type_tag`` attribute) should be a null pointer constant.
+ The second argument to the ``type_tag_for_datatype`` attribute is ignored. For
+ example:
+
+ .. code-block:: c++
+
+ /* In mpi.h */
+ typedef int MPI_Datatype;
+ extern struct mpi_datatype mpi_datatype_null
+ __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) ));
+
+ #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null)
+ int MPI_Send(void *buf, int count, MPI_Datatype datatype, ...)
+ __attribute__(( pointer_with_type_tag(mpi,1,3) ));
+
+ /* In user code */
+ struct my_pair { double a; int b; };
+ struct my_pair *buffer;
+ MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL
+ // was specified but buffer
+ // is not a null pointer
}];
}
@@ -1878,7 +2114,7 @@ by Clang.
}
def NullabilityDocs : DocumentationCategory<"Nullability Attributes"> {
let Content = [{
-Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``).
+Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``).
The nullability (type) qualifiers express whether a value of a given pointer type can be null (the ``_Nullable`` qualifier), doesn't have a defined meaning for null (the ``_Nonnull`` qualifier), or for which the purpose of null is unclear (the ``_Null_unspecified`` qualifier). Because nullability qualifiers are expressed within the type system, they are more general than the ``nonnull`` and ``returns_nonnull`` attributes, allowing one to express (for example) a nullable pointer to an array of nonnull pointers. Nullability qualifiers are written to the right of the pointer to which they apply. For example:
@@ -2318,7 +2554,7 @@ def SwiftIndirectResultDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
The ``swift_indirect_result`` attribute marks a parameter of a ``swiftcall``
-function as having the special indirect-result ABI treatmenet.
+function as having the special indirect-result ABI treatment.
This treatment gives the parameter the target's normal indirect-result
ABI treatment, which may involve passing it differently from an ordinary
@@ -2490,3 +2726,29 @@ Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_
If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise.
}];
}
+
+def TransparentUnionDocs : Documentation {
+ let Category = DocCatType;
+ let Content = [{
+This attribute can be applied to a union to change the behaviour of calls to
+functions that have an argument with a transparent union type. The compiler
+behaviour is changed in the following manner:
+
+- A value whose type is any member of the transparent union can be passed as an
+ argument without the need to cast that value.
+
+- The argument is passed to the function using the calling convention of the
+ first member of the transparent union. Consequently, all the members of the
+ transparent union should have the same calling convention as its first member.
+
+Transparent unions are not supported in C++.
+ }];
+}
+
+def ObjCSubclassingRestrictedDocs : Documentation {
+ let Category = DocCatType;
+ let Content = [{
+This attribute can be added to an Objective-C ``@interface`` declaration to
+ensure that this class cannot be subclassed.
+ }];
+}
diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h
index a2b86841cddf..ea9e28ae681a 100644
--- a/include/clang/Basic/Attributes.h
+++ b/include/clang/Basic/Attributes.h
@@ -22,6 +22,8 @@ enum class AttrSyntax {
GNU,
/// Is the identifier known as a __declspec-style attribute?
Declspec,
+ /// Is the identifier known as a [] Microsoft-style attribute?
+ Microsoft,
// Is the identifier known as a C++-style attribute?
CXX,
// Is the identifier known as a pragma attribute?
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 96bb359e51cb..ec0a2796ec08 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -29,6 +29,7 @@
// f -> float
// d -> double
// z -> size_t
+// w -> wchar_t
// F -> constant CFString
// G -> id
// H -> SEL
@@ -74,6 +75,7 @@
// f -> this is a libc/libm function without the '__builtin_' prefix. It can
// be followed by ':headername:' to state which header this function
// comes from.
+// h -> this function requires a specific header or an explicit declaration.
// i -> this is a runtime library implemented function without the
// '__builtin_' prefix. It will be implemented in compiler-rt or libgcc.
// p:N: -> this is a printf-like function whose Nth argument is the format
@@ -366,7 +368,7 @@ BUILTIN(__builtin_islessgreater , "i.", "Fnc")
BUILTIN(__builtin_isunordered , "i.", "Fnc")
// Unary FP classification
-BUILTIN(__builtin_fpclassify, "iiiii.", "Fnc")
+BUILTIN(__builtin_fpclassify, "iiiiii.", "Fnc")
BUILTIN(__builtin_isfinite, "i.", "Fnc")
BUILTIN(__builtin_isinf, "i.", "Fnc")
BUILTIN(__builtin_isinf_sign, "i.", "Fnc")
@@ -455,6 +457,12 @@ BUILTIN(__builtin_strpbrk, "c*cC*cC*", "nF")
BUILTIN(__builtin_strrchr, "c*cC*i", "nF")
BUILTIN(__builtin_strspn, "zcC*cC*", "nF")
BUILTIN(__builtin_strstr, "c*cC*cC*", "nF")
+BUILTIN(__builtin_wcschr, "w*wC*w", "nF")
+BUILTIN(__builtin_wcscmp, "iwC*wC*", "nF")
+BUILTIN(__builtin_wcslen, "zwC*", "nF")
+BUILTIN(__builtin_wcsncmp, "iwC*wC*z", "nF")
+BUILTIN(__builtin_wmemchr, "w*wC*wz", "nF")
+BUILTIN(__builtin_wmemcmp, "iwC*wC*z", "nF")
BUILTIN(__builtin_return_address, "v*IUi", "n")
BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
BUILTIN(__builtin_frame_address, "v*IUi", "n")
@@ -511,6 +519,7 @@ BUILTIN(__builtin_unreachable, "v", "nr")
BUILTIN(__builtin_shufflevector, "v." , "nc")
BUILTIN(__builtin_convertvector, "v." , "nct")
BUILTIN(__builtin_alloca, "v*z" , "Fn")
+BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn")
BUILTIN(__builtin_call_with_static_chain, "v.", "nt")
// "Overloaded" Atomic operator builtins. These are overloaded to support data
@@ -693,7 +702,7 @@ BUILTIN(__atomic_is_lock_free, "izvCD*", "n")
#undef ATOMIC_BUILTIN
// Non-overloaded atomic builtins.
-BUILTIN(__sync_synchronize, "v.", "n")
+BUILTIN(__sync_synchronize, "v", "n")
// GCC does not support these, they are a Clang extension.
BUILTIN(__sync_fetch_and_min, "iiD*i", "n")
BUILTIN(__sync_fetch_and_max, "iiD*i", "n")
@@ -708,6 +717,9 @@ 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)
+LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
+LIBBUILTIN(_byteswap_ulong, "ULiULi", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
+LIBBUILTIN(_byteswap_uint64, "ULLiULLi", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__exception_code, "ULi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_exception_code, "ULi", "n", ALL_MS_LANGUAGES)
@@ -716,15 +728,50 @@ LANGBUILTIN(_exception_info, "v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__abnormal_termination, "i", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_abnormal_termination, "i", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__GetExceptionInfo, "v*.", "ntu", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedAnd8, "ccD*c", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedAnd16, "ssD*s", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedAnd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedCompareExchange8, "ccD*cc", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedCompareExchange16, "ssD*ss", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedCompareExchange64, "LLiLLiD*LLiLLi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedDecrement16, "ssD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchange8, "ccD*c", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchange16, "ssD*s", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangeAdd8, "ccD*c", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangeAdd16, "ssD*s", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangeSub8, "ccD*c", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangeSub16, "ssD*s", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangeSub, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedIncrement16, "ssD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedOr8, "ccD*c", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedOr16, "ssD*s", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedOr, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedXor8, "ccD*c", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedXor16, "ssD*s", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedXor, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__popcnt64, "ULLiULLi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__readfsdword, "ULiULi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_ReturnAddress, "v*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotl8, "UcUcUc", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotl16, "UsUsUc", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotl, "UiUii", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_lrotl, "ULiULii", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotl64, "ULLiULLii", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotr8, "UcUcUc", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotr16, "UsUsUc", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotr, "UiUii", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_lrotr, "ULiULii", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotr64, "ULLiULLii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)
// Microsoft library builtins.
@@ -766,7 +813,7 @@ LIBBUILTIN(fprintf, "iP*cC*.", "fp:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(snprintf, "ic*zcC*.", "fp:2:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(sprintf, "ic*cC*.", "fp:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(vprintf, "icC*a", "fP:0:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vfprintf, "i.", "fP:1:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(vfprintf, "iP*cC*a", "fP:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(vsprintf, "ic*cC*a", "fP:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(scanf, "icC*R.", "fs:0:", "stdio.h", ALL_LANGUAGES)
@@ -790,6 +837,15 @@ LIBBUILTIN(isupper, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
LIBBUILTIN(isxdigit, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
LIBBUILTIN(tolower, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
LIBBUILTIN(toupper, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
+// C99 wchar.h
+// FIXME: This list is incomplete. We should cover at least the functions that
+// take format strings.
+LIBBUILTIN(wcschr, "w*wC*w", "f", "wchar.h", ALL_LANGUAGES)
+LIBBUILTIN(wcscmp, "iwC*wC*", "f", "wchar.h", ALL_LANGUAGES)
+LIBBUILTIN(wcslen, "zwC*", "f", "wchar.h", ALL_LANGUAGES)
+LIBBUILTIN(wcsncmp, "iwC*wC*z", "f", "wchar.h", ALL_LANGUAGES)
+LIBBUILTIN(wmemchr, "w*wC*wz", "f", "wchar.h", ALL_LANGUAGES)
+LIBBUILTIN(wmemcmp, "iwC*wC*z", "f", "wchar.h", ALL_LANGUAGES)
// C99
// In some systems setjmp is a macro that expands to _setjmp. We undefine
@@ -906,6 +962,18 @@ LIBBUILTIN(fabs, "dd", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(fabsf, "ff", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(fabsl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+// Some systems define finitef as alias of _finitef.
+#if defined (finitef)
+#undef finitef
+#endif
+LIBBUILTIN(finite, "id", "fnc", "math.h", GNU_LANG)
+LIBBUILTIN(finitef, "if", "fnc", "math.h", GNU_LANG)
+LIBBUILTIN(finitel, "iLd", "fnc", "math.h", GNU_LANG)
+// glibc's math.h generates calls to __finite
+LIBBUILTIN(__finite, "id", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__finitef, "if", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__finitel, "iLd", "fnc", "math.h", ALL_LANGUAGES)
+
LIBBUILTIN(fmod, "ddd", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(fmodf, "fff", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(fmodl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
@@ -1280,6 +1348,22 @@ BUILTIN(__builtin___get_unsafe_stack_ptr, "v*", "Fn")
BUILTIN(__builtin_nontemporal_store, "v.", "t")
BUILTIN(__builtin_nontemporal_load, "v.", "t")
+// Coroutine intrinsics.
+BUILTIN(__builtin_coro_resume, "vv*", "")
+BUILTIN(__builtin_coro_destroy, "vv*", "")
+BUILTIN(__builtin_coro_done, "bv*", "n")
+BUILTIN(__builtin_coro_promise, "v*v*IiIb", "n")
+
+BUILTIN(__builtin_coro_size, "z", "n")
+BUILTIN(__builtin_coro_frame, "v*", "n")
+BUILTIN(__builtin_coro_free, "v*v*", "n")
+
+BUILTIN(__builtin_coro_id, "v*Iiv*v*v*", "n")
+BUILTIN(__builtin_coro_alloc, "b", "n")
+BUILTIN(__builtin_coro_begin, "v*v*", "n")
+BUILTIN(__builtin_coro_end, "vv*Ib", "n")
+BUILTIN(__builtin_coro_suspend, "cIb", "n")
+BUILTIN(__builtin_coro_param, "bv*v*", "n")
// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
// We need the generic prototype, since the packet type could be anything.
LANGBUILTIN(read_pipe, "i.", "tn", OCLC20_LANG)
@@ -1317,6 +1401,10 @@ LANGBUILTIN(to_global, "v*v*", "tn", OCLC20_LANG)
LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG)
LANGBUILTIN(to_private, "v*v*", "tn", OCLC20_LANG)
+// Builtins for os_log/os_trace
+BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nut")
+BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt")
+
#undef BUILTIN
#undef LIBBUILTIN
#undef LANGBUILTIN
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
index 15e9a413fb42..87c1f93eedef 100644
--- a/include/clang/Basic/Builtins.h
+++ b/include/clang/Basic/Builtins.h
@@ -139,6 +139,13 @@ public:
return strchr(getRecord(ID).Attributes, 'f') != nullptr;
}
+ /// \brief Returns true if this builtin requires appropriate header in other
+ /// compilers. In Clang it will work even without including it, but we can emit
+ /// a warning about missing header.
+ bool isHeaderDependentFunction(unsigned ID) const {
+ return strchr(getRecord(ID).Attributes, 'h') != nullptr;
+ }
+
/// \brief Determines whether this builtin is a predefined compiler-rt/libgcc
/// function, such as "__clear_cache", where we know the signature a
/// priori.
diff --git a/include/clang/Basic/BuiltinsAMDGPU.def b/include/clang/Basic/BuiltinsAMDGPU.def
index ea63ea10f84c..f0f63fa73a79 100644
--- a/include/clang/Basic/BuiltinsAMDGPU.def
+++ b/include/clang/Basic/BuiltinsAMDGPU.def
@@ -36,6 +36,7 @@ BUILTIN(__builtin_amdgcn_workitem_id_z, "Ui", "nc")
// Instruction builtins.
//===----------------------------------------------------------------------===//
BUILTIN(__builtin_amdgcn_s_barrier, "v", "n")
+BUILTIN(__builtin_amdgcn_wave_barrier, "v", "n")
BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n")
BUILTIN(__builtin_amdgcn_div_scalef, "fffbb*", "n")
BUILTIN(__builtin_amdgcn_div_fmas, "ddddb", "nc")
@@ -70,11 +71,30 @@ BUILTIN(__builtin_amdgcn_cubetc, "ffff", "nc")
BUILTIN(__builtin_amdgcn_cubema, "ffff", "nc")
BUILTIN(__builtin_amdgcn_s_memtime, "LUi", "n")
BUILTIN(__builtin_amdgcn_s_sleep, "vIi", "n")
+BUILTIN(__builtin_amdgcn_s_incperflevel, "vIi", "n")
+BUILTIN(__builtin_amdgcn_s_decperflevel, "vIi", "n")
+BUILTIN(__builtin_amdgcn_uicmp, "LUiUiUiIi", "nc")
+BUILTIN(__builtin_amdgcn_uicmpl, "LUiLUiLUiIi", "nc")
+BUILTIN(__builtin_amdgcn_sicmp, "LUiiiIi", "nc")
+BUILTIN(__builtin_amdgcn_sicmpl, "LUiLiLiIi", "nc")
+BUILTIN(__builtin_amdgcn_fcmp, "LUiddIi", "nc")
+BUILTIN(__builtin_amdgcn_fcmpf, "LUiffIi", "nc")
+BUILTIN(__builtin_amdgcn_ds_swizzle, "iiIi", "nc")
//===----------------------------------------------------------------------===//
// VI+ only builtins.
//===----------------------------------------------------------------------===//
+TARGET_BUILTIN(__builtin_amdgcn_div_fixuph, "hhhh", "nc", "16-bit-insts")
+TARGET_BUILTIN(__builtin_amdgcn_rcph, "hh", "nc", "16-bit-insts")
+TARGET_BUILTIN(__builtin_amdgcn_rsqh, "hh", "nc", "16-bit-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sinh, "hh", "nc", "16-bit-insts")
+TARGET_BUILTIN(__builtin_amdgcn_cosh, "hh", "nc", "16-bit-insts")
+TARGET_BUILTIN(__builtin_amdgcn_ldexph, "hhi", "nc", "16-bit-insts")
+TARGET_BUILTIN(__builtin_amdgcn_frexp_manth, "hh", "nc", "16-bit-insts")
+TARGET_BUILTIN(__builtin_amdgcn_frexp_exph, "sh", "nc", "16-bit-insts")
+TARGET_BUILTIN(__builtin_amdgcn_fracth, "hh", "nc", "16-bit-insts")
+TARGET_BUILTIN(__builtin_amdgcn_classh, "bhi", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_s_memrealtime, "LUi", "n", "s-memrealtime")
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index 93b6458c5ef2..6cc7308d4cbc 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -18,6 +18,10 @@
# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
#endif
+#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN)
+# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
// In libgcc
BUILTIN(__clear_cache, "vv*v*", "i")
@@ -115,11 +119,34 @@ LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES)
LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__ldrexd, "WiWiCD*", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveFromCoprocessor, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveFromCoprocessor2, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveToCoprocessor, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveToCoprocessor2, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
+TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanForward64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
#undef BUILTIN
#undef LANGBUILTIN
+#undef TARGET_HEADER_BUILTIN
diff --git a/include/clang/Basic/BuiltinsNVPTX.def b/include/clang/Basic/BuiltinsNVPTX.def
index 456d0001a12d..b6329fbd4251 100644
--- a/include/clang/Basic/BuiltinsNVPTX.def
+++ b/include/clang/Basic/BuiltinsNVPTX.def
@@ -14,6 +14,10 @@
// The format of this database matches clang/Basic/Builtins.def.
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
// Special Registers
BUILTIN(__nvvm_read_ptx_sreg_tid_x, "i", "nc")
@@ -452,18 +456,28 @@ BUILTIN(__builtin_ptx_get_image_channel_orderi_, "ii", "")
BUILTIN(__nvvm_atom_add_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_add_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_add_gen_i, "iiD*i", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_add_gen_i, "iiD*i", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_add_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_add_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_add_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_add_gen_l, "LiLiD*Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_add_gen_l, "LiLiD*Li", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_add_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_add_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_add_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_add_gen_ll, "LLiLLiD*LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_add_gen_ll, "LLiLLiD*LLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_add_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_add_g_f, "ffD*1f", "n")
BUILTIN(__nvvm_atom_add_s_f, "ffD*3f", "n")
BUILTIN(__nvvm_atom_add_gen_f, "ffD*f", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_add_gen_f, "ffD*f", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_add_gen_f, "ffD*f", "n", "satom")
BUILTIN(__nvvm_atom_add_g_d, "ddD*1d", "n")
BUILTIN(__nvvm_atom_add_s_d, "ddD*3d", "n")
BUILTIN(__nvvm_atom_add_gen_d, "ddD*d", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_add_gen_d, "ddD*d", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_add_gen_d, "ddD*d", "n", "satom")
BUILTIN(__nvvm_atom_sub_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_sub_s_i, "iiD*3i", "n")
@@ -478,97 +492,155 @@ BUILTIN(__nvvm_atom_sub_gen_ll, "LLiLLiD*LLi", "n")
BUILTIN(__nvvm_atom_xchg_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_xchg_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_xchg_gen_i, "iiD*i", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_i, "iiD*i", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_xchg_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_xchg_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_xchg_gen_l, "LiLiD*Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_l, "LiLiD*Li", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_xchg_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_xchg_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_xchg_gen_ll, "LLiLLiD*LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_ll, "LLiLLiD*LLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_max_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_max_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_max_gen_i, "iiD*i", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_max_gen_i, "iiD*i", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_max_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_max_g_ui, "UiUiD*1Ui", "n")
BUILTIN(__nvvm_atom_max_s_ui, "UiUiD*3Ui", "n")
BUILTIN(__nvvm_atom_max_gen_ui, "UiUiD*Ui", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ui, "UiUiD*Ui", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ui, "UiUiD*Ui", "n", "satom")
BUILTIN(__nvvm_atom_max_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_max_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_max_gen_l, "LiLiD*Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_max_gen_l, "LiLiD*Li", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_max_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_max_g_ul, "ULiULiD*1ULi", "n")
BUILTIN(__nvvm_atom_max_s_ul, "ULiULiD*3ULi", "n")
BUILTIN(__nvvm_atom_max_gen_ul, "ULiULiD*ULi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ul, "ULiULiD*ULi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ul, "ULiULiD*ULi", "n", "satom")
BUILTIN(__nvvm_atom_max_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_max_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_max_gen_ll, "LLiLLiD*LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ll, "LLiLLiD*LLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_max_g_ull, "ULLiULLiD*1ULLi", "n")
BUILTIN(__nvvm_atom_max_s_ull, "ULLiULLiD*3ULLi", "n")
BUILTIN(__nvvm_atom_max_gen_ull, "ULLiULLiD*ULLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ull, "ULLiULLiD*ULLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ull, "ULLiULLiD*ULLi", "n", "satom")
BUILTIN(__nvvm_atom_min_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_min_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_min_gen_i, "iiD*i", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_min_gen_i, "iiD*i", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_min_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_min_g_ui, "UiUiD*1Ui", "n")
BUILTIN(__nvvm_atom_min_s_ui, "UiUiD*3Ui", "n")
BUILTIN(__nvvm_atom_min_gen_ui, "UiUiD*Ui", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ui, "UiUiD*Ui", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ui, "UiUiD*Ui", "n", "satom")
BUILTIN(__nvvm_atom_min_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_min_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_min_gen_l, "LiLiD*Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_min_gen_l, "LiLiD*Li", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_min_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_min_g_ul, "ULiULiD*1ULi", "n")
BUILTIN(__nvvm_atom_min_s_ul, "ULiULiD*3ULi", "n")
BUILTIN(__nvvm_atom_min_gen_ul, "ULiULiD*ULi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ul, "ULiULiD*ULi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ul, "ULiULiD*ULi", "n", "satom")
BUILTIN(__nvvm_atom_min_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_min_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_min_gen_ll, "LLiLLiD*LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ll, "LLiLLiD*LLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_min_g_ull, "ULLiULLiD*1ULLi", "n")
BUILTIN(__nvvm_atom_min_s_ull, "ULLiULLiD*3ULLi", "n")
BUILTIN(__nvvm_atom_min_gen_ull, "ULLiULLiD*ULLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ull, "ULLiULLiD*ULLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ull, "ULLiULLiD*ULLi", "n", "satom")
BUILTIN(__nvvm_atom_inc_g_ui, "UiUiD*1Ui", "n")
BUILTIN(__nvvm_atom_inc_s_ui, "UiUiD*3Ui", "n")
BUILTIN(__nvvm_atom_inc_gen_ui, "UiUiD*Ui", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_inc_gen_ui, "UiUiD*Ui", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_inc_gen_ui, "UiUiD*Ui", "n", "satom")
BUILTIN(__nvvm_atom_dec_g_ui, "UiUiD*1Ui", "n")
BUILTIN(__nvvm_atom_dec_s_ui, "UiUiD*3Ui", "n")
BUILTIN(__nvvm_atom_dec_gen_ui, "UiUiD*Ui", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_dec_gen_ui, "UiUiD*Ui", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_dec_gen_ui, "UiUiD*Ui", "n", "satom")
BUILTIN(__nvvm_atom_and_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_and_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_and_gen_i, "iiD*i", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_and_gen_i, "iiD*i", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_and_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_and_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_and_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_and_gen_l, "LiLiD*Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_and_gen_l, "LiLiD*Li", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_and_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_and_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_and_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_and_gen_ll, "LLiLLiD*LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_and_gen_ll, "LLiLLiD*LLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_and_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_or_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_or_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_or_gen_i, "iiD*i", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_or_gen_i, "iiD*i", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_or_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_or_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_or_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_or_gen_l, "LiLiD*Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_or_gen_l, "LiLiD*Li", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_or_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_or_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_or_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_or_gen_ll, "LLiLLiD*LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_or_gen_ll, "LLiLLiD*LLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_or_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_xor_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_xor_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_xor_gen_i, "iiD*i", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_i, "iiD*i", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_xor_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_xor_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_xor_gen_l, "LiLiD*Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_l, "LiLiD*Li", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_xor_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_xor_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_xor_gen_ll, "LLiLLiD*LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_ll, "LLiLLiD*LLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_cas_g_i, "iiD*1ii", "n")
BUILTIN(__nvvm_atom_cas_s_i, "iiD*3ii", "n")
BUILTIN(__nvvm_atom_cas_gen_i, "iiD*ii", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_i, "iiD*ii", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_i, "iiD*ii", "n", "satom")
BUILTIN(__nvvm_atom_cas_g_l, "LiLiD*1LiLi", "n")
BUILTIN(__nvvm_atom_cas_s_l, "LiLiD*3LiLi", "n")
BUILTIN(__nvvm_atom_cas_gen_l, "LiLiD*LiLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_l, "LiLiD*LiLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_l, "LiLiD*LiLi", "n", "satom")
BUILTIN(__nvvm_atom_cas_g_ll, "LLiLLiD*1LLiLLi", "n")
BUILTIN(__nvvm_atom_cas_s_ll, "LLiLLiD*3LLiLLi", "n")
BUILTIN(__nvvm_atom_cas_gen_ll, "LLiLLiD*LLiLLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_ll, "LLiLLiD*LLiLLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_ll, "LLiLLiD*LLiLLi", "n", "satom")
// Compiler Error Warn
BUILTIN(__nvvm_compiler_error, "vcC*4", "n")
@@ -611,3 +683,4 @@ BUILTIN(__nvvm_ldg_f4, "E4fE4fC*", "")
BUILTIN(__nvvm_ldg_d2, "E2dE2dC*", "")
#undef BUILTIN
+#undef TARGET_BUILTIN
diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
index 365dcc02a46d..657ea4225aa8 100644
--- a/include/clang/Basic/BuiltinsPPC.def
+++ b/include/clang/Basic/BuiltinsPPC.def
@@ -134,6 +134,14 @@ BUILTIN(__builtin_altivec_vcmpequw, "V4iV4iV4i", "")
BUILTIN(__builtin_altivec_vcmpequd, "V2LLiV2LLiV2LLi", "")
BUILTIN(__builtin_altivec_vcmpeqfp, "V4iV4fV4f", "")
+BUILTIN(__builtin_altivec_vcmpneb, "V16cV16cV16c", "")
+BUILTIN(__builtin_altivec_vcmpneh, "V8sV8sV8s", "")
+BUILTIN(__builtin_altivec_vcmpnew, "V4iV4iV4i", "")
+
+BUILTIN(__builtin_altivec_vcmpnezb, "V16cV16cV16c", "")
+BUILTIN(__builtin_altivec_vcmpnezh, "V8sV8sV8s", "")
+BUILTIN(__builtin_altivec_vcmpnezw, "V4iV4iV4i", "")
+
BUILTIN(__builtin_altivec_vcmpgtsb, "V16cV16ScV16Sc", "")
BUILTIN(__builtin_altivec_vcmpgtub, "V16cV16UcV16Uc", "")
BUILTIN(__builtin_altivec_vcmpgtsh, "V8sV8SsV8Ss", "")
@@ -223,6 +231,11 @@ BUILTIN(__builtin_altivec_vcmpequw_p, "iiV4iV4i", "")
BUILTIN(__builtin_altivec_vcmpequd_p, "iiV2LLiV2LLi", "")
BUILTIN(__builtin_altivec_vcmpeqfp_p, "iiV4fV4f", "")
+BUILTIN(__builtin_altivec_vcmpneb_p, "iiV16cV16c", "")
+BUILTIN(__builtin_altivec_vcmpneh_p, "iiV8sV8s", "")
+BUILTIN(__builtin_altivec_vcmpnew_p, "iiV4iV4i", "")
+BUILTIN(__builtin_altivec_vcmpned_p, "iiV2LLiV2LLi", "")
+
BUILTIN(__builtin_altivec_vcmpgtsb_p, "iiV16ScV16Sc", "")
BUILTIN(__builtin_altivec_vcmpgtub_p, "iiV16UcV16Uc", "")
BUILTIN(__builtin_altivec_vcmpgtsh_p, "iiV8SsV8Ss", "")
@@ -254,14 +267,54 @@ BUILTIN(__builtin_altivec_vclzb, "V16UcV16Uc", "")
BUILTIN(__builtin_altivec_vclzh, "V8UsV8Us", "")
BUILTIN(__builtin_altivec_vclzw, "V4UiV4Ui", "")
BUILTIN(__builtin_altivec_vclzd, "V2ULLiV2ULLi", "")
+BUILTIN(__builtin_altivec_vctzb, "V16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vctzh, "V8UsV8Us", "")
+BUILTIN(__builtin_altivec_vctzw, "V4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vctzd, "V2ULLiV2ULLi", "")
+
+BUILTIN(__builtin_altivec_vclzlsbb, "SiV16Uc", "")
+BUILTIN(__builtin_altivec_vctzlsbb, "SiV16Uc", "")
+BUILTIN(__builtin_altivec_vprtybw, "V4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vprtybd, "V2ULLiV2ULLi", "")
+BUILTIN(__builtin_altivec_vprtybq, "V1ULLLiV1ULLLi", "")
+
+// Vector population count built-ins
+BUILTIN(__builtin_altivec_vpopcntb, "V16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vpopcnth, "V8UsV8Us", "")
+BUILTIN(__builtin_altivec_vpopcntw, "V4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vpopcntd, "V2ULLiV2ULLi", "")
+
+// Absolute difference built-ins
+BUILTIN(__builtin_altivec_vabsdub, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vabsduh, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vabsduw, "V4UiV4UiV4Ui", "")
+
+// P9 Shift built-ins.
+BUILTIN(__builtin_altivec_vslv, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vsrv, "V16UcV16UcV16Uc", "")
+
+// P9 Vector rotate built-ins
+BUILTIN(__builtin_altivec_vrlwmi, "V4UiV4UiV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vrldmi, "V2ULLiV2ULLiV2ULLiV2ULLi", "")
+BUILTIN(__builtin_altivec_vrlwnm, "V4UiV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vrldnm, "V2ULLiV2ULLiV2ULLi", "")
// VSX built-ins.
BUILTIN(__builtin_vsx_lxvd2x, "V2divC*", "")
BUILTIN(__builtin_vsx_lxvw4x, "V4iivC*", "")
+BUILTIN(__builtin_vsx_lxvd2x_be, "V2dSLLivC*", "")
+BUILTIN(__builtin_vsx_lxvw4x_be, "V4iSLLivC*", "")
BUILTIN(__builtin_vsx_stxvd2x, "vV2div*", "")
BUILTIN(__builtin_vsx_stxvw4x, "vV4iiv*", "")
+BUILTIN(__builtin_vsx_stxvd2x_be, "vV2dSLLivC*", "")
+BUILTIN(__builtin_vsx_stxvw4x_be, "vV4iSLLivC*", "")
+
+BUILTIN(__builtin_vsx_lxvl, "V4ivC*ULLi", "")
+BUILTIN(__builtin_vsx_lxvll, "V4ivC*ULLi", "")
+BUILTIN(__builtin_vsx_stxvl, "vV4iv*ULLi", "")
+BUILTIN(__builtin_vsx_stxvll, "vV4iv*ULLi", "")
BUILTIN(__builtin_vsx_xvmaxdp, "V2dV2dV2d", "")
BUILTIN(__builtin_vsx_xvmaxsp, "V4fV4fV4f", "")
@@ -339,6 +392,31 @@ BUILTIN(__builtin_vsx_xvcpsgnsp, "V4fV4fV4f", "")
BUILTIN(__builtin_vsx_xvabssp, "V4fV4f", "")
BUILTIN(__builtin_vsx_xvabsdp, "V2dV2d", "")
+// vector Insert/Extract exponent/significand builtins
+BUILTIN(__builtin_vsx_xviexpdp, "V2dV2ULLiV2ULLi", "")
+BUILTIN(__builtin_vsx_xviexpsp, "V4fV4UiV4Ui", "")
+BUILTIN(__builtin_vsx_xvxexpdp, "V2ULLiV2d", "")
+BUILTIN(__builtin_vsx_xvxexpsp, "V4UiV4f", "")
+BUILTIN(__builtin_vsx_xvxsigdp, "V2ULLiV2d", "")
+BUILTIN(__builtin_vsx_xvxsigsp, "V4UiV4f", "")
+
+// Conversion builtins
+BUILTIN(__builtin_vsx_xvcvdpsxws, "V4SiV2d", "")
+BUILTIN(__builtin_vsx_xvcvdpuxws, "V4UiV2d", "")
+BUILTIN(__builtin_vsx_xvcvsxwdp, "V2dV4Si", "")
+BUILTIN(__builtin_vsx_xvcvuxwdp, "V2dV4Ui", "")
+BUILTIN(__builtin_vsx_xvcvspdp, "V2dV4f", "")
+BUILTIN(__builtin_vsx_xvcvsxdsp, "V4fV2SLLi", "")
+BUILTIN(__builtin_vsx_xvcvuxdsp, "V4fV2ULLi", "")
+BUILTIN(__builtin_vsx_xvcvdpsp, "V4fV2d", "")
+
+BUILTIN(__builtin_vsx_xvcvsphp, "V4fV4f", "")
+BUILTIN(__builtin_vsx_xvcvhpsp, "V4fV8Us", "")
+
+// Vector Test Data Class builtins
+BUILTIN(__builtin_vsx_xvtstdcdp, "V2ULLiV2dIi", "")
+BUILTIN(__builtin_vsx_xvtstdcsp, "V4UiV4fIi", "")
+
// HTM builtins
BUILTIN(__builtin_tbegin, "UiUIi", "")
BUILTIN(__builtin_tend, "UiUIi", "")
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 0accba4abab1..e53992bbf50e 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -23,6 +23,10 @@
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
+#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN)
+# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
// FIXME: Are these nothrow/const?
// Miscellaneous builtin for checking x86 cpu features.
@@ -44,9 +48,7 @@ TARGET_BUILTIN(__builtin_ia32_undef512, "V8d", "nc", "")
// FLAGS
//
TARGET_BUILTIN(__builtin_ia32_readeflags_u32, "Ui", "n", "")
-TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "")
TARGET_BUILTIN(__builtin_ia32_writeeflags_u32, "vUi", "n", "")
-TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "")
// 3DNow!
//
@@ -301,15 +303,16 @@ TARGET_BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "", "ssse3")
TARGET_BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "", "ssse3")
TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "", "sse")
+TARGET_HEADER_BUILTIN(_mm_setcsr, "vUi", "h","xmmintrin.h", ALL_LANGUAGES, "sse")
TARGET_BUILTIN(__builtin_ia32_stmxcsr, "Ui", "", "sse")
+TARGET_HEADER_BUILTIN(_mm_getcsr, "Ui", "h", "xmmintrin.h", ALL_LANGUAGES, "sse")
TARGET_BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_cvttss2si, "iV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_movmskps, "iV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_sfence, "v", "", "sse")
+TARGET_HEADER_BUILTIN(_mm_sfence, "v", "h", "xmmintrin.h", ALL_LANGUAGES, "sse")
TARGET_BUILTIN(__builtin_ia32_rcpps, "V4fV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_rcpss, "V4fV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_rsqrtps, "V4fV4f", "", "sse")
@@ -331,15 +334,17 @@ TARGET_BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvttsd2si, "iV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "LLiV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvtsd2ss, "V4fV4fV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_clflush, "vvC*", "", "sse2")
+TARGET_HEADER_BUILTIN(_mm_clflush, "vvC*", "h", "emmintrin.h", ALL_LANGUAGES, "sse2")
TARGET_BUILTIN(__builtin_ia32_lfence, "v", "", "sse2")
+TARGET_HEADER_BUILTIN(_mm_lfence, "v", "h", "emmintrin.h", ALL_LANGUAGES, "sse2")
TARGET_BUILTIN(__builtin_ia32_mfence, "v", "", "sse2")
+TARGET_HEADER_BUILTIN(_mm_mfence, "v", "h", "emmintrin.h", ALL_LANGUAGES, "sse2")
TARGET_BUILTIN(__builtin_ia32_pause, "v", "", "sse2")
+TARGET_HEADER_BUILTIN(_mm_pause, "v", "h", "emmintrin.h", ALL_LANGUAGES, "sse2")
TARGET_BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "", "sse2")
@@ -413,7 +418,6 @@ TARGET_BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16ciIc","", "sse4.2")
TARGET_BUILTIN(__builtin_ia32_crc32qi, "UiUiUc", "", "sse4.2")
TARGET_BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "", "sse4.2")
TARGET_BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "", "sse4.2")
// SSE4a
TARGET_BUILTIN(__builtin_ia32_extrqi, "V2LLiV2LLiIcIc", "", "sse4a")
@@ -627,65 +631,44 @@ TARGET_BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "", "rdrnd")
// FSGSBASE
TARGET_BUILTIN(__builtin_ia32_rdfsbase32, "Ui", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_rdfsbase64, "ULLi", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_rdgsbase32, "Ui", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_wrfsbase32, "vUi", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_wrgsbase32, "vUi", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "", "fsgsbase")
// FXSR
TARGET_BUILTIN(__builtin_ia32_fxrstor, "vv*", "", "fxsr")
-TARGET_BUILTIN(__builtin_ia32_fxrstor64, "vv*", "", "fxsr")
TARGET_BUILTIN(__builtin_ia32_fxsave, "vv*", "", "fxsr")
-TARGET_BUILTIN(__builtin_ia32_fxsave64, "vv*", "", "fxsr")
// XSAVE
TARGET_BUILTIN(__builtin_ia32_xsave, "vv*ULLi", "", "xsave")
-TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "", "xsave")
TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*ULLi", "", "xsave")
-TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "", "xsave")
TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*ULLi", "", "xsaveopt")
-TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "", "xsaveopt")
TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "", "xsaves")
-TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "", "xsaves")
TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "", "xsavec")
-TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec")
TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "", "xsaves")
-TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "", "xsaves")
//CLFLUSHOPT
TARGET_BUILTIN(__builtin_ia32_clflushopt, "vc*", "", "clflushopt")
// ADX
TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "", "adx")
-TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx")
TARGET_BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "", "")
-TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "")
TARGET_BUILTIN(__builtin_ia32_subborrow_u32, "UcUcUiUiUi*", "", "")
-TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "", "")
// RDSEED
TARGET_BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "", "rdseed")
TARGET_BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "", "rdseed")
-TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "", "rdseed")
// BMI
TARGET_BUILTIN(__builtin_ia32_bextr_u32, "UiUiUi", "", "bmi")
-TARGET_BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "", "bmi")
// BMI2
TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "", "bmi2")
// TBM
TARGET_BUILTIN(__builtin_ia32_bextri_u32, "UiUiIUi", "", "tbm")
-TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "", "tbm")
// SHA
TARGET_BUILTIN(__builtin_ia32_sha1rnds4, "V4iV4iV4iIc", "", "sha")
@@ -894,6 +877,7 @@ TARGET_BUILTIN(__builtin_ia32_xtest, "i", "", "rtm")
BUILTIN(__builtin_ia32_rdpmc, "ULLii", "")
BUILTIN(__builtin_ia32_rdtsc, "ULLi", "")
+BUILTIN(__rdtsc, "ULLi", "")
BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "")
// PKU
TARGET_BUILTIN(__builtin_ia32_rdpkru, "Ui", "", "pku")
@@ -977,8 +961,6 @@ TARGET_BUILTIN(__builtin_ia32_maxps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512
TARGET_BUILTIN(__builtin_ia32_maxpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtdq2ps512_mask, "V16fV16iV16fUsIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtdq2pd512_mask, "V8dV8iV8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtudq2pd512_mask, "V8dV8iV8dUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fIiV16sUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsIi", "", "avx512f")
@@ -992,12 +974,11 @@ TARGET_BUILTIN(__builtin_ia32_pminsd512_mask, "V16iV16iV16iV16iUs", "", "avx512f
TARGET_BUILTIN(__builtin_ia32_pminsq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pminud512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pminuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmuldq512_mask, "V8LLiV16iV16iV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmuludq512_mask, "V8LLiV16iV16iV8LLiUc", "", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8LLiV16iV16i", "", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8LLiV16iV16i", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_ptestmd512, "UsV16iV16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_ptestmq512, "UcV8LLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pbroadcastd512_gpr_mask, "V16iiV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_gpr_mask, "V8LLiLLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_mem_mask, "V8LLiLLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "", "avx512f")
@@ -1015,27 +996,19 @@ TARGET_BUILTIN(__builtin_ia32_vpermt2vard512_mask, "V16iV16iV16iV16iUs", "", "av
TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_mask, "V16fV16iV16fV16fUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_mask, "V8dV8LLiV8dV8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_alignq512_mask, "V8LLiV8LLiV8LLiIiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_alignd512_mask, "V16iV16iV16iIiV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_alignd128_mask, "V4iV4iV4iIiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_alignd256_mask, "V8iV8iV8iIiV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_alignq128_mask, "V2LLiV2LLiV2LLiIiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_alignq256_mask, "V4LLiV4LLiV4LLiIiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_extractf64x4_mask, "V4dV8dIiV4dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_extractf32x4_mask, "V4fV16fIiV4fUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V4iV2LLiLLiC*V2LLiUci","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V8iV4LLiLLiC*V4LLiUci","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V4iV2LLiLLiC*V4iUci","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUci","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V8iV4LLiLLiC*V4iUci","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUci","","avx512vl")
@@ -1093,71 +1066,6 @@ TARGET_BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8LLiV8LLiIiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_paddq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psubd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psubq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_paddd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_paddq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psubd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psubq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmuldq256_mask, "V4LLiV8iV8iV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmuldq128_mask, "V2LLiV4iV4iV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmuludq256_mask, "V4LLiV8iV8iV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmuludq128_mask, "V2LLiV4iV4iV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmulld256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmulld128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_paddb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmullw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmullw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmullw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_paddq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psubq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_paddd512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psubd512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_pmulld512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmullq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_xorpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_xorps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_orpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_orps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andnpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andnps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_pmullq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_pmullq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andnpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andnpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andnps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andnps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_andps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_xorpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_xorpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_xorps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_xorps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_orpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_orpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_orps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_orps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq")
-
TARGET_BUILTIN(__builtin_ia32_pabsb512_mask, "V64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pabsw512_mask, "V32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packssdw512_mask, "V32sV16iV16iV32sUi", "", "avx512bw")
@@ -1178,7 +1086,7 @@ TARGET_BUILTIN(__builtin_ia32_pminsb512_mask, "V64cV64cV64cV64cULLi", "", "avx51
TARGET_BUILTIN(__builtin_ia32_pminsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminub512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminuw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pshufb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pshufb512, "V64cV64cV64c", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
@@ -1197,57 +1105,6 @@ TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512_mask, "V16iV16iV16iUs", "", "avx5
TARGET_BUILTIN(__builtin_ia32_vplzcntd_512_mask, "V16iV16iV16iUs", "", "avx512cd")
TARGET_BUILTIN(__builtin_ia32_vplzcntq_512_mask, "V8LLiV8LLiV8LLiUc", "", "avx512cd")
-TARGET_BUILTIN(__builtin_ia32_pabsb128_mask, "V16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pabsb256_mask, "V32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pabsw128_mask, "V8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pabsw256_mask, "V16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packssdw128_mask, "V8sV4iV4iV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packssdw256_mask, "V16sV8iV8iV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packsswb128_mask, "V16cV8sV8sV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packsswb256_mask, "V32cV16sV16sV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packusdw128_mask, "V8sV4iV4iV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packusdw256_mask, "V16sV8iV8iV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packuswb128_mask, "V16cV8sV8sV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packuswb256_mask, "V32cV16sV16sV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddusb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddusb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddusw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddusw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pavgb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pavgb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pavgw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pavgw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxub128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxub256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxuw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminub128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminub256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminuw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pshufb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pshufb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-
TARGET_BUILTIN(__builtin_ia32_vpermi2varhi128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_vpermi2varhi256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_vpermt2varhi128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
@@ -1284,10 +1141,6 @@ TARGET_BUILTIN(__builtin_ia32_subsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f
TARGET_BUILTIN(__builtin_ia32_maxsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_minsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_addpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_addpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_addps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_addps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_compressdf128_mask, "V2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_compressdf256_mask, "V4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_compressdi128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl")
@@ -1304,8 +1157,6 @@ TARGET_BUILTIN(__builtin_ia32_compressstoresf128_mask, "vV4f*V4fUc", "", "avx512
TARGET_BUILTIN(__builtin_ia32_compressstoresf256_mask, "vV8f*V8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_compressstoresi128_mask, "vV4i*V4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_compressstoresi256_mask, "vV8i*V8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtdq2pd128_mask, "V2dV4iV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtdq2pd256_mask, "V4dV4iV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtdq2ps128_mask, "V4fV4iV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtdq2ps256_mask, "V8fV8iV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtpd2dq128_mask, "V4iV2dV4iUc", "", "avx512vl")
@@ -1328,14 +1179,8 @@ TARGET_BUILTIN(__builtin_ia32_cvttps2dq128_mask, "V4iV4fV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvttps2dq256_mask, "V8iV8fV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvttps2udq128_mask, "V4iV4fV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvttps2udq256_mask, "V8iV8fV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtudq2pd128_mask, "V2dV4iV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtudq2pd256_mask, "V4dV4iV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtudq2ps128_mask, "V4fV4iV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtudq2ps256_mask, "V8fV8iV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_divpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_divpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_divps_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_divps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_expanddf128_mask, "V2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_expanddf256_mask, "V4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_expanddi128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl")
@@ -1356,36 +1201,14 @@ TARGET_BUILTIN(__builtin_ia32_getexppd128_mask, "V2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_getexppd256_mask, "V4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_getexpps128_mask, "V4fV4fV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_getexpps256_mask, "V8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_maxpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_maxpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_maxps_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_maxps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_minpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_minpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_minps_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_minps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_mulpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_mulpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_mulps_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_mulps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pabsd128_mask, "V4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pabsd256_mask, "V8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pabsq128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pabsq256_mask, "V4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxsd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxsd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxsq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxsq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxud128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxud256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxuq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxuq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminsd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminsd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminsq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminsq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminud128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminud256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminuq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminuq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_rndscalepd_128_mask, "V2dV2dIiV2dUc", "", "avx512vl")
@@ -1414,14 +1237,6 @@ TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vi*UcV4iV4iIi", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vf*UcV8iV8fIi", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vi*UcV8iV8iIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_sqrtpd128_mask, "V2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_sqrtpd256_mask, "V4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_sqrtps128_mask, "V4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_sqrtps256_mask, "V8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_subpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_subpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_subps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_subps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2vard128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2vard256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2varpd128_mask, "V2dV2dV2LLiV2dUc", "", "avx512vl")
@@ -1485,22 +1300,12 @@ TARGET_BUILTIN(__builtin_ia32_reduceps128_mask, "V4fV4fIiV4fUc", "", "avx512vl,a
TARGET_BUILTIN(__builtin_ia32_reduceps256_mask, "V8fV8fIiV8fUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_reducesd_mask, "V2dV2dV2dV2dUcIiIi", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_reducess_mask, "V4fV4fV4fV4fUcIiIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_pmaddubsw128_mask, "V8sV16cV16cV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaddubsw256_mask, "V16sV32cV32cV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaddwd128_mask, "V4iV8sV8sV4iUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaddwd256_mask, "V8iV16sV16sV8iUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovswb128_mask, "V16cV8sV16cUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovswb256_mask, "V16cV16sV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovuswb128_mask, "V16cV8sV16cUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovuswb256_mask, "V16cV16sV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovwb128_mask, "V16cV8sV16cUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovwb256_mask, "V16cV16sV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhrsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhrsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhuw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_cvtpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvtps2qq512_mask, "V8LLiV8fV8LLiUcIi", "", "avx512dq")
@@ -1517,42 +1322,6 @@ TARGET_BUILTIN(__builtin_ia32_rangepd512_mask, "V8dV8dV8dIiV8dUcIi", "", "avx512
TARGET_BUILTIN(__builtin_ia32_rangeps512_mask, "V16fV16fV16fIiV16fUsIi", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_reducepd512_mask, "V8dV8dIiV8dUcIi", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_reduceps512_mask, "V16fV16fIiV16fUsIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_pmovsxbw512_mask, "V32sV32cV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovsxbd512_mask, "V16iV16cV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsxbq512_mask, "V8LLiV16cV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsxdq512_mask, "V8LLiV8iV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsxwd512_mask, "V16iV16sV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsxwq512_mask, "V8LLiV8sV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsxbw128_mask, "V8sV16cV8sUc","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovsxbw256_mask, "V16sV16cV16sUs","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovsxbd128_mask, "V4iV16cV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsxbd256_mask, "V8iV16cV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsxbq128_mask, "V2LLiV16cV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsxbq256_mask, "V4LLiV16cV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsxdq128_mask, "V2LLiV4iV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsxdq256_mask, "V4LLiV4iV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsxwd128_mask, "V4iV8sV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsxwd256_mask, "V8iV8sV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsxwq128_mask, "V2LLiV8sV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsxwq256_mask, "V4LLiV8sV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbw512_mask, "V32sV32cV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbd512_mask, "V16iV16cV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbq512_mask, "V8LLiV16cV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovzxdq512_mask, "V8LLiV8iV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovzxwd512_mask, "V16iV16sV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovzxwq512_mask, "V8LLiV8sV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbw128_mask, "V8sV16cV8sUc","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbw256_mask, "V16sV16cV16sUs","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbd128_mask, "V4iV16cV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbd256_mask, "V8iV16cV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbq128_mask, "V2LLiV16cV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovzxbq256_mask, "V4LLiV16cV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovzxdq128_mask, "V2LLiV4iV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovzxdq256_mask, "V4LLiV4iV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovzxwd128_mask, "V4iV8sV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovzxwd256_mask, "V8iV8sV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovzxwq128_mask, "V2LLiV8sV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovzxwq256_mask, "V4LLiV8sV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_prold512_mask, "V16iV16iIiV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_prolq512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_prold128_mask, "V4iV4iIiV4iUc","","avx512vl")
@@ -1577,65 +1346,27 @@ TARGET_BUILTIN(__builtin_ia32_prorvd128_mask, "V4iV4iV4iV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_prorvd256_mask, "V8iV8iV8iV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_prorvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_prorvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllv32hi_mask, "V32sV32sV32sV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psllw512_mask, "V32sV32sV8sV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psllwi512_mask, "V32sV32sIiV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psllv16hi_mask, "V16sV16sV16sV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllv8hi_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllw128_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllw256_mask, "V16sV16sV8sV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllwi128_mask, "V8sV8sIiV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllwi256_mask, "V16sV16sIiV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllv2di_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllv4di_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllv4si_mask, "V4iV4iV4iV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllv8si_mask, "V8iV8iV8iV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pslldi512_mask, "V16iV16iIiV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psllqi512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pslld128_mask, "V4iV4iV4iV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pslld256_mask, "V8iV8iV4iV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pslldi128_mask, "V4iV4iIiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pslldi256_mask, "V8iV8iIiV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllq256_mask, "V4LLiV4LLiV2LLiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllqi128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllqi256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlv32hi_mask, "V32sV32sV32sV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrlv16hi_mask, "V16sV16sV16sV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlv8hi_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlv2di_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlv4di_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlv4si_mask, "V4iV4iV4iV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlv8si_mask, "V8iV8iV8iV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrldi512_mask, "V16iV16iIiV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlqi512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrld128_mask, "V4iV4iV4iV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrld256_mask, "V8iV8iV4iV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrldi128_mask, "V4iV4iIiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrldi256_mask, "V8iV8iIiV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlq256_mask, "V4LLiV4LLiV2LLiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlqi128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlqi256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrav32hi_mask, "V32sV32sV32sV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrav16hi_mask, "V16sV16sV16sV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrav8hi_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrav4si_mask, "V4iV4iV4iV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrav8si_mask, "V8iV8iV8iV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psravq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psravq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psraw512_mask, "V32sV32sV8sV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrawi512_mask, "V32sV32sIiV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psraw128_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psraw256_mask, "V16sV16sV8sV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrawi128_mask, "V8sV8sIiV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrawi256_mask, "V16sV16sIiV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlw512_mask, "V32sV32sV8sV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrlwi512_mask, "V32sV32sIiV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrlw128_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlw256_mask, "V16sV16sV8sV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlwi128_mask, "V8sV8sIiV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlwi256_mask, "V16sV16sIiV16sUs","","avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psllv32hi, "V32sV32sV32s","","avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psllw512, "V32sV32sV8s","","avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psllwi512, "V32sV32si","","avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psllv16hi, "V16sV16sV16s","","avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psllv8hi, "V8sV8sV8s","","avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pslldi512, "V16iV16ii","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psllqi512, "V8LLiV8LLii","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrlv32hi, "V32sV32sV32s","","avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psrlv16hi, "V16sV16sV16s","","avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psrlv8hi, "V8sV8sV8s","","avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psrldi512, "V16iV16ii","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrlqi512, "V8LLiV8LLii","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrav32hi, "V32sV32sV32s","","avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psrav16hi, "V16sV16sV16s","","avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psrav8hi, "V8sV8sV8s","","avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psravq128, "V2LLiV2LLiV2LLi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psravq256, "V4LLiV4LLiV4LLi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psraw512, "V32sV32sV8s","","avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psrawi512, "V32sV32si","","avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psrlw512, "V32sV32sV8s","","avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psrlwi512, "V32sV32si","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_movdqa32load128_mask, "V4iV4i*V4iUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_movdqa32load256_mask, "V8iV8i*V8iUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_movdqa32load512_mask, "V16iV16iC*V16iUs","","avx512f")
@@ -1653,8 +1384,6 @@ TARGET_BUILTIN(__builtin_ia32_pbroadcastb128_gpr_mask, "V16ccV16cUs","","avx512b
TARGET_BUILTIN(__builtin_ia32_pbroadcastb256_gpr_mask, "V32ccV32cUi","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_pbroadcastd128_gpr_mask, "V4iiV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pbroadcastd256_gpr_mask, "V8iiV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastq128_gpr_mask, "V2LLiULLiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pbroadcastq256_gpr_mask, "V4LLiULLiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
@@ -1707,8 +1436,10 @@ TARGET_BUILTIN(__builtin_ia32_fixupimmps128_maskz, "V4fV4fV4fV4iIiUc","","avx512
TARGET_BUILTIN(__builtin_ia32_fixupimmps256_mask, "V8fV8fV8fV8iIiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_fixupimmps256_maskz, "V8fV8fV8fV8iIiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadapd128_mask, "V2dV2d*V2dUc","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loadsd128_mask, "V8dV8d*V8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_loadapd256_mask, "V4dV4d*V4dUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadaps128_mask, "V4fV4f*V4fUc","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loadss128_mask, "V16fV16f*V16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_loadaps256_mask, "V8fV8f*V8fUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_loaddqudi128_mask, "V2LLiV2LLi*V2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_loaddqudi256_mask, "V4LLiV4LLi*V4LLiUc","","avx512vl")
@@ -1725,8 +1456,10 @@ TARGET_BUILTIN(__builtin_ia32_storedquhi256_mask, "vV16s*V16sUs","","avx512vl,av
TARGET_BUILTIN(__builtin_ia32_storedquqi128_mask, "vV16c*V16cUs","","avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_storedquqi256_mask, "vV32c*V32cUi","","avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_storeapd128_mask, "vV2d*V2dUc","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storesd128_mask, "vV8d*V8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_storeapd256_mask, "vV4d*V4dUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_storeaps128_mask, "vV4f*V4fUc","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storess128_mask, "vV16f*V16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_storeaps256_mask, "vV8f*V8fUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_storedqudi128_mask, "vV2LLi*V2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_storedqudi256_mask, "vV4LLi*V4LLiUc","","avx512vl")
@@ -1744,36 +1477,24 @@ TARGET_BUILTIN(__builtin_ia32_vplzcntd_128_mask, "V4iV4iV4iUc","","avx512cd,avx5
TARGET_BUILTIN(__builtin_ia32_vplzcntd_256_mask, "V8iV8iV8iUc","","avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vplzcntq_128_mask, "V2LLiV2LLiV2LLiUc","","avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vplzcntq_256_mask, "V4LLiV4LLiV4LLiUc","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vcvtsd2si64, "LLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtsd2si32, "iV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi32, "UiV2dIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "ULLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtss2si32, "iV4fIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "LLiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtss2usi32, "UiV4fIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtss2usi64, "ULLiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttsd2si32, "iV2dIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvttsd2si64, "LLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi32, "UiV2dIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi64, "ULLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttss2si32, "iV4fIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvttss2si64, "LLiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttss2usi32, "UiV4fIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvttss2usi64, "ULLiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermi2vard512_mask, "V16iV16iV16iV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermi2varpd512_mask, "V8dV8dV8LLiV8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermi2varps512_mask, "V16fV16fV16iV16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermi2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512_mask, "V8dV8dV8LLiV8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarps512_mask, "V16fV16fV16iV16fUs","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512, "V8dV8dV8LLi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermilvarps512, "V16fV16fV16i","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2vard512_maskz, "V16iV16iV16iV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_maskz, "V8dV8LLiV8dV8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_maskz, "V16fV16iV16fV16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarpd_mask, "V2dV2dV2LLiV2dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarpd256_mask, "V4dV4dV4LLiV4dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarps_mask, "V4fV4fV4iV4fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarps256_mask, "V8fV8fV8iV8fUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_ptestmb512, "ULLiV64cV64cULLi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_ptestmw512, "UiV32sV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_ptestnmb512, "ULLiV64cV64cULLi","","avx512bw")
@@ -1802,28 +1523,24 @@ TARGET_BUILTIN(__builtin_ia32_scalefpd512_mask, "V8dV8dV8dV8dUcIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_scalefps512_mask, "V16fV16fV16fV16fUsIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_scalefsd_round_mask, "V2dV2dV2dV2dUcIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_scalefss_round_mask, "V4fV4fV4fV4fUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psradi512_mask, "V16iV16iIiV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psraqi512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrad128_mask, "V4iV4iV4iV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrad256_mask, "V8iV8iV4iV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psradi128_mask, "V4iV4iIiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psradi256_mask, "V8iV8iIiV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psraq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psraq256_mask, "V4LLiV4LLiV2LLiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psraqi128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psraqi256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pslld512_mask, "V16iV16iV4iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psllq512_mask, "V8LLiV8LLiV2LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psllv16si_mask, "V16iV16iV16iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psllv8di_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrad512_mask, "V16iV16iV4iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psraq512_mask, "V8LLiV8LLiV2LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrav16si_mask, "V16iV16iV16iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrav8di_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrld512_mask, "V16iV16iV4iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlq512_mask, "V8LLiV8LLiV2LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlv16si_mask, "V16iV16iV16iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlv8di_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psradi512, "V16iV16ii","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psraqi512, "V8LLiV8LLii","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psraq128, "V2LLiV2LLiV2LLi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psraq256, "V4LLiV4LLiV2LLi","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psraqi128, "V2LLiV2LLii","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psraqi256, "V4LLiV4LLii","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pslld512, "V16iV16iV4i","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psllq512, "V8LLiV8LLiV2LLi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psllv16si, "V16iV16iV16i","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psllv8di, "V8LLiV8LLiV8LLi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrad512, "V16iV16iV4i","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psraq512, "V8LLiV8LLiV2LLi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrav16si, "V16iV16iV16i","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrav8di, "V8LLiV8LLiV8LLi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrld512, "V16iV16iV4i","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrlq512, "V8LLiV8LLiV2LLi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrlv16si, "V16iV16iV16i","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrlv8di, "V8LLiV8LLiV8LLi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pternlogd512_mask, "V16iV16iV16iV16iIiUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pternlogd512_maskz, "V16iV16iV16iV16iIiUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pternlogq512_mask, "V8LLiV8LLiV8LLiV8LLiIiUc","","avx512f")
@@ -1996,28 +1713,6 @@ TARGET_BUILTIN(__builtin_ia32_pmovqw128_mask, "V8sV2LLiV8sUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovqw128mem_mask, "vV8s*V2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovqw256_mask, "V8sV4LLiV8sUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovqw256mem_mask, "vV8s*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_extractf32x8_mask, "V8fV16fIiV8fUc","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_extractf64x2_512_mask, "V2dV8dIiV2dUc","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_extracti32x8_mask, "V8iV16iIiV8iUc","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_extracti64x2_512_mask, "V2LLiV8LLiIiV2LLiUc","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_extracti32x4_mask, "V4iV16iIiV4iUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_extracti64x4_mask, "V4LLiV8LLiIiV4LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_extractf64x2_256_mask, "V2dV4dIiV2dUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_extracti64x2_256_mask, "V2LLiV4LLiIiV2LLiUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_extractf32x4_256_mask, "V4fV8fIiV4fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_extracti32x4_256_mask, "V4iV8iIiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_insertf32x8_mask, "V16fV16fV8fIiV16fUs","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_insertf64x2_512_mask, "V8dV8dV2dIiV8dUc","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_inserti32x8_mask, "V16iV16iV8iIiV16iUs","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_inserti64x2_512_mask, "V8LLiV8LLiV2LLiIiV8LLiUc","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_insertf64x4_mask, "V8dV8dV4dIiV8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_inserti64x4_mask, "V8LLiV8LLiV4LLiIiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_insertf64x2_256_mask, "V4dV4dV2dIiV4dUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_inserti64x2_256_mask, "V4LLiV4LLiV2LLiIiV4LLiUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_insertf32x4_256_mask, "V8fV8fV4fIiV8fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_inserti32x4_256_mask, "V8iV8iV4iIiV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_insertf32x4_mask, "V16fV16fV4fIiV16fUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_inserti32x4_mask, "V16iV16iV4iIiV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_getmantpd128_mask, "V2dV2diV2dUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_getmantpd256_mask, "V4dV4diV4dUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_getmantps128_mask, "V4fV4fiV4fUc","","avx512vl")
@@ -2032,6 +1727,10 @@ TARGET_BUILTIN(__builtin_ia32_vfmaddss3_mask3, "V4fV4fV4fV4fUcIi", "", "avx512f"
TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_maskz, "V2dV2dV2dV2dUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask3, "V2dV2dV2dV2dUcIi", "", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmsubsd3_mask3, "V2dV2dV2dV2dUcIi", "", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmsubss3_mask3, "V4fV4fV4fV4fUcIi", "", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfnmsubsd3_mask3, "V2dV2dV2dV2dUcIi", "", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfnmsubss3_mask3, "V4fV4fV4fV4fUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_permvarhi512_mask, "V32sV32sV32sV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_permvardf512_mask, "V8dV8dV8LLiV8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_permvardi512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
@@ -2064,8 +1763,6 @@ TARGET_BUILTIN(__builtin_ia32_kxnorhi, "UsUsUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_kxorhi, "UsUsUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_movntdqa512, "V8LLiV8LLi*","","avx512f")
TARGET_BUILTIN(__builtin_ia32_palignr512_mask, "V64cV64cV64cIiV64cULLi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_palignr128_mask, "V16cV16cV16cIiV16cUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_palignr256_mask, "V32cV32cV32cIiV32cUi","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_dbpsadbw128_mask, "V8sV16cV16cIiV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_dbpsadbw256_mask, "V16sV32cV32cIiV16sUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_dbpsadbw512_mask, "V32sV64cV64cIiV32sUi","","avx512bw")
@@ -2097,14 +1794,10 @@ TARGET_BUILTIN(__builtin_ia32_cvtw2mask512, "UiV32s","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_cvtw2mask128, "UcV8s","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtw2mask256, "UsV16s","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtsd2ss_round_mask, "V4fV4fV2dV4fUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtsi2sd64, "V2dV2dLLiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtsi2ss32, "V4fV4fiIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fLLiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtss2sd_round_mask, "V2dV2dV4fV2dUcIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2sd32, "V2dV2dUi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dULLiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2ss32, "V4fV4fUiIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fULLiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512_mask, "V64cV64cV64cV64cULLi","","avx512vbmi")
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128_mask, "V16cV16cV16cV16cUs","","avx512vbmi,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256_mask, "V32cV32cV32cV32cUi","","avx512vbmi,avx512vl")
@@ -2133,5 +1826,21 @@ TARGET_BUILTIN(__builtin_ia32_selectpd_512, "V8dUcV8dV8d", "", "")
TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx")
TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx")
+// MSVC
+TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_ReadBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_WriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__emul, "LLiii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
#undef BUILTIN
#undef TARGET_BUILTIN
+#undef TARGET_HEADER_BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86_64.def b/include/clang/Basic/BuiltinsX86_64.def
new file mode 100644
index 000000000000..d38f522c3812
--- /dev/null
+++ b/include/clang/Basic/BuiltinsX86_64.def
@@ -0,0 +1,90 @@
+//===--- BuiltinsX86_64.def - X86-64 Builtin function database --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the X86-64-specific builtin function database. Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN)
+# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+TARGET_HEADER_BUILTIN(_BitScanForward64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_mul128, "LLiLLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_umul128, "ULLiULLiULLiULLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "")
+TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "")
+TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse")
+TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "", "sse")
+TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "LLiV2d", "", "sse2")
+TARGET_BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_rdfsbase64, "ULLi", "", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_fxrstor64, "vv*", "", "fxsr")
+TARGET_BUILTIN(__builtin_ia32_fxsave64, "vv*", "", "fxsr")
+TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "", "xsave")
+TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "", "xsave")
+TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "", "xsaveopt")
+TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "", "xsaves")
+TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec")
+TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "", "xsaves")
+TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx")
+TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "")
+TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "", "")
+TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "", "rdseed")
+TARGET_BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "", "bmi")
+TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "", "bmi2")
+TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "", "bmi2")
+TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "", "bmi2")
+TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "", "tbm")
+TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_gpr_mask, "V8LLiLLiV8LLiUc", "", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pbroadcastq128_gpr_mask, "V2LLiULLiV2LLiUc","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pbroadcastq256_gpr_mask, "V4LLiULLiV4LLiUc","","avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtsd2si64, "LLiV2dIi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "ULLiV2dIi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "LLiV4fIi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtss2usi64, "ULLiV4fIi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvttsd2si64, "LLiV2dIi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi64, "ULLiV2dIi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvttss2si64, "LLiV4fIi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvttss2usi64, "ULLiV4fIi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtsi2sd64, "V2dV2dLLiIi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fLLiIi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dULLiIi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fULLiIi","","avx512f")
+
+#undef BUILTIN
+#undef TARGET_BUILTIN
+#undef TARGET_HEADER_BUILTIN
diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td
index 4f7bbc078d98..7b581d3eec0f 100644
--- a/include/clang/Basic/DeclNodes.td
+++ b/include/clang/Basic/DeclNodes.td
@@ -37,6 +37,7 @@ def Named : Decl<1>;
def EnumConstant : DDecl<Value>;
def UnresolvedUsingValue : DDecl<Value>;
def IndirectField : DDecl<Value>;
+ def Binding : DDecl<Value>;
def OMPDeclareReduction : DDecl<Value>, DeclContext;
def Declarator : DDecl<Value, 1>;
def Field : DDecl<Declarator>;
@@ -54,6 +55,7 @@ def Named : Decl<1>;
: DDecl<VarTemplateSpecialization>;
def ImplicitParam : DDecl<Var>;
def ParmVar : DDecl<Var>;
+ def Decomposition : DDecl<Var>;
def OMPCapturedExpr : DDecl<Var>;
def NonTypeTemplateParm : DDecl<Declarator>;
def Template : DDecl<Named, 1>;
@@ -65,6 +67,7 @@ def Named : Decl<1>;
def TemplateTemplateParm : DDecl<Template>;
def BuiltinTemplate : DDecl<Template>;
def Using : DDecl<Named>;
+ def UsingPack : DDecl<Named>;
def UsingShadow : DDecl<Named>;
def ConstructorUsingShadow : DDecl<UsingShadow>;
def ObjCMethod : DDecl<Named>, DeclContext;
@@ -78,6 +81,7 @@ def Named : Decl<1>;
def ObjCProperty : DDecl<Named>;
def ObjCCompatibleAlias : DDecl<Named>;
def LinkageSpec : Decl, DeclContext;
+def Export : Decl, DeclContext;
def ObjCPropertyImpl : Decl;
def FileScopeAsm : Decl;
def AccessSpec : Decl;
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 085faeae4834..b83ef4d44b24 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -23,22 +23,33 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
#include <list>
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <utility>
#include <vector>
namespace clang {
- class DeclContext;
- class DiagnosticBuilder;
- class DiagnosticConsumer;
- class DiagnosticErrorTrap;
- class DiagnosticOptions;
- class IdentifierInfo;
- class LangOptions;
- class Preprocessor;
- class StoredDiagnostic;
- namespace tok {
+
+class DeclContext;
+class DiagnosticBuilder;
+class DiagnosticConsumer;
+class IdentifierInfo;
+class LangOptions;
+class Preprocessor;
+class StoredDiagnostic;
+
+namespace tok {
+
enum TokenKind : unsigned short;
- }
+
+} // end namespace tok
/// \brief Annotates a diagnostic with some code that should be
/// inserted, removed, or replaced to fix the problem.
@@ -133,9 +144,6 @@ public:
/// the user. DiagnosticsEngine is tied to one translation unit and one
/// SourceManager.
class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
- DiagnosticsEngine(const DiagnosticsEngine &) = delete;
- void operator=(const DiagnosticsEngine &) = delete;
-
public:
/// \brief The level of the diagnostic, after it has been through mapping.
enum Level {
@@ -344,11 +352,12 @@ private:
std::string FlagValue;
public:
- explicit DiagnosticsEngine(
- const IntrusiveRefCntPtr<DiagnosticIDs> &Diags,
- DiagnosticOptions *DiagOpts,
- DiagnosticConsumer *client = nullptr,
- bool ShouldOwnClient = true);
+ explicit DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> Diags,
+ DiagnosticOptions *DiagOpts,
+ DiagnosticConsumer *client = nullptr,
+ bool ShouldOwnClient = true);
+ DiagnosticsEngine(const DiagnosticsEngine &) = delete;
+ DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete;
~DiagnosticsEngine();
const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
@@ -885,7 +894,6 @@ class DiagnosticBuilder {
/// call to ForceEmit.
mutable bool IsForceEmit = false;
- void operator=(const DiagnosticBuilder &) = delete;
friend class DiagnosticsEngine;
DiagnosticBuilder() = default;
@@ -950,16 +958,18 @@ public:
NumArgs = D.NumArgs;
}
- /// \brief Retrieve an empty diagnostic builder.
- static DiagnosticBuilder getEmpty() {
- return DiagnosticBuilder();
- }
+ DiagnosticBuilder &operator=(const DiagnosticBuilder &) = delete;
/// \brief Emits the diagnostic.
~DiagnosticBuilder() {
Emit();
}
-
+
+ /// \brief Retrieve an empty diagnostic builder.
+ static DiagnosticBuilder getEmpty() {
+ return DiagnosticBuilder();
+ }
+
/// \brief Forces the diagnostic to be emitted.
const DiagnosticBuilder &setForceEmit() const {
IsForceEmit = true;
@@ -1144,6 +1154,7 @@ inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
class Diagnostic {
const DiagnosticsEngine *DiagObj;
StringRef StoredDiagMessage;
+
public:
explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {}
Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage)
@@ -1280,7 +1291,7 @@ public:
ArrayRef<FixItHint> Fixits);
/// \brief Evaluates true when this object stores a diagnostic.
- explicit operator bool() const { return Message.size() > 0; }
+ explicit operator bool() const { return !Message.empty(); }
unsigned getID() const { return ID; }
DiagnosticsEngine::Level getLevel() const { return Level; }
@@ -1298,7 +1309,6 @@ public:
return llvm::makeArrayRef(Ranges);
}
-
typedef std::vector<FixItHint>::const_iterator fixit_iterator;
fixit_iterator fixit_begin() const { return FixIts.begin(); }
fixit_iterator fixit_end() const { return FixIts.end(); }
@@ -1313,18 +1323,18 @@ public:
/// formats and prints fully processed diagnostics.
class DiagnosticConsumer {
protected:
- unsigned NumWarnings; ///< Number of warnings reported
- unsigned NumErrors; ///< Number of errors reported
+ unsigned NumWarnings = 0; ///< Number of warnings reported
+ unsigned NumErrors = 0; ///< Number of errors reported
public:
- DiagnosticConsumer() : NumWarnings(0), NumErrors(0) { }
+ DiagnosticConsumer() = default;
+
+ virtual ~DiagnosticConsumer();
unsigned getNumErrors() const { return NumErrors; }
unsigned getNumWarnings() const { return NumWarnings; }
virtual void clear() { NumWarnings = NumErrors = 0; }
- virtual ~DiagnosticConsumer();
-
/// \brief Callback to inform the diagnostic client that processing
/// of a source file is beginning.
///
@@ -1369,6 +1379,7 @@ public:
/// \brief A diagnostic client that ignores all diagnostics.
class IgnoringDiagConsumer : public DiagnosticConsumer {
virtual void anchor();
+
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const Diagnostic &Info) override {
// Just ignore it.
@@ -1416,6 +1427,6 @@ void ProcessWarningOptions(DiagnosticsEngine &Diags,
const DiagnosticOptions &Opts,
bool ReportDiags = true);
-} // end namespace clang
+} // end namespace clang
-#endif
+#endif // LLVM_CLANG_BASIC_DIAGNOSTIC_H
diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td
index 48cbf09419b3..39da0060ddbd 100644
--- a/include/clang/Basic/Diagnostic.td
+++ b/include/clang/Basic/Diagnostic.td
@@ -48,10 +48,13 @@ class DiagGroup<string Name, list<DiagGroup> subgroups = []> {
string GroupName = Name;
list<DiagGroup> SubGroups = subgroups;
string CategoryName = "";
+ code Documentation = [{}];
}
class InGroup<DiagGroup G> { DiagGroup Group = G; }
//class IsGroup<string Name> { DiagGroup Group = DiagGroup<Name>; }
+// This defines documentation for diagnostic groups.
+include "DiagnosticDocs.td"
// This defines all of the named diagnostic categories.
include "DiagnosticCategories.td"
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index 039888ba6631..03ed8aa74597 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -158,6 +158,12 @@ def warn_integer_constant_overflow : Warning<
"overflow in expression; result is %0 with type %1">,
InGroup<DiagGroup<"integer-overflow">>;
+// This is a temporary diagnostic, and shall be removed once our
+// implementation is complete, and like the preceding constexpr notes belongs
+// in Sema.
+def note_unimplemented_constexpr_lambda_feature_ast : Note<
+ "unimplemented constexpr lambda feature: %0 (coming soon!)">;
+
// inline asm related.
let CategoryName = "Inline Assembly Issue" in {
def err_asm_invalid_escape : Error<
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 1c3bbfc11840..e8180eb1db48 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -94,6 +94,8 @@ def err_module_lock_timeout : Error<
"timed out waiting to acquire lock file for module '%0'">, DefaultFatal;
def err_module_cycle : Error<"cyclic dependency in module '%0': %1">,
DefaultFatal;
+def err_module_prebuilt : Error<
+ "error in loading module '%0' from prebuilt module path">, DefaultFatal;
def note_pragma_entered_here : Note<"#pragma entered here">;
def note_decl_hiding_tag_type : Note<
"%1 %0 is hidden by a non-type declaration of %0 here">;
@@ -188,6 +190,8 @@ def err_target_unsupported_fpmath : Error<
"the '%0' unit is not supported with this instruction set">;
def err_target_unsupported_unaligned : Error<
"the %0 sub-architecture does not support unaligned accesses">;
+def err_target_unsupported_execute_only : Error<
+ "execute only is not supported for the %0 sub-architecture">;
def err_opt_not_valid_with_opt : Error<
"option '%0' cannot be specified with '%1'">;
diff --git a/include/clang/Basic/DiagnosticDocs.td b/include/clang/Basic/DiagnosticDocs.td
new file mode 100644
index 000000000000..0a3e1ce5f2f2
--- /dev/null
+++ b/include/clang/Basic/DiagnosticDocs.td
@@ -0,0 +1,84 @@
+//==--- DiagnosticDocs.td - Diagnostic documentation ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+def GlobalDocumentation {
+ code Intro =[{..
+ -------------------------------------------------------------------
+ NOTE: This file is automatically generated by running clang-tblgen
+ -gen-diag-docs. Do not edit this file by hand!!
+ -------------------------------------------------------------------
+
+.. Add custom CSS to output. FIXME: This should be put into <head> rather
+ than the start of <body>.
+.. raw:: html
+
+ <style>
+ table.docutils {
+ width: 1px;
+ }
+ table.docutils td {
+ border: none;
+ padding: 0 0 0 0.2em;
+ vertical-align: middle;
+ white-space: nowrap;
+ width: 1px;
+ font-family: monospace;
+ }
+ table.docutils tr + tr {
+ border-top: 0.2em solid #aaa;
+ }
+ .error {
+ font-family: monospace;
+ font-weight: bold;
+ color: #c00;
+ }
+ .warning {
+ font-family: monospace;
+ font-weight: bold;
+ color: #80a;
+ }
+ .remark {
+ font-family: monospace;
+ font-weight: bold;
+ color: #00c;
+ }
+ .diagtext {
+ font-family: monospace;
+ font-weight: bold;
+ }
+ </style>
+
+.. FIXME: rST doesn't support formatting this, so we format all <td> elements
+ as monospace font face instead.
+.. |nbsp| unicode:: 0xA0
+ :trim:
+
+.. Roles generated by clang-tblgen.
+.. role:: error
+.. role:: warning
+.. role:: remark
+.. role:: diagtext
+.. role:: placeholder(emphasis)
+
+=========================
+Diagnostic flags in Clang
+=========================
+.. contents::
+ :local:
+
+Introduction
+============
+
+This page lists the diagnostic flags currently supported by Clang.
+
+Diagnostic flags
+================
+}];
+}
+
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 0a9b34827dc2..2fcd3a5a2fba 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -26,10 +26,14 @@ def err_drv_cuda_bad_gpu_arch : Error<"Unsupported CUDA gpu architecture: %0">;
def err_drv_no_cuda_installation : Error<
"cannot find CUDA installation. Provide its path via --cuda-path, or pass "
"-nocudainc to build without CUDA includes.">;
+def err_drv_no_cuda_libdevice : Error<
+ "cannot find libdevice for %0. Provide path to different CUDA installation "
+ "via --cuda-path, or pass -nocudalib to build without linking with libdevice.">;
def err_drv_cuda_version_too_low : Error<
"GPU arch %1 requires CUDA version at least %3, but installation at %0 is %2. "
"Use --cuda-path to specify a different CUDA install, or pass "
"--no-cuda-version-check.">;
+def err_drv_cuda_nvptx_host : Error<"unsupported use of NVPTX for host compilation.">;
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<
@@ -83,6 +87,8 @@ def err_drv_clang_unsupported_opt_cxx_darwin_i386 : Error<
"the clang compiler does not support '%0' for C++ on Darwin/i386">;
def err_drv_command_failed : Error<
"%0 command failed with exit code %1 (use -v to see invocation)">;
+def err_drv_compilationdatabase : Error<
+ "compilation database '%0' could not be opened: %1">;
def err_drv_command_signalled : Error<
"%0 command failed due to signal (use -v to see invocation)">;
def err_drv_force_crash : Error<
@@ -131,8 +137,6 @@ def err_drv_preamble_format : Error<
"incorrect format for -preamble-bytes=N,END">;
def err_drv_conflicting_deployment_targets : Error<
"conflicting deployment targets, both '%0' and '%1' are present in environment">;
-def err_drv_objc_gc_arr : Error<
- "cannot specify both '-fobjc-arc' and '%0'">;
def err_arc_unsupported_on_runtime : Error<
"-fobjc-arc is not supported on platforms using the legacy runtime">;
def err_arc_unsupported_on_toolchain : Error< // feel free to generalize this
@@ -155,6 +159,11 @@ def err_drv_omp_host_ir_file_not_found : Error<
"The provided host compiler IR file '%0' is required to generate code for OpenMP target regions but cannot be found.">;
def err_drv_omp_host_target_not_supported : Error<
"The target '%0' is not a supported OpenMP host target.">;
+def err_drv_expecting_fopenmp_with_fopenmp_targets : Error<
+ "The option -fopenmp-targets must be used in conjunction with a -fopenmp option compatible with offloading, please use -fopenmp=libomp or -fopenmp=libiomp5.">;
+def warn_drv_omp_offload_target_duplicate : Warning<
+ "The OpenMP offloading target '%0' is similar to target '%1' already specified - will be ignored.">,
+ InGroup<OpenMPTarget>;
def err_drv_bitcode_unsupported_on_toolchain : Error<
"-fembed-bitcode is not supported on versions of iOS prior to 6.0">;
@@ -163,6 +172,9 @@ def warn_drv_optimization_value : Warning<"optimization level '%0' is not suppor
InGroup<InvalidCommandLineArgument>;
def warn_ignored_gcc_optimization : Warning<"optimization flag '%0' is not supported">,
InGroup<IgnoredOptimizationArgument>;
+def warn_drv_unsupported_opt_for_target : Warning<
+ "optimization flag '%0' is not supported for target '%1'">,
+ 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<
@@ -180,6 +192,9 @@ def warn_drv_unused_argument : Warning<
def warn_drv_empty_joined_argument : Warning<
"joined argument expects additional value: '%0'">,
InGroup<UnusedCommandLineArgument>;
+def warn_drv_fdiagnostics_show_hotness_requires_pgo : Warning<
+ "argument '-fdiagnostics-show-hotness' requires profile-guided optimization information">,
+ InGroup<UnusedCommandLineArgument>;
def warn_drv_clang_unsupported : Warning<
"the clang compiler does not support '%0'">;
def warn_drv_deprecated_arg : Warning<
@@ -194,8 +209,6 @@ def warn_drv_overriding_flag_option : Warning<
def warn_drv_treating_input_as_cxx : Warning<
"treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
InGroup<Deprecated>;
-def warn_drv_objc_gc_unsupported : Warning<
- "Objective-C garbage collection is not supported on this platform, ignoring '%0'">;
def warn_drv_pch_not_first_include : Warning<
"precompiled header '%0' was ignored because '%1' is not first '-include'">;
def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">,
@@ -234,6 +247,11 @@ def err_test_module_file_extension_format : Error<
def warn_drv_invoking_fallback : Warning<"falling back to %0">,
InGroup<Fallback>;
+def err_drv_ropi_rwpi_incompatible_with_pic : Error<
+ "embedded and GOT-based position independence are incompatible">;
+def err_drv_ropi_incompatible_with_cxx : Error<
+ "ROPI is not compatible with c++">;
+
def warn_target_unsupported_nan2008 : Warning<
"ignoring '-mnan=2008' option because the '%0' architecture does not support it">,
InGroup<UnsupportedNan>;
@@ -257,4 +275,6 @@ def warn_drv_ps4_sdk_dir : Warning<
InGroup<InvalidOrNonExistentDirectory>;
def err_drv_unsupported_linker : Error<"unsupported value '%0' for -linker option">;
+def err_drv_defsym_invalid_format : Error<"defsym must be of the form: sym=value: %0">;
+def err_drv_defsym_invalid_symval : Error<"Value is not an integer: %0">;
}
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 2aa8f103500d..1267f8d09f58 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -107,10 +107,15 @@ def warn_fe_cc_print_header_failure : Warning<
"unable to open CC_PRINT_HEADERS file: %0 (using stderr)">;
def warn_fe_cc_log_diagnostics_failure : Warning<
"unable to open CC_LOG_DIAGNOSTICS file: %0 (using stderr)">;
+def warn_fe_unable_to_open_stats_file : Warning<
+ "unable to open statistics output file '%0': '%1'">,
+ InGroup<DiagGroup<"unable-to-open-stats-file">>;
def err_fe_no_pch_in_dir : Error<
"no suitable precompiled header file found in directory '%0'">;
def err_fe_action_not_available : Error<
"action %0 not compiled in">;
+def err_fe_invalid_alignment : Error<
+ "invalid value '%1' in '%0'; alignment must be a power of 2">;
def warn_fe_serialized_diag_merge_failure : Warning<
"unable to merge a subprocess's serialized diagnostics">,
@@ -174,6 +179,8 @@ def warn_incompatible_analyzer_plugin_api : Warning<
def note_incompatible_analyzer_plugin_api : Note<
"current API version is '%0', but plugin was compiled with version '%1'">;
+def err_module_interface_requires_modules_ts : Error<
+ "module interface compilation requires '-fmodules-ts'">;
def warn_module_config_mismatch : Warning<
"module file %0 cannot be loaded due to a configuration mismatch with the current "
"compilation">, InGroup<DiagGroup<"module-file-config-mismatch">>, DefaultError;
@@ -217,4 +224,4 @@ def err_invalid_vfs_overlay : Error<
def warn_option_invalid_ocl_version : Warning<
"OpenCL version %0 does not support the option '%1'">, InGroup<Deprecated>;
-} \ No newline at end of file
+}
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 72dfedbbaef0..ba82b36cea31 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -62,7 +62,6 @@ def NullConversion : DiagGroup<"null-conversion">;
def ImplicitConversionFloatingPointToBool :
DiagGroup<"implicit-conversion-floating-point-to-bool">;
def ObjCLiteralConversion : DiagGroup<"objc-literal-conversion">;
-def BadArrayNewLength : DiagGroup<"bad-array-new-length">;
def MacroRedefined : DiagGroup<"macro-redefined">;
def BuiltinMacroRedefined : DiagGroup<"builtin-macro-redefined">;
def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
@@ -95,8 +94,11 @@ def CXX11CompatDeprecatedWritableStr :
def DeprecatedAttributes : DiagGroup<"deprecated-attributes">;
def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
def UnavailableDeclarations : DiagGroup<"unavailable-declarations">;
-def PartialAvailability : DiagGroup<"partial-availability">;
def UnguardedAvailability : DiagGroup<"unguarded-availability">;
+// partial-availability is an alias of unguarded-availability.
+def : DiagGroup<"partial-availability", [UnguardedAvailability]>;
+def DeprecatedDynamicExceptionSpec
+ : DiagGroup<"deprecated-dynamic-exception-spec">;
def DeprecatedImplementations :DiagGroup<"deprecated-implementations">;
def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">;
def DeprecatedRegister : DiagGroup<"deprecated-register">;
@@ -105,15 +107,20 @@ def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
// FIXME: Why is DeprecatedImplementations not in this group?
def Deprecated : DiagGroup<"deprecated", [DeprecatedAttributes,
DeprecatedDeclarations,
+ DeprecatedDynamicExceptionSpec,
DeprecatedIncrementBool,
DeprecatedRegister,
DeprecatedWritableStr]>,
DiagCategory<"Deprecations">;
+def DynamicExceptionSpec
+ : DiagGroup<"dynamic-exception-spec", [DeprecatedDynamicExceptionSpec]>;
+
def LibLTO : DiagGroup<"liblto">;
def : DiagGroup<"disabled-optimization">;
def : DiagGroup<"discard-qual">;
-def : DiagGroup<"div-by-zero">;
+def DivZero : DiagGroup<"division-by-zero">;
+def : DiagGroup<"div-by-zero", [DivZero]>;
def DocumentationHTML : DiagGroup<"documentation-html">;
def DocumentationUnknownCommand : DiagGroup<"documentation-unknown-command">;
@@ -200,8 +207,6 @@ def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic",
def CXX1zCompat : DiagGroup<"c++1z-compat", [DeprecatedRegister,
DeprecatedIncrementBool]>;
-def : DiagGroup<"effc++">;
-def DivZero : DiagGroup<"division-by-zero">;
def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">;
def FourByteMultiChar : DiagGroup<"four-char-constants">;
@@ -225,9 +230,12 @@ def GNUIncludeNext : DiagGroup<"gnu-include-next">;
def IncompatibleMSStruct : DiagGroup<"incompatible-ms-struct">;
def IncompatiblePointerTypesDiscardsQualifiers
: DiagGroup<"incompatible-pointer-types-discards-qualifiers">;
+def IncompatibleFunctionPointerTypes
+ : DiagGroup<"incompatible-function-pointer-types">;
def IncompatiblePointerTypes
: DiagGroup<"incompatible-pointer-types",
- [IncompatiblePointerTypesDiscardsQualifiers]>;
+ [IncompatiblePointerTypesDiscardsQualifiers,
+ IncompatibleFunctionPointerTypes]>;
def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">;
def NonModularIncludeInFrameworkModule
: DiagGroup<"non-modular-include-in-framework-module">;
@@ -235,6 +243,7 @@ def NonModularIncludeInModule : DiagGroup<"non-modular-include-in-module",
[NonModularIncludeInFrameworkModule]>;
def IncompleteModule : DiagGroup<"incomplete-module",
[IncompleteUmbrella, NonModularIncludeInModule]>;
+def PrivateModule : DiagGroup<"private-module">;
def CXX11InlineNamespace : DiagGroup<"c++11-inline-namespace">;
def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
@@ -254,6 +263,7 @@ def LoopAnalysis : DiagGroup<"loop-analysis", [ForLoopAnalysis,
def MalformedWarningCheck : DiagGroup<"malformed-warning-check">;
def Main : DiagGroup<"main">;
def MainReturnType : DiagGroup<"main-return-type">;
+def MaxUnsignedZero : DiagGroup<"max-unsigned-zero">;
def MissingBraces : DiagGroup<"missing-braces">;
def MissingDeclarations: DiagGroup<"missing-declarations">;
def : DiagGroup<"missing-format-attribute">;
@@ -275,8 +285,11 @@ def ModuleFileExtension : DiagGroup<"module-file-extension">;
def NewlineEOF : DiagGroup<"newline-eof">;
def Nullability : DiagGroup<"nullability">;
def NullabilityDeclSpec : DiagGroup<"nullability-declspec">;
+def NullabilityInferredOnNestedType : DiagGroup<"nullability-inferred-on-nested-type">;
def NullableToNonNullConversion : DiagGroup<"nullable-to-nonnull-conversion">;
-def NullabilityCompleteness : DiagGroup<"nullability-completeness">;
+def NullabilityCompletenessOnArrays : DiagGroup<"nullability-completeness-on-arrays">;
+def NullabilityCompleteness : DiagGroup<"nullability-completeness",
+ [NullabilityCompletenessOnArrays]>;
def NullArithmetic : DiagGroup<"null-arithmetic">;
def NullCharacter : DiagGroup<"null-character">;
def NullDereference : DiagGroup<"null-dereference">;
@@ -286,6 +299,7 @@ def NonPODVarargs : DiagGroup<"non-pod-varargs">;
def ClassVarargs : DiagGroup<"class-varargs", [NonPODVarargs]>;
def : DiagGroup<"nonportable-cfstrings">;
def NonVirtualDtor : DiagGroup<"non-virtual-dtor">;
+def : DiagGroup<"effc++", [NonVirtualDtor]>;
def OveralignedType : DiagGroup<"over-aligned">;
def OldStyleCast : DiagGroup<"old-style-cast">;
def : DiagGroup<"old-style-definition">;
@@ -313,6 +327,7 @@ def ObjCRootClass : DiagGroup<"objc-root-class">;
def ObjCPointerIntrospectPerformSelector : DiagGroup<"deprecated-objc-pointer-introspection-performSelector">;
def ObjCPointerIntrospect : DiagGroup<"deprecated-objc-pointer-introspection", [ObjCPointerIntrospectPerformSelector]>;
def ObjCMultipleMethodNames : DiagGroup<"objc-multiple-method-names">;
+def OpenCLUnsupportedRGBA: DiagGroup<"opencl-unsupported-rgba">;
def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
def Packed : DiagGroup<"packed">;
@@ -343,11 +358,15 @@ def MissingMethodReturnType : DiagGroup<"missing-method-return-type">;
def ShadowFieldInConstructorModified : DiagGroup<"shadow-field-in-constructor-modified">;
def ShadowFieldInConstructor : DiagGroup<"shadow-field-in-constructor",
[ShadowFieldInConstructorModified]>;
+def ShadowIvar : DiagGroup<"shadow-ivar">;
+def ShadowUncapturedLocal : DiagGroup<"shadow-uncaptured-local">;
// -Wshadow-all is a catch-all for all shadowing. -Wshadow is just the
// shadowing that we think is unsafe.
-def Shadow : DiagGroup<"shadow", [ShadowFieldInConstructorModified]>;
-def ShadowAll : DiagGroup<"shadow-all", [Shadow, ShadowFieldInConstructor]>;
+def Shadow : DiagGroup<"shadow", [ShadowFieldInConstructorModified,
+ ShadowIvar]>;
+def ShadowAll : DiagGroup<"shadow-all", [Shadow, ShadowFieldInConstructor,
+ ShadowUncapturedLocal]>;
def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
def : DiagGroup<"sign-promo">;
@@ -432,8 +451,9 @@ def UninitializedSometimes : DiagGroup<"sometimes-uninitialized">;
def UninitializedStaticSelfInit : DiagGroup<"static-self-init">;
def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes,
UninitializedStaticSelfInit]>;
+def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
-def IgnoredPragmas : DiagGroup<"ignored-pragmas">;
+def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>;
def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>;
def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
@@ -491,6 +511,7 @@ def AutomaticReferenceCounting : DiagGroup<"arc",
def ARCRepeatedUseOfWeakMaybe : DiagGroup<"arc-maybe-repeated-use-of-weak">;
def ARCRepeatedUseOfWeak : DiagGroup<"arc-repeated-use-of-weak",
[ARCRepeatedUseOfWeakMaybe]>;
+def BlockCaptureAutoReleasing : DiagGroup<"block-capture-autoreleasing">;
def ObjCBridge : DiagGroup<"bridge-cast">;
def DeallocInCategory:DiagGroup<"dealloc-in-category">;
@@ -530,6 +551,7 @@ def GCCWriteStrings : DiagGroup<"write-strings" , [WritableStrings]>;
def CharSubscript : DiagGroup<"char-subscripts">;
def LargeByValueCopy : DiagGroup<"large-by-value-copy">;
def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
+def SignedEnumBitfield : DiagGroup<"signed-enum-bitfield">;
// Unreachable code warning groups.
//
@@ -614,6 +636,8 @@ def Format2 : DiagGroup<"format=2",
def TypeSafety : DiagGroup<"type-safety">;
+def IncompatibleExceptionSpec : DiagGroup<"incompatible-exception-spec">;
+
def IntToVoidPointerCast : DiagGroup<"int-to-void-pointer-cast">;
def IntToPointerCast : DiagGroup<"int-to-pointer-cast",
[IntToVoidPointerCast]>;
@@ -830,8 +854,9 @@ def ObjCLiteralComparison : DiagGroup<"objc-literal-compare", [
// Inline ASM warnings.
def ASMOperandWidths : DiagGroup<"asm-operand-widths">;
+def ASMIgnoredQualifier : DiagGroup<"asm-ignored-qualifier">;
def ASM : DiagGroup<"asm", [
- ASMOperandWidths
+ ASMOperandWidths, ASMIgnoredQualifier
]>;
// OpenMP warnings.
@@ -872,3 +897,7 @@ def InvalidOrNonExistentDirectory : DiagGroup<"invalid-or-nonexistent-directory"
def OptionIgnored : DiagGroup<"option-ignored">;
def UnknownArgument : DiagGroup<"unknown-argument">;
+
+// A warning group for warnings about code that clang accepts when
+// compiling OpenCL C/C++ but which is not compatible with the SPIR spec.
+def SpirCompat : DiagGroup<"spir-compat">;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 604d51db1ffe..7f7022b49e3d 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -183,7 +183,7 @@ def ext_hex_constant_invalid : Extension<
def ext_hex_literal_invalid : Extension<
"hexadecimal floating literals are a C++1z feature">, InGroup<CXX1z>;
def warn_cxx1z_hex_literal : Warning<
- "hexidecimal floating literals are incompatible with "
+ "hexadecimal floating literals are incompatible with "
"C++ standards before C++1z">,
InGroup<CXXPre1zCompatPedantic>, DefaultIgnore;
def ext_binary_literal : Extension<
@@ -642,6 +642,11 @@ def err_mmap_expected_feature : Error<"expected a feature name">;
def err_mmap_expected_attribute : Error<"expected an attribute name">;
def warn_mmap_unknown_attribute : Warning<"unknown attribute '%0'">,
InGroup<IgnoredAttributes>;
+def warn_mmap_mismatched_top_level_private : Warning<
+ "top-level module '%0' in private module map, expected a submodule of '%1'">,
+ InGroup<PrivateModule>;
+def note_mmap_rename_top_level_private_as_submodule : Note<
+ "make '%0' a submodule of '%1' to ensure it can be found by name">;
def warn_auto_module_import : Warning<
"treating #%select{include|import|include_next|__include_macros}0 as an "
@@ -659,10 +664,10 @@ def warn_use_of_private_header_outside_module : Warning<
def err_undeclared_use_of_module : Error<
"module %0 does not depend on a module exporting '%1'">;
def warn_non_modular_include_in_framework_module : Warning<
- "include of non-modular header inside framework module '%0'">,
+ "include of non-modular header inside framework module '%0': '%1'">,
InGroup<NonModularIncludeInFrameworkModule>, DefaultIgnore;
def warn_non_modular_include_in_module : Warning<
- "include of non-modular header inside module '%0'">,
+ "include of non-modular header inside module '%0': '%1'">,
InGroup<NonModularIncludeInModule>, DefaultIgnore;
def warn_module_conflict : Warning<
"module '%0' conflicts with already-imported module '%1': %2">,
diff --git a/include/clang/Basic/DiagnosticOptions.def b/include/clang/Basic/DiagnosticOptions.def
index f4ba6da81fe0..0ab6724ed9ef 100644
--- a/include/clang/Basic/DiagnosticOptions.def
+++ b/include/clang/Basic/DiagnosticOptions.def
@@ -50,6 +50,7 @@ DIAGOPT(Pedantic, 1, 0) /// -pedantic
DIAGOPT(PedanticErrors, 1, 0) /// -pedantic-errors
DIAGOPT(ShowColumn, 1, 1) /// Show column number on diagnostics.
DIAGOPT(ShowLocation, 1, 1) /// Show source location information.
+DIAGOPT(AbsolutePath, 1, 0) /// Use absolute paths.
DIAGOPT(ShowCarets, 1, 1) /// Show carets in diagnostics.
DIAGOPT(ShowFixits, 1, 1) /// Show fixit information.
DIAGOPT(ShowSourceRanges, 1, 0) /// Show source ranges in numeric form.
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 45044e626770..0943feae950e 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -13,10 +13,11 @@
let Component = "Parse" in {
-def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">,
- CatInlineAsm;
+def warn_asm_qualifier_ignored : Warning<
+ "ignored %0 qualifier on asm">, CatInlineAsm, InGroup<ASMIgnoredQualifier>;
def warn_file_asm_volatile : Warning<
- "meaningless 'volatile' on asm outside function">, CatInlineAsm;
+ "meaningless 'volatile' on asm outside function">, CatInlineAsm,
+ InGroup<ASMIgnoredQualifier>;
let CategoryName = "Inline Assembly Issue" in {
def err_asm_empty : Error<"__asm used with no assembly instructions">;
@@ -63,7 +64,7 @@ def ext_nullability : Extension<
"type nullability specifier %0 is a Clang extension">,
InGroup<DiagGroup<"nullability-extension">>;
-def error_empty_enum : Error<"use of empty enum">;
+def err_empty_enum : Error<"use of empty enum">;
def ext_ident_list_in_param : Extension<
"type-less parameter names in function declaration">;
@@ -346,8 +347,6 @@ def ext_c11_static_assert : Extension<
def warn_cxx98_compat_static_assert : Warning<
"static_assert declarations are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
-def err_paren_after_colon_colon : Error<
- "unexpected parenthesis after '::'">;
def err_function_definition_not_allowed : Error<
"function definition is not allowed here">;
def err_expected_end_of_enumerator : Error<
@@ -355,6 +354,10 @@ def err_expected_end_of_enumerator : Error<
def err_expected_coloncolon_after_super : Error<
"expected '::' after '__super'">;
+def ext_decomp_decl_empty : ExtWarn<
+ "ISO C++1z does not allow a decomposition group to be empty">,
+ InGroup<DiagGroup<"empty-decomposition">>;
+
/// Objective-C parser diagnostics
def err_expected_minus_or_plus : Error<
"method type specifier must start with '-' or '+'">;
@@ -395,7 +398,7 @@ def err_objc_expected_selector_for_getter_setter : Error<
"expected selector for Objective-C %select{setter|getter}0">;
def err_objc_property_requires_field_name : Error<
"property requires fields to be named">;
-def err_objc_property_bitfield : Error<"property name cannot be a bitfield">;
+def err_objc_property_bitfield : Error<"property name cannot be a bit-field">;
def err_objc_expected_property_attr : Error<"unknown property attribute %0">;
def err_objc_properties_require_objc2 : Error<
"properties are an Objective-C 2 feature">;
@@ -417,13 +420,11 @@ def err_unexpected_protocol_qualifier : Error<
"@implementation declaration cannot be protocol qualified">;
def err_objc_unexpected_atend : Error<
"'@end' appears where closing brace '}' is expected">;
-def error_property_ivar_decl : Error<
- "property synthesize requires specification of an ivar">;
def err_synthesized_property_name : Error<
"expected a property name in @synthesize">;
def warn_semicolon_before_method_body : Warning<
"semicolon before method body is ignored">,
- InGroup<DiagGroup<"semicolon-before-method-body">>, DefaultIgnore;
+ InGroup<SemiBeforeMethodBody>, DefaultIgnore;
def note_extra_comma_message_arg : Note<
"comma separating Objective-C messaging arguments">;
@@ -517,6 +518,12 @@ def ext_constexpr_if : ExtWarn<
def warn_cxx14_compat_constexpr_if : Warning<
"constexpr if is incompatible with C++ standards before C++1z">,
DefaultIgnore, InGroup<CXXPre1zCompat>;
+def ext_init_statement : ExtWarn<
+ "'%select{if|switch}0' initialization statements are a C++1z extension">,
+ InGroup<CXX1z>;
+def warn_cxx14_compat_init_statement : Warning<
+ "%select{if|switch}0 initialization statements are incompatible with "
+ "C++ standards before C++1z">, DefaultIgnore, InGroup<CXXPre1zCompat>;
// C++ derived classes
def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
@@ -719,7 +726,7 @@ def warn_cxx98_compat_nonstatic_member_init : Warning<
"in-class initialization of non-static data members is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_bitfield_member_init: Error<
- "bitfield member cannot have an in-class initializer">;
+ "bit-field member cannot have an in-class initializer">;
def err_incomplete_array_member_init: Error<
"array bound cannot be deduced from an in-class initializer">;
@@ -733,6 +740,22 @@ 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">;
+def err_alias_declaration_pack_expansion : Error<
+ "alias declaration cannot be a pack expansion">;
+
+// C++1z using-declaration pack expansions
+def ext_multi_using_declaration : ExtWarn<
+ "use of multiple declarators in a single using declaration is "
+ "a C++1z extension">, InGroup<CXX1z>;
+def warn_cxx1z_compat_multi_using_declaration : Warning<
+ "use of multiple declarators in a single using declaration is "
+ "incompatible with C++ standards before C++1z">,
+ InGroup<CXXPre1zCompat>, DefaultIgnore;
+def ext_using_declaration_pack : ExtWarn<
+ "pack expansion of using declaration is a C++1z extension">, InGroup<CXX1z>;
+def warn_cxx1z_compat_using_declaration_pack : Warning<
+ "pack expansion using declaration is incompatible with C++ standards "
+ "before C++1z">, InGroup<CXXPre1zCompat>, DefaultIgnore;
// C++11 override control
def ext_override_control_keyword : ExtWarn<
@@ -780,11 +803,20 @@ def warn_cxx98_compat_lambda : Warning<
InGroup<CXX98Compat>, DefaultIgnore;
def err_lambda_missing_parens : Error<
"lambda requires '()' before %select{'mutable'|return type|"
- "attribute specifier}0">;
-// C++1z lambda expressions
+ "attribute specifier|'constexpr'}0">;
+def err_lambda_decl_specifier_repeated : Error<
+ "%select{'mutable'|'constexpr'}0 cannot appear multiple times in a lambda declarator">;
+// C++1z lambda expressions
def err_expected_star_this_capture : Error<
"expected 'this' following '*' in lambda capture list">;
+// C++1z constexpr lambda expressions
+def warn_cxx14_compat_constexpr_on_lambda : Warning<
+ "constexpr on lambda expressions is incompatible with C++ standards before C++1z">,
+ InGroup<CXXPre1zCompat>, DefaultIgnore;
+def ext_constexpr_on_lambda_cxx1z : ExtWarn<
+ "'constexpr' on lambda expressions is a C++1z extension">, InGroup<CXX1z>;
+
// Availability attribute
def err_expected_version : Error<
"expected a version of the form 'major[.minor[.subminor]]'">;
@@ -815,8 +847,6 @@ def warn_availability_and_unavailable : Warning<
InGroup<Availability>;
// @available(...)
-def err_avail_query_expected_condition : Error<
- "expected an availability condition here">;
def err_avail_query_expected_platform_name : Error<
"expected a platform name here">;
@@ -900,6 +930,10 @@ def warn_pragma_invalid_action : Warning<
def warn_pragma_pack_malformed : Warning<
"expected integer or identifier in '#pragma pack' - ignored">,
InGroup<IgnoredPragmas>;
+// - #pragma intrinsic
+def warn_pragma_intrinsic_builtin : Warning<
+ "%0 is not a recognized builtin%select{|; consider including <intrin.h> to access non-builtin intrinsics}1">,
+ InGroup<IgnoredPragmaIntrinsic>;
// - #pragma unused
def warn_pragma_unused_expected_var : Warning<
"expected '#pragma unused' argument to be a variable name">,
@@ -941,8 +975,10 @@ def err_opencl_unroll_hint_on_non_loop : Error<
// OpenCL EXTENSION pragma (OpenCL 1.1 [9.1])
def warn_pragma_expected_colon : Warning<
"missing ':' after %0 - ignoring">, InGroup<IgnoredPragmas>;
-def warn_pragma_expected_enable_disable : Warning<
- "expected 'enable' or 'disable' - ignoring">, InGroup<IgnoredPragmas>;
+def warn_pragma_expected_predicate : Warning<
+ "expected %select{'enable', 'disable', 'begin' or 'end'|'disable'}0 - ignoring">, InGroup<IgnoredPragmas>;
+def warn_pragma_begin_end_mismatch : Warning<
+ "OpenCL extension end directive mismatches begin directive - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_unknown_extension : Warning<
"unknown OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_unsupported_extension : Warning<
@@ -1007,14 +1043,36 @@ def err_pragma_invalid_keyword : Error<
def warn_pragma_unroll_cuda_value_in_parens : Warning<
"argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">,
InGroup<CudaCompat>;
+
+def warn_cuda_attr_lambda_position : Warning<
+ "nvcc does not allow '__%0__' to appear after '()' in lambdas">,
+ InGroup<CudaCompat>;
+def warn_pragma_force_cuda_host_device_bad_arg : Warning<
+ "incorrect use of #pragma clang force_cuda_host_device begin|end">,
+ InGroup<IgnoredPragmas>;
+def err_pragma_cannot_end_force_cuda_host_device : Error<
+ "force_cuda_host_device end pragma without matching "
+ "force_cuda_host_device begin">;
} // end of Parse Issue category.
let CategoryName = "Modules Issue" in {
+def err_expected_module_interface_decl : Error<
+ "expected module declaration at start of module interface">;
+def err_unexpected_module_decl : Error<
+ "module declaration must be the first declaration in the translation unit">;
def err_module_expected_ident : Error<
- "expected a module name after module import">;
+ "expected a module name after module%select{| import}0">;
+def err_unexpected_module_kind : Error<
+ "unexpected module kind %0; expected 'implementation' or 'partition'">;
+def err_attribute_not_module_attr : Error<
+ "%0 attribute cannot be applied to a module">;
+def err_attribute_not_import_attr : Error<
+ "%0 attribute cannot be applied to a module import">;
def err_module_expected_semi : Error<
"expected ';' after module name">;
def err_missing_before_module_end : Error<"expected %0 at end of module">;
+
+def err_export_empty : Error<"export declaration cannot be empty">;
}
let CategoryName = "Generics Issue" in {
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 98b687b8e821..c4e4e2b60192 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -53,6 +53,14 @@ def warn_pointer_abs : Warning<
"taking the absolute value of %select{pointer|function|array}0 type %1 is suspicious">,
InGroup<AbsoluteValue>;
+def warn_max_unsigned_zero : Warning<
+ "taking the max of "
+ "%select{a value and unsigned zero|unsigned zero and a value}0 "
+ "is always equal to the other value">,
+ InGroup<MaxUnsignedZero>;
+def note_remove_max_call : Note<
+ "remove call to max function and unsigned zero argument">;
+
def warn_infinite_recursive_function : Warning<
"all paths through this function will call itself">,
InGroup<InfiniteRecursion>, DefaultIgnore;
@@ -357,6 +365,9 @@ def warn_decl_shadow :
"static data member of %2|"
"field of %2}1">,
InGroup<Shadow>, DefaultIgnore;
+def warn_decl_shadow_uncaptured_local :
+ Warning<warn_decl_shadow.Text>,
+ InGroup<ShadowUncapturedLocal>, DefaultIgnore;
def warn_ctor_parm_shadows_field:
Warning<"constructor parameter %0 shadows the field %1 of %2">,
InGroup<ShadowFieldInConstructor>, DefaultIgnore;
@@ -365,6 +376,58 @@ def warn_modifying_shadowing_decl :
"field of %1">,
InGroup<ShadowFieldInConstructorModified>, DefaultIgnore;
+// C++ decomposition declarations
+def err_decomp_decl_context : Error<
+ "decomposition declaration not permitted in this context">;
+def warn_cxx14_compat_decomp_decl : Warning<
+ "decomposition declarations are incompatible with "
+ "C++ standards before C++1z">, DefaultIgnore, InGroup<CXXPre1zCompat>;
+def ext_decomp_decl : ExtWarn<
+ "decomposition declarations are a C++1z extension">, InGroup<CXX1z>;
+def err_decomp_decl_spec : Error<
+ "decomposition declaration cannot be declared "
+ "%plural{1:'%1'|:with '%1' specifiers}0">;
+def err_decomp_decl_type : Error<
+ "decomposition declaration cannot be declared with type %0; "
+ "declared type must be 'auto' or reference to 'auto'">;
+def err_decomp_decl_parens : Error<
+ "decomposition declaration cannot be declared with parentheses">;
+def err_decomp_decl_template : Error<
+ "decomposition declaration template not supported">;
+def err_decomp_decl_not_alone : Error<
+ "decomposition declaration must be the only declaration in its group">;
+def err_decomp_decl_requires_init : Error<
+ "decomposition declaration %0 requires an initializer">;
+def err_decomp_decl_wrong_number_bindings : Error<
+ "type %0 decomposes into %2 elements, but %select{only |}3%1 "
+ "names were provided">;
+def err_decomp_decl_unbindable_type : Error<
+ "cannot decompose %select{union|non-class, non-array}1 type %2">;
+def err_decomp_decl_multiple_bases_with_members : Error<
+ "cannot decompose class type %1: "
+ "%select{its base classes %2 and|both it and its base class}0 %3 "
+ "have non-static data members">;
+def err_decomp_decl_ambiguous_base : Error<
+ "cannot decompose members of ambiguous base class %1 of %0:%2">;
+def err_decomp_decl_non_public_base : Error<
+ "cannot decompose members of non-public base class %1 of %0">;
+def err_decomp_decl_non_public_member : Error<
+ "cannot decompose non-public member %0 of %1">;
+def err_decomp_decl_anon_union_member : Error<
+ "cannot decompose class type %0 because it has an anonymous "
+ "%select{struct|union}1 member">;
+def err_decomp_decl_std_tuple_element_not_specialized : Error<
+ "cannot decompose this type; 'std::tuple_element<%0>::type' "
+ "does not name a type">;
+def err_decomp_decl_std_tuple_size_not_constant : Error<
+ "cannot decompose this type; 'std::tuple_size<%0>::value' "
+ "is not a valid integral constant expression">;
+def note_in_binding_decl_init : Note<
+ "in implicit initialization of binding declaration %0">;
+
+def err_std_type_trait_not_class_template : Error<
+ "unsupported standard library implementation: "
+ "'std::%0' is not a class template">;
// C++ using declarations
def err_using_requires_qualname : Error<
@@ -411,6 +474,8 @@ def err_using_decl_conflict : Error<
def err_using_decl_conflict_reverse : Error<
"declaration conflicts with target of using declaration already in scope">;
def note_using_decl : Note<"%select{|previous }0using declaration">;
+def err_using_decl_redeclaration_expansion : Error<
+ "using declaration pack expansion at block scope produces multiple values">;
def warn_access_decl_deprecated : Warning<
"access declarations are deprecated; use using declarations instead">,
@@ -418,15 +483,21 @@ def warn_access_decl_deprecated : Warning<
def err_access_decl : Error<
"ISO C++11 does not allow access declarations; "
"use using declarations instead">;
+def ext_dynamic_exception_spec : ExtWarn<
+ "ISO C++1z does not allow dynamic exception specifications">,
+ InGroup<DynamicExceptionSpec>, DefaultError;
def warn_exception_spec_deprecated : Warning<
"dynamic exception specifications are deprecated">,
- InGroup<Deprecated>, DefaultIgnore;
+ InGroup<DeprecatedDynamicExceptionSpec>, DefaultIgnore;
def note_exception_spec_deprecated : Note<"use '%0' instead">;
def warn_deprecated_copy_operation : Warning<
"definition of implicit copy %select{constructor|assignment operator}1 "
"for %0 is deprecated because it has a user-declared "
"%select{copy %select{assignment operator|constructor}1|destructor}2">,
InGroup<Deprecated>, DefaultIgnore;
+def warn_cxx1z_compat_exception_spec_in_signature : Warning<
+ "mangled name of %0 will change in C++17 due to non-throwing exception "
+ "specification in function signature">, InGroup<CXX1zCompat>;
def warn_global_constructor : Warning<
"declaration requires a global constructor">,
@@ -455,6 +526,12 @@ def err_maybe_falloff_nonvoid_block : Error<
"control may reach end of non-void block">;
def err_falloff_nonvoid_block : Error<
"control reaches end of non-void block">;
+def warn_maybe_falloff_nonvoid_coroutine : Warning<
+ "control may reach end of non-void coroutine">,
+ InGroup<ReturnType>;
+def warn_falloff_nonvoid_coroutine : Warning<
+ "control reaches end of non-void coroutine">,
+ InGroup<ReturnType>;
def warn_suggest_noreturn_function : Warning<
"%select{function|method}0 %1 could be declared with attribute 'noreturn'">,
InGroup<MissingNoreturn>, DefaultIgnore;
@@ -580,6 +657,8 @@ def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">,
def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 "
"parameter of 'main' (%select{argument count|argument array|environment|"
"platform-specific data}0) must be of type %1">;
+def warn_main_returns_bool_literal : Warning<"bool literal returned from "
+ "'main'">, InGroup<Main>;
def err_main_global_variable :
Error<"main cannot be declared as global variable">;
def warn_main_redefined : Warning<"variable named 'main' with external linkage "
@@ -605,7 +684,8 @@ def err_object_cannot_be_passed_returned_by_value : Error<
def err_parameters_retval_cannot_have_fp16_type : Error<
"%select{parameters|function return value}0 cannot have __fp16 type; did you forget * ?">;
def err_opencl_half_load_store : Error<
- "%select{loading directly from|assigning directly to}0 pointer to type %1 is not allowed">;
+ "%select{loading directly from|assigning directly to}0 pointer to type %1 requires "
+ "cl_khr_fp16. Use vector data %select{load|store}0 builtin functions instead">;
def err_opencl_cast_to_half : Error<"casting to type %0 is not allowed">;
def err_opencl_half_declaration : Error<
"declaring variable of type %0 is not allowed">;
@@ -675,7 +755,9 @@ def err_recursive_superclass : Error<
"trying to recursively use %0 as superclass of %1">;
def err_conflicting_aliasing_type : Error<"conflicting types for alias %0">;
def warn_undef_interface : Warning<"cannot find interface declaration for %0">;
-def warn_duplicate_protocol_def : Warning<"duplicate protocol definition of %0 is ignored">;
+def warn_duplicate_protocol_def : Warning<
+ "duplicate protocol definition of %0 is ignored">,
+ InGroup<DiagGroup<"duplicate-protocol">>;
def err_protocol_has_circular_dependency : Error<
"protocol has circular dependency">;
def err_undeclared_protocol : Error<"cannot find protocol declaration for %0">;
@@ -717,6 +799,9 @@ def note_suppressed_class_declare : Note<
"class with specified objc_requires_property_definitions attribute is declared here">;
def err_objc_root_class_subclass : Error<
"objc_root_class attribute may only be specified on a root class declaration">;
+def err_restricted_superclass_mismatch : Error<
+ "cannot subclass a class that was declared with the "
+ "'objc_subclassing_restricted' attribute">;
def warn_objc_root_class_missing : Warning<
"class %0 defined without specifying a base class">,
InGroup<ObjCRootClass>;
@@ -832,7 +917,7 @@ def warn_strict_multiple_method_decl : Warning<
"multiple methods named %0 found">, InGroup<StrictSelector>, DefaultIgnore;
def warn_accessor_property_type_mismatch : Warning<
"type of property %0 does not match type of accessor %1">;
-def not_conv_function_declared_at : Note<"type conversion function declared here">;
+def note_conv_function_declared_at : Note<"type conversion function declared here">;
def note_method_declared_at : Note<"method %0 declared here">;
def note_property_attribute : Note<"property %0 is declared "
"%select{deprecated|unavailable|partial}1 here">;
@@ -848,7 +933,7 @@ def warn_objc_cdirective_format_string :
InGroup<ObjCCStringFormat>, DefaultIgnore;
def err_objc_var_decl_inclass :
Error<"cannot declare variable inside @interface or @protocol">;
-def error_missing_method_context : Error<
+def err_missing_method_context : Error<
"missing context for method declaration">;
def err_objc_property_attr_mutually_exclusive : Error<
"property attributes '%0' and '%1' are mutually exclusive">;
@@ -939,7 +1024,7 @@ def warn_property_getter_owning_mismatch : Warning<
def warn_property_redecl_getter_mismatch : Warning<
"getter name mismatch between property redeclaration (%1) and its original "
"declaration (%0)">, InGroup<PropertyAttr>;
-def error_property_setter_ambiguous_use : Error<
+def err_property_setter_ambiguous_use : Error<
"synthesized properties %0 and %1 both claim setter %2 -"
" use of this setter will cause unexpected behavior">;
def warn_default_atomic_custom_getter_setter : Warning<
@@ -958,12 +1043,12 @@ def err_use_continuation_class_redeclaration_readwrite : Error<
"'readonly' public property?)">;
def err_continuation_class : Error<"class extension has no primary class">;
def err_property_type : Error<"property cannot have array or function type %0">;
-def error_missing_property_context : Error<
+def err_missing_property_context : Error<
"missing context for property implementation declaration">;
-def error_bad_property_decl : Error<
+def err_bad_property_decl : Error<
"property implementation must have its declaration in interface %0 or one of "
"its extensions">;
-def error_category_property : Error<
+def err_category_property : Error<
"property declared in category %0 cannot be implemented in "
"class implementation">;
def note_property_declare : Note<
@@ -972,19 +1057,17 @@ def note_protocol_property_declare : Note<
"it could also be property of type %0 declared here">;
def note_property_synthesize : Note<
"property synthesized here">;
-def error_synthesize_category_decl : Error<
+def err_synthesize_category_decl : Error<
"@synthesize not allowed in a category's implementation">;
-def error_synthesize_on_class_property : Error<
+def err_synthesize_on_class_property : Error<
"@synthesize not allowed on a class property %0">;
-def error_reference_property : Error<
- "property of reference type is not supported">;
-def error_missing_property_interface : Error<
+def err_missing_property_interface : Error<
"property implementation in a category with no category declaration">;
-def error_bad_category_property_decl : Error<
+def err_bad_category_property_decl : Error<
"property implementation must have its declaration in the category %0">;
-def error_bad_property_context : Error<
+def err_bad_property_context : Error<
"property implementation must be in a class or category implementation">;
-def error_missing_property_ivar_decl : Error<
+def err_missing_property_ivar_decl : Error<
"synthesized property %0 must either be named the same as a compatible"
" instance variable or must explicitly name an instance variable">;
def err_arc_perform_selector_retains : Error<
@@ -1018,25 +1101,25 @@ def note_arc_weak_also_accessed_here : Note<
def err_incomplete_synthesized_property : Error<
"cannot synthesize property %0 with incomplete type %1">;
-def error_property_ivar_type : Error<
+def err_property_ivar_type : Error<
"type of property %0 (%1) does not match type of instance variable %2 (%3)">;
-def error_property_accessor_type : Error<
+def err_property_accessor_type : Error<
"type of property %0 (%1) does not match type of accessor %2 (%3)">;
-def error_ivar_in_superclass_use : Error<
+def err_ivar_in_superclass_use : Error<
"property %0 attempting to use instance variable %1 declared in super class %2">;
-def error_weak_property : Error<
+def err_weak_property : Error<
"existing instance variable %1 for __weak property %0 must be __weak">;
-def error_strong_property : Error<
+def err_strong_property : Error<
"existing instance variable %1 for strong property %0 may not be __weak">;
-def error_dynamic_property_ivar_decl : Error<
+def err_dynamic_property_ivar_decl : Error<
"dynamic property cannot have instance variable specification">;
-def error_duplicate_ivar_use : Error<
+def err_duplicate_ivar_use : Error<
"synthesized properties %0 and %1 both claim instance variable %2">;
-def error_property_implemented : Error<"property %0 is already implemented">;
+def err_property_implemented : Error<"property %0 is already implemented">;
def warn_objc_missing_super_call : Warning<
"method possibly missing a [super %0] call">,
InGroup<ObjCMissingSuperCalls>;
-def error_dealloc_bad_result_type : Error<
+def err_dealloc_bad_result_type : Error<
"dealloc return type must be correctly specified as 'void' under ARC, "
"instead of %0">;
def warn_undeclared_selector : Warning<
@@ -1060,7 +1143,7 @@ def warn_unimplemented_selector: Warning<
InGroup<Selector>, DefaultIgnore;
def warn_unimplemented_protocol_method : Warning<
"method %0 in protocol %1 not implemented">, InGroup<Protocol>;
-def warning_multiple_selectors: Warning<
+def warn_multiple_selectors: Warning<
"several methods with selector %0 of mismatched types are found "
"for the @selector expression">,
InGroup<SelectorTypeMismatch>, DefaultIgnore;
@@ -1087,10 +1170,9 @@ def warn_cxx14_compat_inline_variable : Warning<
DefaultIgnore, InGroup<CXXPre1zCompat>;
def warn_inline_namespace_reopened_noninline : Warning<
- "inline namespace cannot be reopened as a non-inline namespace">;
+ "inline namespace reopened as a non-inline namespace">;
def err_inline_namespace_mismatch : Error<
- "%select{|non-}0inline namespace "
- "cannot be reopened as %select{non-|}0inline">;
+ "non-inline namespace cannot be reopened as inline">;
def err_unexpected_friend : Error<
"friends can only be classes or functions">;
@@ -1240,8 +1322,12 @@ def ext_override_exception_spec : ExtWarn<err_override_exception_spec.Text>,
InGroup<MicrosoftExceptionSpec>;
def err_incompatible_exception_specs : Error<
"target exception specification is not superset of source">;
+def warn_incompatible_exception_specs : Warning<
+ err_incompatible_exception_specs.Text>, InGroup<IncompatibleExceptionSpec>;
def err_deep_exception_specs_differ : Error<
"exception specifications of %select{return|argument}0 types differ">;
+def warn_deep_exception_specs_differ : Warning<
+ err_deep_exception_specs_differ.Text>, InGroup<IncompatibleExceptionSpec>;
def err_missing_exception_specification : Error<
"%0 is missing exception specification '%1'">;
def ext_missing_exception_specification : ExtWarn<
@@ -1590,7 +1676,8 @@ def err_init_conversion_failed : Error<
"%select{none|const|restrict|const and restrict|volatile|const and volatile|"
"volatile and restrict|const, volatile, and restrict}5 vs "
"%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}6)}4">;
+ "volatile and restrict|const, volatile, and restrict}6)"
+ "|: different exception specifications}4">;
def err_lvalue_to_rvalue_ref : Error<"rvalue reference %diff{to type $ cannot "
"bind to lvalue of type $|cannot bind to incompatible lvalue}0,1">;
@@ -1691,8 +1778,10 @@ def warn_uninit_byref_blockvar_captured_by_block : Warning<
def note_block_var_fixit_add_initialization : Note<
"did you mean to use __block %0?">;
def note_in_omitted_aggregate_initializer : Note<
- "in implicit initialization of %select{array element %1|field %1}0 "
- "with omitted initializer">;
+ "in implicit initialization of %select{"
+ "array element %1 with omitted initializer|"
+ "field %1 with omitted initializer|"
+ "trailing array elements in runtime-sized array new}0">;
def note_in_reference_temporary_list_initializer : Note<
"in initialization of temporary of type %0 created to "
"list-initialize this reference">;
@@ -1702,6 +1791,8 @@ def note_uninit_fixit_remove_cond : Note<
"remove the %select{'%1' if its condition|condition if it}0 "
"is always %select{false|true}2">;
def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
+def err_list_init_in_parens : Error<"list-initializer for non-class type %0 "
+ "must not be parenthesized">;
def warn_unsequenced_mod_mod : Warning<
"multiple unsequenced modifications to %0">, InGroup<Unsequenced>;
@@ -1756,6 +1847,9 @@ def warn_cxx98_compat_auto_type_specifier : Warning<
def err_auto_variable_cannot_appear_in_own_initializer : Error<
"variable %0 declared with %select{'auto'|'decltype(auto)'|'__auto_type'}1 "
"type cannot appear in its own initializer">;
+def err_binding_cannot_appear_in_own_initializer : Error<
+ "binding %0 cannot appear in the initializer of its own "
+ "decomposition declaration">;
def err_illegal_decl_array_of_auto : Error<
"'%0' declared as array of %1">;
def err_new_array_of_auto : Error<
@@ -1769,7 +1863,8 @@ def err_auto_not_allowed : Error<
"|in exception declaration|in template parameter|in block literal"
"|in template argument|in typedef|in type alias|in function return type"
"|in conversion function type|here|in lambda parameter"
- "|in type allocated by 'new'|in K&R-style function parameter}1">;
+ "|in type allocated by 'new'|in K&R-style function parameter}1"
+ "%select{|||||||| until C++1z||||||||||}1">;
def err_auto_not_allowed_var_inst : Error<
"'auto' variable template instantiation is not allowed">;
def err_auto_var_requires_init : Error<
@@ -2198,10 +2293,15 @@ def err_attribute_only_once_per_parameter : Error<
"%0 attribute can only be applied once per parameter">;
def err_attribute_uuid_malformed_guid : Error<
"uuid attribute contains a malformed GUID">;
+def err_mismatched_uuid : Error<"uuid does not match previous declaration">;
+def note_previous_uuid : Note<"previous uuid specified here">;
def warn_attribute_pointers_only : Warning<
"%0 attribute only applies to%select{| constant}1 pointer arguments">,
InGroup<IgnoredAttributes>;
def err_attribute_pointers_only : Error<warn_attribute_pointers_only.Text>;
+def err_attribute_integers_only : Error<
+ "%0 attribute argument may only refer to a function parameter of integer "
+ "type">;
def warn_attribute_return_pointers_only : Warning<
"%0 attribute only applies to return values that are pointers">,
InGroup<IgnoredAttributes>;
@@ -2242,6 +2342,9 @@ def err_typecheck_vector_not_convertable_non_scalar : Error<
"cannot convert between vector and non-scalar values (%0 and %1)">;
def err_typecheck_vector_lengths_not_equal : Error<
"vector operands do not have the same number of elements (%0 and %1)">;
+def warn_typecheck_vector_element_sizes_not_equal : Warning<
+ "vector operands do not have the same elements sizes (%0 and %1)">,
+ InGroup<DiagGroup<"vec-elem-size">>, DefaultError;
def err_ext_vector_component_exceeds_length : Error<
"vector component access exceeds type %0">;
def err_ext_vector_component_name_illegal : Error<
@@ -2311,17 +2414,15 @@ def err_swift_param_attr_not_swiftcall : Error<
"'%0' parameter can only be used with swiftcall calling convention">;
def err_swift_indirect_result_not_first : Error<
"'swift_indirect_result' parameters must be first parameters of function">;
-def err_swift_context_not_before_swift_error_result : Error<
- "'swift_context' parameter can only be followed by 'swift_error_result' "
- "parameter">;
-def err_swift_error_result_not_last : Error<
- "'swift_error_result' parameter must be last parameter of function">;
def err_swift_error_result_not_after_swift_context : Error<
"'swift_error_result' parameter must follow 'swift_context' parameter">;
def err_swift_abi_parameter_wrong_type : Error<
"'%0' parameter must have pointer%select{| to unqualified pointer}1 type; "
"type here is %2">;
+def err_attribute_argument_invalid : Error<
+ "%0 attribute argument is invalid: %select{max must be 0 since min is 0|"
+ "min must not be greater than max}1">;
def err_attribute_argument_is_zero : Error<
"%0 attribute must be greater than 0">;
def warn_attribute_argument_n_negative : Warning<
@@ -2357,9 +2458,17 @@ def err_property_is_variably_modified : Error<
"property %0 has a variably modified type">;
def err_no_accessor_for_property : Error<
"no %select{getter|setter}0 defined for property %1">;
-def error_cannot_find_suitable_accessor : Error<
+def err_cannot_find_suitable_accessor : Error<
"cannot find suitable %select{getter|setter}0 for property %1">;
+def warn_alloca_align_alignof : Warning<
+ "second argument to __builtin_alloca_with_align is supposed to be in bits">,
+ InGroup<DiagGroup<"alloca-with-align-alignof">>;
+
+def err_alignment_too_small : Error<
+ "requested alignment must be %0 or greater">;
+def err_alignment_too_big : Error<
+ "requested alignment must be %0 or smaller">;
def err_alignment_not_power_of_two : Error<
"requested alignment is not a power of 2">;
def err_alignment_dependent_typedef_name : Error<
@@ -2502,25 +2611,52 @@ def err_ifunc_resolver_return : Error<
def err_ifunc_resolver_params : Error<
"ifunc resolver function must have no parameters">;
def warn_attribute_wrong_decl_type : Warning<
- "%0 attribute only applies to %select{functions|unions|"
- "variables and functions|"
- "functions, variables, and Objective-C interfaces|"
- "functions and methods|parameters|"
- "functions, methods and blocks|functions, methods, and classes|"
- "functions, methods, and parameters|classes|enums|variables|methods|"
- "fields and global variables|structs|parameters and typedefs|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|"
- "functions, variables, classes, and Objective-C interfaces|"
- "Objective-C protocols|"
- "functions and global variables|structs, unions, and typedefs|structs and typedefs|"
- "interface or protocol declarations|kernel functions|non-K&R-style functions|"
- "variables, enums, fields and typedefs|functions, methods, enums, and classes|"
- "structs, classes, variables, functions, and inline namespaces|"
- "variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members}1">,
+ "%0 attribute only applies to %select{"
+ "functions"
+ "|unions"
+ "|variables and functions"
+ "|functions and global variables"
+ "|functions, variables, and Objective-C interfaces"
+ "|functions and methods"
+ "|parameters"
+ "|functions, methods and blocks"
+ "|functions, methods, and classes"
+ "|functions, methods, and parameters"
+ "|functions, methods, and global variables"
+ "|classes"
+ "|enums"
+ "|variables"
+ "|methods"
+ "|fields and global variables"
+ "|structs"
+ "|parameters and typedefs"
+ "|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"
+ "|functions, variables, classes, and Objective-C interfaces"
+ "|Objective-C protocols"
+ "|variables with static or thread storage duration"
+ "|functions, methods, properties, and global variables"
+ "|structs, unions, and typedefs"
+ "|structs and typedefs"
+ "|interface or protocol declarations"
+ "|kernel functions"
+ "|non-K&R-style functions"
+ "|variables, enums, fields and typedefs"
+ "|functions, methods, enums, and classes"
+ "|structs, classes, variables, functions, and inline namespaces"
+ "|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members"
+ "|classes and enumerations}1">,
InGroup<IgnoredAttributes>;
def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
def warn_type_attribute_wrong_type : Warning<
@@ -2599,8 +2735,20 @@ def note_overridden_method : Note<
def note_protocol_method : Note<
"protocol method is here">;
-def warn_available_using_star_case : Warning<
- "using '*' case here, platform %0 is not accounted for">, InGroup<UnguardedAvailability>;
+def warn_unguarded_availability :
+ Warning<"%0 is only available on %1 %2 or newer">,
+ InGroup<UnguardedAvailability>, DefaultIgnore;
+def warn_partial_availability : Warning<"%0 is only available conditionally">,
+ InGroup<UnguardedAvailability>, DefaultIgnore;
+def note_partial_availability_silence : Note<
+ "explicitly redeclare %0 to silence this warning">;
+def note_unguarded_available_silence : Note<
+ "enclose %0 in an @available check to silence this warning">;
+def warn_partial_message : Warning<"%0 is partial: %1">,
+ InGroup<UnguardedAvailability>, DefaultIgnore;
+def warn_partial_fwdclass_message : Warning<
+ "%0 may be partial because the receiver type is unknown">,
+ InGroup<UnguardedAvailability>, DefaultIgnore;
// Thread Safety Attributes
def warn_invalid_capability_name : Warning<
@@ -2784,7 +2932,7 @@ def warn_impcast_integer_precision_constant : Warning<
"implicit conversion from %2 to %3 changes value from %0 to %1">,
InGroup<ConstantConversion>;
def warn_impcast_bitfield_precision_constant : Warning<
- "implicit truncation from %2 to bitfield changes value from %0 to %1">,
+ "implicit truncation from %2 to bit-field changes value from %0 to %1">,
InGroup<BitFieldConstantConversion>;
def warn_impcast_literal_float_to_integer : Warning<
@@ -2887,6 +3035,10 @@ def warn_int_to_void_pointer_cast : Warning<
"cast to %1 from smaller integer type %0">,
InGroup<IntToVoidPointerCast>;
+def warn_no_underlying_type_specified_for_enum_bitfield : Warning<
+ "enums in the Microsoft ABI are signed integers by default; consider giving "
+ "the enum %0 an unsigned underlying type to make this code portable">,
+ InGroup<SignedEnumBitfield>, DefaultIgnore;
def warn_attribute_packed_for_bitfield : Warning<
"'packed' attribute was ignored on bit-fields with single-byte alignment "
"in older versions of GCC and Clang">,
@@ -3166,17 +3318,18 @@ def note_ovl_candidate : Note<"candidate "
"is the implicit copy assignment operator|"
"is the implicit move assignment operator|"
"inherited constructor|"
- "inherited constructor }0%1"
- "%select{| has different class%diff{ (expected $ but has $)|}3,4"
- "| has different number of parameters (expected %3 but has %4)"
- "| has type mismatch at %ordinal3 parameter"
- "%diff{ (expected $ but has $)|}4,5"
- "| has different return type%diff{ ($ expected but has $)|}3,4"
+ "inherited constructor }0%2"
+ "%select{| has different class%diff{ (expected $ but has $)|}4,5"
+ "| has different number of parameters (expected %4 but has %5)"
+ "| has type mismatch at %ordinal4 parameter"
+ "%diff{ (expected $ but has $)|}5,6"
+ "| has different return type%diff{ ($ expected but has $)|}4,5"
"| has different qualifiers (expected "
"%select{none|const|restrict|const and restrict|volatile|const and volatile"
- "|volatile and restrict|const, volatile, and restrict}3 but found "
+ "|volatile and restrict|const, volatile, and restrict}4 but found "
"%select{none|const|restrict|const and restrict|volatile|const and volatile"
- "|volatile and restrict|const, volatile, and restrict}4)}2">;
+ "|volatile and restrict|const, volatile, and restrict}5)"
+ "| has different exception specification}3">;
def note_ovl_candidate_inherited_constructor : Note<
"constructor from base class %0 inherited here">;
@@ -3190,6 +3343,10 @@ def note_ovl_candidate_incomplete_deduction : Note<"candidate template ignored:
def note_ovl_candidate_inconsistent_deduction : Note<
"candidate template ignored: deduced conflicting %select{types|values|"
"templates}0 for parameter %1%diff{ ($ vs. $)|}2,3">;
+def note_ovl_candidate_inconsistent_deduction_types : Note<
+ "candidate template ignored: deduced values %diff{"
+ "of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|"
+ "%1 and %3 of conflicting types for parameter %0}2,4">;
def note_ovl_candidate_explicit_arg_mismatch_named : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0">;
@@ -3211,6 +3368,8 @@ def note_ovl_candidate_has_pass_object_size_params: Note<
"pass_object_size attribute">;
def note_ovl_candidate_disabled_by_enable_if_attr : Note<
"candidate disabled: %0">;
+def note_ovl_candidate_disabled_by_extension : Note<
+ "candidate disabled due to OpenCL extension">;
def err_addrof_function_disabled_by_enable_if_attr : Error<
"cannot take address of function %0 becuase it has one or more "
"non-tautological enable_if conditions">;
@@ -3581,6 +3740,10 @@ def note_template_nontype_parm_prev_declaration : Note<
"previous non-type template parameter with type %0 is here">;
def err_template_nontype_parm_bad_type : Error<
"a non-type template parameter cannot have type %0">;
+def warn_cxx14_compat_template_nontype_parm_auto_type : Warning<
+ "non-type template parameters declared with %0 are incompatible with C++ "
+ "standards before C++1z">,
+ DefaultIgnore, InGroup<CXXPre1zCompat>;
def err_template_param_default_arg_redefinition : Error<
"template parameter redefines default argument">;
def note_template_param_prev_default_arg : Note<
@@ -3675,11 +3838,13 @@ def warn_cxx98_compat_template_arg_null : Warning<
def err_template_arg_untyped_null_constant : Error<
"null non-type template argument must be cast to template parameter type %0">;
def err_template_arg_wrongtype_null_constant : Error<
- "null non-type template argument of type %0 does not match template parameter "
- "of type %1">;
+ "null non-type template argument of type %0 does not match template parameter "
+ "of type %1">;
+def err_non_type_template_parm_type_deduction_failure : Error<
+ "non-type template parameter %0 with type %1 has incompatible initializer of type %2">;
def err_deduced_non_type_template_arg_type_mismatch : Error<
"deduced non-type template argument does not have the same type as the "
- "its corresponding template parameter%diff{ ($ vs $)|}0,1">;
+ "corresponding template parameter%diff{ ($ vs $)|}0,1">;
def err_non_type_template_arg_subobject : Error<
"non-type template argument refers to subobject '%0'">;
def err_non_type_template_arg_addr_label_diff : Error<
@@ -3867,8 +4032,8 @@ def err_specialize_member_of_template : Error<
def err_default_arg_in_partial_spec : Error<
"default template argument in a class template partial specialization">;
def err_dependent_non_type_arg_in_partial_spec : Error<
- "non-type template argument depends on a template parameter of the "
- "partial specialization">;
+ "type of specialized non-type template argument depends on a template "
+ "parameter of the partial specialization">;
def note_dependent_non_type_default_arg_in_partial_spec : Note<
"template parameter is used in default argument declared here">;
def err_dependent_typed_non_type_arg_in_partial_spec : Error<
@@ -3878,10 +4043,16 @@ def err_partial_spec_args_match_primary_template : Error<
"%select{class|variable}0 template partial specialization does not "
"specialize any template argument; to %select{declare|define}1 the "
"primary template, remove the template argument list">;
-def warn_partial_specs_not_deducible : Warning<
+def ext_partial_spec_not_more_specialized_than_primary : ExtWarn<
+ "%select{class|variable}0 template partial specialization is not "
+ "more specialized than the primary template">, DefaultError,
+ InGroup<DiagGroup<"invalid-partial-specialization">>;
+def note_partial_spec_not_more_specialized_than_primary : Note<"%0">;
+def ext_partial_specs_not_deducible : ExtWarn<
"%select{class|variable}0 template partial specialization contains "
"%select{a template parameter|template parameters}1 that cannot be "
- "deduced; this partial specialization will never be used">;
+ "deduced; this partial specialization will never be used">,
+ DefaultError, InGroup<DiagGroup<"unusable-partial-specialization">>;
def note_partial_spec_unused_parameter : Note<
"non-deducible template parameter %0">;
def err_partial_spec_ordering_ambiguous : Error<
@@ -3915,7 +4086,7 @@ def err_function_template_spec_ambiguous : Error<
"function template; explicitly specify%select{| additional}1 template "
"arguments to identify a particular function template">;
def note_function_template_spec_matched : Note<
- "function template matches specialization %0">;
+ "function template %q0 matches specialization %1">;
def err_function_template_partial_spec : Error<
"function template partial specialization is not allowed">;
@@ -3938,9 +4109,9 @@ def note_template_class_instantiation_was_here : Note<
def note_template_class_explicit_specialization_was_here : Note<
"class template %0 was explicitly specialized here">;
def note_template_class_instantiation_here : Note<
- "in instantiation of template class %0 requested here">;
+ "in instantiation of template class %q0 requested here">;
def note_template_member_class_here : Note<
- "in instantiation of member class %0 requested here">;
+ "in instantiation of member class %q0 requested here">;
def note_template_member_function_here : Note<
"in instantiation of member function %q0 requested here">;
def note_function_template_spec_here : Note<
@@ -3980,9 +4151,9 @@ def note_explicit_template_arg_substitution_here : Note<
def note_function_template_deduction_instantiation_here : Note<
"while substituting deduced template arguments into function template %0 "
"%1">;
-def note_partial_spec_deduct_instantiation_here : Note<
- "during template argument deduction for class template partial "
- "specialization %0 %1">;
+def note_deduced_template_arg_substitution_here : Note<
+ "during template argument deduction for %select{class|variable}0 template "
+ "%select{partial specialization |}1%2 %3">;
def note_prior_template_arg_substitution : Note<
"while substituting prior template arguments into %select{non-type|template}0"
" template parameter%1 %2">;
@@ -3999,6 +4170,9 @@ def err_variable_instantiates_to_function : Error<
def err_nested_name_spec_non_tag : Error<
"type %0 cannot be used prior to '::' because it has no members">;
+def err_using_pack_expansion_empty : Error<
+ "%select{|member}0 using declaration %1 instantiates to an empty pack">;
+
// C++ Explicit Instantiation
def err_explicit_instantiation_duplicate : Error<
"duplicate explicit instantiation of %0">;
@@ -4007,14 +4181,10 @@ def ext_explicit_instantiation_duplicate : ExtWarn<
InGroup<MicrosoftTemplate>;
def note_previous_explicit_instantiation : Note<
"previous explicit instantiation is here">;
-def ext_explicit_instantiation_after_specialization : Extension<
- "explicit instantiation of %0 that occurs after an explicit "
- "specialization will be ignored (C++11 extension)">,
- InGroup<CXX11>;
-def warn_cxx98_compat_explicit_instantiation_after_specialization : Warning<
- "explicit instantiation of %0 that occurs after an explicit "
- "specialization is incompatible with C++98">,
- InGroup<CXX98CompatPedantic>, DefaultIgnore;
+def warn_explicit_instantiation_after_specialization : Warning<
+ "explicit instantiation of %0 that occurs after an explicit "
+ "specialization has no effect">,
+ InGroup<DiagGroup<"instantiation-after-specialization">>;
def note_previous_template_specialization : Note<
"previous template specialization is here">;
def err_explicit_instantiation_nontemplate_type : Error<
@@ -4054,7 +4224,7 @@ def err_explicit_instantiation_member_function_not_instantiated : Error<
def err_explicit_instantiation_ambiguous : Error<
"partial ordering for explicit instantiation of %0 is ambiguous">;
def note_explicit_instantiation_candidate : Note<
- "explicit instantiation candidate function template here %0">;
+ "explicit instantiation candidate function %q0 template here %1">;
def err_explicit_instantiation_inline : Error<
"explicit instantiation cannot be 'inline'">;
def warn_explicit_instantiation_inline_0x : Warning<
@@ -4222,15 +4392,6 @@ def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neith
def note_not_found_by_two_phase_lookup : Note<"%0 should be declared prior to the "
"call site%select{| or in %2| or in an associated namespace of one of its arguments}1">;
def err_undeclared_use : Error<"use of undeclared %0">;
-def warn_partial_availability : Warning<"%0 is only available conditionally">,
- InGroup<PartialAvailability>, DefaultIgnore;
-def note_partial_availability_silence : Note<
- "explicitly redeclare %0 to silence this warning">;
-def warn_partial_message : Warning<"%0 is partial: %1">,
- InGroup<PartialAvailability>, DefaultIgnore;
-def warn_partial_fwdclass_message : Warning<
- "%0 may be partial because the receiver type is unknown">,
- InGroup<PartialAvailability>, DefaultIgnore;
def warn_deprecated : Warning<"%0 is deprecated">,
InGroup<DeprecatedDeclarations>;
def warn_property_method_deprecated :
@@ -4259,8 +4420,6 @@ def note_availability_specified_here : Note<
"%select{unavailable|deleted|deprecated|partial}1 here">;
def note_implicitly_deleted : Note<
"explicitly defaulted function was implicitly deleted here">;
-def note_inherited_deleted_here : Note<
- "deleted constructor was inherited here">;
def warn_not_enough_argument : Warning<
"not enough variable arguments in %0 declaration to fit a sentinel">,
InGroup<Sentinel>;
@@ -4274,6 +4433,10 @@ def warn_missing_prototype : Warning<
InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;
def note_declaration_not_a_prototype : Note<
"this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function">;
+def warn_strict_prototypes : Warning<
+ "this %select{function declaration is not|"
+ "old-style function definition is not preceded by}0 a prototype">,
+ InGroup<DiagGroup<"strict-prototypes">>, DefaultIgnore;
def warn_missing_variable_declarations : Warning<
"no previous extern declaration for non-static variable %0">,
InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;
@@ -4385,6 +4548,8 @@ def err_extern_c_global_conflict : Error<
"conflicts with declaration %select{in global scope|with C language linkage}0">;
def note_extern_c_global_conflict : Note<
"declared %select{in global scope|with C language linkage}0 here">;
+def note_extern_c_begins_here : Note<
+ "extern \"C\" language linkage specification begins here">;
def warn_weak_import : Warning <
"an already-declared variable is made a weak_import declaration %0">;
def ext_static_non_static : Extension<
@@ -4418,10 +4583,15 @@ def err_redefinition_different_typedef : Error<
"%select{typedef|type alias|type alias template}0 "
"redefinition with different types%diff{ ($ vs $)|}1,2">;
def err_tag_reference_non_tag : Error<
- "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template|a type alias template|a template template argument}0">;
+ "%select{non-struct type|non-class type|non-union type|non-enum "
+ "type|typedef|type alias|template|type alias template|template "
+ "template argument}1 %0 cannot be referenced with a "
+ "%select{struct|interface|union|class|enum}2 specifier">;
def err_tag_reference_conflict : Error<
- "implicit declaration introduced by elaborated type conflicts with "
- "%select{a declaration|a typedef|a type alias|a template}0 of the same name">;
+ "implicit declaration introduced by elaborated type conflicts with a "
+ "%select{non-struct type|non-class type|non-union type|non-enum "
+ "type|typedef|type alias|template|type alias template|template "
+ "template argument}0 of the same name">;
def err_dependent_tag_decl : Error<
"%select{declaration|definition}0 of "
"%select{struct|interface|union|class|enum}1 in a dependent scope">;
@@ -4490,9 +4660,6 @@ def err_vm_func_decl : Error<
"function declaration cannot have variably modified type">;
def err_array_too_large : Error<
"array is too large (%0 elements)">;
-def warn_array_new_too_large : Warning<"array is too large (%0 elements)">,
- // FIXME PR11644: ", will throw std::bad_array_new_length at runtime"
- InGroup<BadArrayNewLength>;
// -Wpadded, -Wpacked
def warn_padded_struct_field : Warning<
@@ -4510,9 +4677,6 @@ def warn_unnecessary_packed : Warning<
"packed attribute is unnecessary for %0">, InGroup<Packed>, DefaultIgnore;
def err_typecheck_negative_array_size : Error<"array size is negative">;
-def warn_typecheck_negative_array_new_size : Warning<"array size is negative">,
- // FIXME PR11644: ", will throw std::bad_array_new_length at runtime"
- InGroup<BadArrayNewLength>;
def warn_typecheck_function_qualifiers_ignored : Warning<
"'%0' qualifier on function type %1 has no effect">,
InGroup<IgnoredQualifiers>;
@@ -4683,6 +4847,8 @@ def note_protected_by_vla_type_alias : Note<
"jump bypasses initialization of VLA type alias">;
def note_protected_by_constexpr_if : Note<
"jump enters controlled statement of constexpr if">;
+def note_protected_by_if_available : Note<
+ "jump enters controlled statement of if available">;
def note_protected_by_vla : Note<
"jump bypasses initialization of variable length array">;
def note_protected_by_objc_try : Note<
@@ -4984,6 +5150,16 @@ def err_arc_inconsistent_property_ownership : Error<
} // end "ARC and @properties" category
+def warn_block_capture_autoreleasing : Warning<
+ "block captures an autoreleasing out-parameter, which may result in "
+ "use-after-free bugs">,
+ InGroup<BlockCaptureAutoReleasing>, DefaultIgnore;
+def note_declare_parameter_autoreleasing : Note<
+ "declare the parameter __autoreleasing explicitly to suppress this warning">;
+def note_declare_parameter_strong : Note<
+ "declare the parameter __strong or capture a __block __strong variable to "
+ "keep values alive across autorelease pools">;
+
def err_arc_atomic_ownership : Error<
"cannot perform atomic operation on a pointer to type %0: type has "
"non-trivial ownership">;
@@ -5232,7 +5408,7 @@ def err_typecheck_member_reference_struct_union : Error<
"member reference base type %0 is not a structure or union">;
def err_typecheck_member_reference_ivar : Error<
"%0 does not have a member named %1">;
-def error_arc_weak_ivar_access : Error<
+def err_arc_weak_ivar_access : Error<
"dereferencing a __weak pointer is not allowed due to possible "
"null value caused by race condition, assign it to strong variable first">;
def err_typecheck_member_reference_arrow : Error<
@@ -5408,7 +5584,7 @@ def err_typecheck_invalid_lvalue_addrof : Error<
"cannot take the address of an rvalue of type %0">;
def ext_typecheck_addrof_temporary : ExtWarn<
"taking the address of a temporary object of type %0">,
- InGroup<DiagGroup<"address-of-temporary">>, DefaultError;
+ InGroup<AddressOfTemporary>, DefaultError;
def err_typecheck_addrof_temporary : Error<
"taking the address of a temporary object of type %0">;
def err_typecheck_addrof_dtor : Error<
@@ -5432,6 +5608,9 @@ def warn_pointer_indirection_from_incompatible_type : Warning<
"dereference of type %1 that was reinterpret_cast from type %0 has undefined "
"behavior">,
InGroup<UndefinedReinterpretCast>, DefaultIgnore;
+def warn_taking_address_of_packed_member : Warning<
+ "taking address of packed member %0 of class or structure %q1 may result in an unaligned pointer value">,
+ InGroup<DiagGroup<"address-of-packed-member">>;
def err_objc_object_assignment : Error<
"cannot assign to class object (%0 invalid)">;
@@ -5444,6 +5623,8 @@ def ext_typecheck_ordered_comparison_of_pointer_integer : ExtWarn<
"ordered comparison between pointer and integer (%0 and %1)">;
def ext_typecheck_ordered_comparison_of_pointer_and_zero : Extension<
"ordered comparison between pointer and zero (%0 and %1) is an extension">;
+def err_typecheck_ordered_comparison_of_pointer_and_zero : Error<
+ "ordered comparison between pointer and zero (%0 and %1)">;
def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
"ordered comparison of function pointers (%0 and %1)">;
def ext_typecheck_comparison_of_fptr_to_void : Extension<
@@ -5464,9 +5645,6 @@ def err_cond_voidptr_arc : Error <
"in ARC mode">;
def err_typecheck_comparison_of_distinct_pointers : Error<
"comparison of distinct pointer types%diff{ ($ and $)|}0,1">;
-def ext_typecheck_comparison_of_distinct_pointers_nonstandard : ExtWarn<
- "comparison of distinct pointer types (%0 and %1) uses non-standard "
- "composite pointer type %2">, InGroup<CompareDistinctPointerType>;
def err_typecheck_op_on_nonoverlapping_address_space_pointers : Error<
"%select{comparison between %diff{ ($ and $)|}0,1"
"|arithmetic operation with operands of type %diff{ ($ and $)|}0,1"
@@ -5518,11 +5696,13 @@ def err_shift_rhs_only_vector : Error<
"requested shift is a vector of type %0 but the first operand is not a "
"vector (%1)">;
-def warn_logical_not_on_lhs_of_comparison : Warning<
- "logical not is only applied to the left hand side of this comparison">,
+def warn_logical_not_on_lhs_of_check : Warning<
+ "logical not is only applied to the left hand side of this "
+ "%select{comparison|bitwise operator}0">,
InGroup<LogicalNotParentheses>;
def note_logical_not_fix : Note<
- "add parentheses after the '!' to evaluate the comparison first">;
+ "add parentheses after the '!' to evaluate the "
+ "%select{comparison|bitwise operator}0 first">;
def note_logical_not_silence_with_parens : Note<
"add parentheses around left hand side expression to silence this warning">;
@@ -5630,7 +5810,7 @@ def ext_gnu_ptr_func_arith : Extension<
"arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 function "
"type%select{|s}2 %1%select{| and %3}2 is a GNU extension">,
InGroup<PointerArith>;
-def error_readonly_message_assignment : Error<
+def err_readonly_message_assignment : Error<
"assigning to 'readonly' return result of an Objective-C message not allowed">;
def ext_integer_increment_complex : Extension<
"ISO C does not support '++'/'--' on complex integer type %0">;
@@ -5646,7 +5826,7 @@ def err_nogetter_property_compound_assignment : Error<
"a getter method is needed to perform a compound assignment on a property">;
def err_nogetter_property_incdec : Error<
"no getter method %1 for %select{increment|decrement}0 of property">;
-def error_no_subobject_property_setting : Error<
+def err_no_subobject_property_setting : Error<
"expression is not assignable">;
def err_qualified_objc_access : Error<
"%select{property|instance variable}0 access cannot be qualified with '%1'">;
@@ -5676,12 +5856,12 @@ def warn_instance_method_not_found_with_typo : Warning<
def warn_class_method_not_found_with_typo : Warning<
"class method %objcclass0 not found (return type defaults to 'id')"
"; did you mean %objcclass2?">, InGroup<MethodAccess>;
-def error_method_not_found_with_typo : Error<
+def err_method_not_found_with_typo : Error<
"%select{instance|class}1 method %0 not found "
"; did you mean %2?">;
-def error_no_super_class_message : Error<
+def err_no_super_class_message : Error<
"no @interface declaration found in class messaging of %0">;
-def error_root_class_cannot_use_super : Error<
+def err_root_class_cannot_use_super : Error<
"%0 cannot use 'super' because it is a root class">;
def err_invalid_receiver_to_message_super : Error<
"'super' is only valid in a method body">;
@@ -5696,11 +5876,11 @@ def err_bad_receiver_type : Error<"bad receiver type %0">;
def err_incomplete_receiver_type : Error<"incomplete receiver type %0">;
def err_unknown_receiver_suggest : Error<
"unknown receiver %0; did you mean %1?">;
-def error_objc_throw_expects_object : Error<
+def err_objc_throw_expects_object : Error<
"@throw requires an Objective-C object type (%0 invalid)">;
-def error_objc_synchronized_expects_object : Error<
+def err_objc_synchronized_expects_object : Error<
"@synchronized requires an Objective-C object type (%0 invalid)">;
-def error_rethrow_used_outside_catch : Error<
+def err_rethrow_used_outside_catch : Error<
"@throw (rethrow) used outside of a @catch block">;
def err_attribute_multiple_objc_gc : Error<
"multiple garbage collection attributes specified for type">;
@@ -5815,6 +5995,9 @@ def err_bad_cxx_cast_vector_to_vector_different_size : Error<
def err_bad_lvalue_to_rvalue_cast : Error<
"cannot cast from lvalue of type %1 to rvalue reference type %2; types are "
"not compatible">;
+def err_bad_rvalue_to_rvalue_cast : Error<
+ "cannot cast from rvalue of type %1 to rvalue reference type %2; types are "
+ "not compatible">;
def err_bad_static_cast_pointer_nonpointer : Error<
"cannot cast from type %1 to pointer type %2">;
def err_bad_static_cast_member_pointer_nonmp : Error<
@@ -5934,6 +6117,10 @@ def err_no_suitable_delete_member_function_found : Error<
"no suitable member %0 in %1">;
def err_ambiguous_suitable_delete_member_function_found : Error<
"multiple suitable %0 functions in %1">;
+def warn_ambiguous_suitable_delete_function_found : Warning<
+ "multiple suitable %0 functions for %1; no 'operator delete' function "
+ "will be invoked if initialization throws an exception">,
+ InGroup<DiagGroup<"ambiguous-delete">>;
def note_member_declared_here : Note<
"member %0 declared here">;
def err_decrement_bool : Error<"cannot decrement expression of type bool">;
@@ -6005,7 +6192,8 @@ def note_hidden_overloaded_virtual_declared_here : Note<
"%select{none|const|restrict|const and restrict|volatile|const and volatile|"
"volatile and restrict|const, volatile, and restrict}2 vs "
"%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}3)}1">;
+ "volatile and restrict|const, volatile, and restrict}3)"
+ "|: different exception specifications}1">;
def warn_using_directive_in_header : Warning<
"using namespace directive in global context in header">,
InGroup<HeaderHygiene>, DefaultIgnore;
@@ -6093,6 +6281,8 @@ let CategoryName = "Lambda Issue" in {
def note_lambda_to_block_conv : Note<
"implicit capture of lambda object due to conversion to block pointer "
"here">;
+ def note_var_explicitly_captured_here : Note<"variable %0 is"
+ "%select{| explicitly}1 captured here">;
// C++14 lambda init-captures.
def warn_cxx11_compat_init_capture : Warning<
@@ -6247,13 +6437,14 @@ def err_typecheck_convert_incompatible : Error<
"%select{none|const|restrict|const and restrict|volatile|const and volatile|"
"volatile and restrict|const, volatile, and restrict}5 vs "
"%select{none|const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}6)}4">;
+ "volatile and restrict|const, volatile, and restrict}6)"
+ "|: different exception specifications}4">;
def err_typecheck_missing_return_type_incompatible : Error<
"%diff{return type $ must match previous return type $|"
"return type must match previous return type}0,1 when %select{block "
"literal|lambda expression}2 has unspecified explicit return type">;
-def not_incomplete_class_and_qualified_id : Note<
+def note_incomplete_class_and_qualified_id : Note<
"conformance of forward class %0 to protocol %1 can not be confirmed">;
def warn_incompatible_qualified_id : Warning<
"%select{%diff{assigning to $ from incompatible type $|"
@@ -6351,6 +6542,24 @@ def ext_typecheck_convert_incompatible_pointer : ExtWarn<
"; remove *|"
"; remove &}3">,
InGroup<IncompatiblePointerTypes>;
+def ext_typecheck_convert_incompatible_function_pointer : ExtWarn<
+ "incompatible function pointer types "
+ "%select{%diff{assigning to $ from $|assigning to different types}0,1"
+ "|%diff{passing $ to parameter of type $|"
+ "passing to parameter of different type}0,1"
+ "|%diff{returning $ from a function with result type $|"
+ "returning from function with different return type}0,1"
+ "|%diff{converting $ to type $|converting between types}0,1"
+ "|%diff{initializing $ with an expression of type $|"
+ "initializing with expression of different type}0,1"
+ "|%diff{sending $ to parameter of type $|"
+ "sending to parameter of different type}0,1"
+ "|%diff{casting $ to type $|casting between types}0,1}2"
+ "%select{|; dereference with *|"
+ "; take the address with &|"
+ "; remove *|"
+ "; remove &}3">,
+ InGroup<IncompatibleFunctionPointerTypes>;
def ext_typecheck_convert_discards_qualifiers : ExtWarn<
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
"|%diff{passing $ to parameter of type $|"
@@ -6586,6 +6795,7 @@ def err_deleted_function_use : Error<"attempt to use a deleted function">;
def err_deleted_inherited_ctor_use : Error<
"constructor inherited by %0 from base class %1 is implicitly deleted">;
+def note_called_by : Note<"called by %0">;
def err_kern_type_not_void_return : Error<
"kernel function type %0 must have void return type">;
def err_kern_is_nonstatic_method : Error<
@@ -6599,6 +6809,9 @@ def err_global_call_not_config : Error<
def err_ref_bad_target : Error<
"reference to %select{__device__|__global__|__host__|__host__ __device__}0 "
"function %1 in %select{__device__|__global__|__host__|__host__ __device__}2 function">;
+def err_ref_bad_target_global_initializer : Error<
+ "reference to %select{__device__|__global__|__host__|__host__ __device__}0 "
+ "function %1 in global initializer">;
def warn_kern_is_method : Extension<
"kernel function %0 is a member function; this may not be accepted by nvcc">,
InGroup<CudaCompat>;
@@ -6616,14 +6829,31 @@ def err_cuda_unattributed_constexpr_cannot_overload_device : Error<
"attribute, or build with -fno-cuda-host-device-constexpr.">;
def note_cuda_conflicting_device_function_declared_here : Note<
"conflicting __device__ function declared here">;
+def err_cuda_device_exceptions : Error<
+ "cannot use '%0' in "
+ "%select{__device__|__global__|__host__|__host__ __device__}1 function">;
def err_dynamic_var_init : Error<
"dynamic initialization is not supported for "
"__device__, __constant__, and __shared__ variables.">;
def err_shared_var_init : Error<
"initialization is not supported for __shared__ variables.">;
def err_device_static_local_var : Error<
- "Within a __device__/__global__ function, "
- "only __shared__ variables may be marked \"static\"">;
+ "within a %select{__device__|__global__|__host__|__host__ __device__}0 "
+ "function, only __shared__ variables may be marked 'static'">;
+def err_cuda_vla : Error<
+ "cannot use variable-length arrays in "
+ "%select{__device__|__global__|__host__|__host__ __device__}0 functions">;
+def err_cuda_extern_shared : Error<"__shared__ variable %0 cannot be 'extern'">;
+def err_cuda_host_shared : Error<
+ "__shared__ local variables not allowed in "
+ "%select{__device__|__global__|__host__|__host__ __device__}0 functions">;
+def err_cuda_nonglobal_constant : Error<"__constant__ variables must be global">;
+def err_cuda_ovl_target : Error<
+ "%select{__device__|__global__|__host__|__host__ __device__}0 function %1 "
+ "cannot overload %select{__device__|__global__|__host__|__host__ __device__}2 function %3">;
+def note_cuda_ovl_candidate_target_mismatch : Note<
+ "candidate template ignored: target attributes do not match">;
+
def warn_non_pod_vararg_with_format_string : Warning<
"cannot pass %select{non-POD|non-trivial}0 object of type %1 to variadic "
"%select{function|block|method|constructor}2; expected type from format "
@@ -6705,9 +6935,6 @@ def err_typecheck_expect_scalar_operand : Error<
"operand of type %0 where arithmetic or pointer type is required">;
def err_typecheck_cond_incompatible_operands : Error<
"incompatible operand types%diff{ ($ and $)|}0,1">;
-def ext_typecheck_cond_incompatible_operands_nonstandard : ExtWarn<
- "incompatible operand types%diff{ ($ and $)|}0,1 use non-standard composite "
- "pointer type %2">;
def err_cast_selector_expr : Error<
"cannot type cast @selector expression">;
def ext_typecheck_cond_incompatible_pointers : ExtWarn<
@@ -6741,7 +6968,7 @@ def warn_side_effects_typeid : Warning<
"operand to 'typeid'">, InGroup<PotentiallyEvaluatedExpression>;
def warn_unused_result : Warning<
"ignoring return value of function declared with %0 attribute">,
- InGroup<DiagGroup<"unused-result">>;
+ InGroup<UnusedResult>;
def warn_unused_volatile : Warning<
"expression result unused; assign into a variable to force a volatile load">,
InGroup<DiagGroup<"unused-volatile-lvalue">>;
@@ -6759,7 +6986,12 @@ def note_inequality_comparison_to_or_assign : Note<
def err_incomplete_type_used_in_type_trait_expr : Error<
"incomplete type %0 used in type trait expression">;
-
+
+def err_require_constant_init_failed : Error<
+ "variable does not have a constant initializer">;
+def note_declared_required_constant_init_here : Note<
+ "required by 'require_constant_initializer' attribute here">;
+
def err_dimension_expr_not_constant_integer : Error<
"dimension expression does not evaluate to a constant unsigned int">;
@@ -6843,6 +7075,10 @@ let CategoryName = "Inline Assembly Issue" in {
"constraint '%0' is already present here">;
}
+ def error_inoutput_conflict_with_clobber : Error<
+ "asm-specifier for input or output variable conflicts with asm"
+ " clobber list">;
+
let CategoryName = "Semantic Issue" in {
def err_invalid_conversion_between_vectors : Error<
@@ -6911,12 +7147,11 @@ 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_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 err_in_class_initializer_not_yet_parsed : Error<
+ "default member initializer for %1 needed within definition of enclosing "
+ "class %0 outside of member functions">;
+def note_in_class_initializer_not_yet_parsed : Note<
+ "default member initializer declared here">;
def err_in_class_initializer_cycle
: Error<"default member initializer for %0 uses itself">;
def err_exception_spec_cycle
@@ -6971,14 +7206,9 @@ def ext_ms_anonymous_record : ExtWarn<
InGroup<MicrosoftAnonTag>;
// C++ local classes
-def err_reference_to_local_var_in_enclosing_function : Error<
- "reference to local variable %0 declared in enclosing function %1">;
-def err_reference_to_local_var_in_enclosing_block : Error<
- "reference to local variable %0 declared in enclosing block literal">;
-def err_reference_to_local_var_in_enclosing_lambda : Error<
- "reference to local variable %0 declared in enclosing lambda expression">;
-def err_reference_to_local_var_in_enclosing_context : Error<
- "reference to local variable %0 declared in enclosing context">;
+def err_reference_to_local_in_enclosing_context : Error<
+ "reference to local %select{variable|binding}1 %0 declared in enclosing "
+ "%select{%3|block literal|lambda expression|context}2">;
def err_static_data_member_not_allowed_in_local_class : Error<
"static data member %0 not allowed in local class %1">;
@@ -7281,6 +7511,12 @@ def warn_format_non_standard: Warning<
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_format_invalid_annotation : Warning<
+ "using '%0' format specifier annotation outside of os_log()/os_trace()">,
+ InGroup<Format>;
+def warn_format_P_no_precision : Warning<
+ "using '%%P' format specifier without precision">,
+ InGroup<Format>;
def warn_printf_ignored_flag: Warning<
"flag '%0' is ignored when flag '%1' is present">,
InGroup<Format>;
@@ -7417,6 +7653,15 @@ def warn_cfstring_truncated : Warning<
"belong to the input codeset UTF-8">,
InGroup<DiagGroup<"CFString-literal">>;
+// os_log checking
+// TODO: separate diagnostic for os_trace()
+def err_os_log_format_not_string_constant : Error<
+ "os_log() format argument is not a string constant">;
+def err_os_log_argument_too_big : Error<
+ "os_log() argument %0 is too big (%1 bytes, max %2)">;
+def warn_os_log_format_narg : Error<
+ "os_log() '%%n' format specifier is not allowed">, DefaultError;
+
// Statements.
def err_continue_not_in_loop : Error<
"'continue' statement not in loop statement">;
@@ -7641,6 +7886,8 @@ def err_ppc_builtin_only_on_pwr7 : Error<
"this builtin is only valid on POWER7 or later CPUs">;
def err_x86_builtin_32_bit_tgt : Error<
"this builtin is only available on x86-64 targets">;
+def err_x86_builtin_invalid_rounding : Error<
+ "invalid rounding argument">;
def err_builtin_longjmp_unsupported : Error<
"__builtin_longjmp is not supported for the current target">;
@@ -7713,8 +7960,6 @@ def ext_c99_array_usage : Extension<
def err_c99_array_usage_cxx : Error<
"%select{qualifier in |static |}0array size %select{||'[*] '}0is a C99 "
"feature, not permitted in C++">;
- def err_type_requires_extension : Error<
- "use of type %0 requires %1 extension to be enabled">;
def err_type_unsupported : Error<
"%0 is not supported on this target">;
def err_nsconsumed_attribute_mismatch : Error<
@@ -7730,7 +7975,7 @@ def err_invalid_protocol_qualifiers : Error<
"invalid protocol qualifiers on non-ObjC type">;
def warn_ivar_use_hidden : Warning<
"local declaration of %0 hides instance variable">,
- InGroup<DiagGroup<"shadow-ivar">>;
+ InGroup<ShadowIvar>;
def warn_direct_initialize_call : Warning<
"explicit call to +initialize results in duplicate call to +initialize">,
InGroup<ExplicitInitializeCall>;
@@ -7738,13 +7983,11 @@ 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<
+def err_ivar_use_in_class_method : Error<
"instance variable %0 accessed in class method">;
-def error_implicit_ivar_access : Error<
- "instance variable %0 cannot be accessed because 'self' has been redeclared">;
-def error_private_ivar_access : Error<"instance variable %0 is private">,
+def err_private_ivar_access : Error<"instance variable %0 is private">,
AccessControl;
-def error_protected_ivar_access : Error<"instance variable %0 is protected">,
+def err_protected_ivar_access : Error<"instance variable %0 is protected">,
AccessControl;
def warn_maynot_respond : Warning<"%0 may not respond to %1">;
def ext_typecheck_base_super : Warning<
@@ -7831,6 +8074,9 @@ def err_unsupported_unknown_any_call : Error<
def err_unknown_any_addrof : Error<
"the address of a declaration with unknown type "
"can only be cast to a pointer type">;
+def err_unknown_any_addrof_call : Error<
+ "address-of operator cannot be applied to a call to a function with "
+ "unknown return type">;
def err_unknown_any_var_function_type : Error<
"variable %0 with unknown type cannot be given a function type">;
def err_unknown_any_function : Error<
@@ -7853,14 +8099,15 @@ def err_static_kernel : Error<
"kernel functions cannot be declared static">;
def err_opencl_ptrptr_kernel_param : Error<
"kernel parameter cannot be declared as a pointer to a pointer">;
-def err_opencl_private_ptr_kernel_param : Error<
- "kernel parameter cannot be declared as a pointer to the __private address space">;
+def err_kernel_arg_address_space : Error<
+ "pointer arguments to kernel functions must reside in '__global', "
+ "'__constant' or '__local' address space">;
def err_opencl_function_variable : Error<
"%select{non-kernel function|function scope}0 variable cannot be declared in %1 address space">;
def err_static_function_scope : Error<
"variables in function scope cannot be declared static">;
def err_opencl_bitfields : Error<
- "bitfields are not supported in OpenCL">;
+ "bit-fields are not supported in OpenCL">;
def err_opencl_vla : Error<
"variable length arrays are not supported in OpenCL">;
def err_bad_kernel_param_type : Error<
@@ -7871,19 +8118,21 @@ def note_within_field_of_type : Note<
"within field of type %0 declared here">;
def note_illegal_field_declared_here : Note<
"field of illegal %select{type|pointer type}0 %1 declared here">;
-def err_event_t_global_var : Error<
- "the event_t type cannot be used to declare a program scope variable">;
def err_opencl_type_struct_or_union_field : Error<
"the %0 type cannot be used to declare a structure or union field">;
def err_event_t_addr_space_qual : Error<
"the event_t type can only be used with __private address space qualifier">;
def err_expected_kernel_void_return_type : Error<
"kernel must have void return type">;
+def err_sampler_initializer_not_integer : Error<
+ "sampler_t initialization requires 32-bit integer, not %0">;
+def warn_sampler_initializer_invalid_bits : Warning<
+ "sampler initializer has invalid %0 bits">, InGroup<SpirCompat>, DefaultIgnore;
def err_sampler_argument_required : Error<
"sampler_t variable required - got %0">;
def err_wrong_sampler_addressspace: Error<
"sampler type cannot be used with the __local and __global address space qualifiers">;
-def error_opencl_cast_non_zero_to_event_t : Error<
+def err_opencl_cast_non_zero_to_event_t : Error<
"cannot cast non-zero value '%0' to 'event_t'">;
def err_opencl_global_invalid_addr_space : Error<
"%select{program scope|static local|extern}0 variable must reside in %1 address space">;
@@ -7903,8 +8152,6 @@ def err_atomic_init_constant : Error<
" in the declaration statement in the program scope">;
def err_opencl_implicit_vector_conversion : Error<
"implicit conversions between vector types (%0 and %1) are not permitted">;
-def err_opencl_block_proto_variadic : Error<
- "invalid block prototype, variadic arguments are not allowed in OpenCL">;
def err_opencl_invalid_type_array : Error<
"array of %0 type is invalid in OpenCL">;
def err_opencl_ternary_with_block : Error<
@@ -7916,6 +8163,10 @@ def err_opencl_type_can_only_be_used_as_function_parameter : Error <
def warn_opencl_attr_deprecated_ignored : Warning <
"%0 attribute is deprecated and ignored in OpenCL version %1">,
InGroup<IgnoredAttributes>;
+def err_opencl_variadic_function : Error<
+ "invalid prototype, variadic arguments are not allowed in OpenCL">;
+def err_opencl_requires_extension : Error<
+ "use of %select{type |declaration}0%1 requires %2 extension to be enabled">;
// OpenCL v2.0 s6.13.6 -- Builtin Pipe Functions
def err_opencl_builtin_pipe_first_arg : Error<
@@ -7963,11 +8214,16 @@ def err_opencl_enqueue_kernel_expected_type : Error<
def err_opencl_enqueue_kernel_local_size_args : Error<
"mismatch in number of block parameters and local size arguments passed">;
def err_opencl_enqueue_kernel_invalid_local_size_type : Error<
- "local memory sizes need to be specified as uint">;
+ "illegal call to enqueue_kernel, parameter needs to be specified as integer type">;
def err_opencl_enqueue_kernel_blocks_non_local_void_args : Error<
"blocks used in device side enqueue are expected to have parameters of type 'local void*'">;
def err_opencl_enqueue_kernel_blocks_no_args : Error<
"blocks in this form of device side enqueue call are expected to have have no parameters">;
+
+// OpenCL v2.2 s2.1.2.3 - Vector Component Access
+def ext_opencl_ext_vector_type_rgba_selector: ExtWarn<
+ "vector component name '%0' is an OpenCL version 2.2 feature">,
+ InGroup<OpenCLUnsupportedRGBA>;
} // end of sema category
let CategoryName = "OpenMP Issue" in {
@@ -8248,8 +8504,10 @@ def warn_omp_section_is_char : Warning<"array section %select{lower bound|length
InGroup<CharSubscript>, DefaultIgnore;
def err_omp_section_incomplete_type : Error<
"section of pointer to incomplete type %0">;
-def err_omp_section_negative : Error<
- "section %select{lower bound|length}0 is evaluated to a negative value %1">;
+def err_omp_section_not_subset_of_array : Error<
+ "array section must be a subset of the original array">;
+def err_omp_section_length_negative : Error<
+ "section length is evaluated to a negative value %0">;
def err_omp_section_length_undefined : Error<
"section length is unspecified and cannot be inferred because subscripted value is %select{not an array|an array of unknown bound}0">;
def err_omp_wrong_linear_modifier : Error<
@@ -8330,8 +8588,8 @@ def err_omp_schedule_nonmonotonic_ordered : Error<
"'schedule' clause with 'nonmonotonic' modifier cannot be specified if an 'ordered' clause is specified">;
def err_omp_ordered_simd : Error<
"'ordered' clause with a parameter can not be specified in '#pragma omp %0' directive">;
-def err_omp_variable_in_map_and_dsa : Error<
- "%0 variable cannot be in a map clause in '#pragma omp %1' directive">;
+def err_omp_variable_in_given_clause_and_dsa : Error<
+ "%0 variable cannot be in a %1 clause in '#pragma omp %2' directive">;
def err_omp_param_or_this_in_clause : Error<
"expected reference to one of the parameters of function %0%select{| or 'this'}1">;
def err_omp_expected_uniform_param : Error<
@@ -8340,13 +8598,16 @@ def err_omp_expected_int_param : Error<
"expected a reference to an integer-typed parameter">;
def err_omp_at_least_one_motion_clause_required : Error<
"expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'">;
-def err_omp_usedeviceptr_not_a_pointer : Error<
+def err_omp_usedeviceptr_not_a_pointer : Error<
"expected pointer or reference to pointer in 'use_device_ptr' clause">;
def err_omp_argument_type_isdeviceptr : Error <
"expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'">;
def warn_omp_nesting_simd : Warning<
"OpenMP only allows an ordered construct with the simd clause nested in a simd construct">,
InGroup<SourceUsesOpenMP>;
+def err_omp_orphaned_device_directive : Error<
+ "orphaned 'omp %0' directives are prohibited"
+ "; perhaps you forget to enclose the directive into a %select{|||target |teams }1region?">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
@@ -8371,10 +8632,21 @@ def note_related_result_type_inferred : Note<
def note_related_result_type_explicit : Note<
"%select{overridden|current}0 method is explicitly declared 'instancetype'"
"%select{| and is expected to return an instance of its class type}0">;
+def err_invalid_type_for_program_scope_var : Error<
+ "the %0 type cannot be used to declare a program scope variable">;
}
let CategoryName = "Modules Issue" in {
+def err_module_interface_implementation_mismatch : Error<
+ "%select{'module'|'module partition'|'module implementation'}0 declaration "
+ "found while %select{not |not |}0building module interface">;
+def err_current_module_name_mismatch : Error<
+ "module name '%0' specified on command line does not match name of module">;
+def err_module_redefinition : Error<
+ "redefinition of module '%0'">;
+def note_prev_module_definition : Note<"previously defined here">;
+def note_prev_module_definition_from_ast_file : Note<"module loaded from '%0'">;
def err_module_private_specialization : Error<
"%select{template|partial|member}0 specialization cannot be "
"declared __module_private__">;
@@ -8401,8 +8673,6 @@ def ext_module_import_in_extern_c : ExtWarn<
"import of C++ module '%0' appears within extern \"C\" language linkage "
"specification">, DefaultError,
InGroup<DiagGroup<"module-import-in-extern-c">>;
-def note_module_import_in_extern_c : Note<
- "extern \"C\" language linkage specification begins here">;
def err_module_import_not_at_top_level_fatal : Error<
"import of module '%0' appears within %1">, DefaultFatal;
def ext_module_import_not_at_top_level_noop : ExtWarn<
@@ -8413,6 +8683,8 @@ def err_module_self_import : Error<
"import of module '%0' appears within same top-level module '%1'">;
def err_module_import_in_implementation : Error<
"@import of module '%0' in implementation of '%1'; use #import">;
+def err_export_within_export : Error<
+ "export declaration appears within another export declaration">;
def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
"ambiguous use of internal linkage declaration %0 defined in multiple modules">,
@@ -8433,20 +8705,19 @@ def err_coroutine_unevaluated_context : Error<
"'%0' cannot be used in an unevaluated context">;
def err_coroutine_outside_function : Error<
"'%0' cannot be used outside a function">;
-def err_coroutine_ctor_dtor : Error<
- "'%1' cannot be used in a %select{constructor|destructor}0">;
-def err_coroutine_constexpr : Error<
- "'%0' cannot be used in a constexpr function">;
-def err_coroutine_varargs : Error<
- "'%0' cannot be used in a varargs function">;
+def err_coroutine_invalid_func_context : Error<
+ "'%1' cannot be used in %select{a constructor|a destructor"
+ "|a copy assignment operator|a move assignment operator|the 'main' function"
+ "|a constexpr function|a function with a deduced return type"
+ "|a varargs function}0">;
def ext_coroutine_without_co_await_co_yield : ExtWarn<
"'co_return' used in a function "
"that uses neither 'co_await' nor 'co_yield'">,
InGroup<DiagGroup<"coreturn-without-coawait">>;
def err_implied_std_coroutine_traits_not_found : Error<
- "you need to include <coroutine> before defining a coroutine">;
+ "you need to include <experimental/coroutine> before defining a coroutine">;
def err_malformed_std_coroutine_traits : Error<
- "'std::coroutine_traits' must be a class template">;
+ "'std::experimental::coroutine_traits' must be a class template">;
def err_implied_std_coroutine_traits_promise_type_not_found : Error<
"this function cannot be a coroutine: %q0 has no member named 'promise_type'">;
def err_implied_std_coroutine_traits_promise_type_not_class : Error<
@@ -8454,6 +8725,13 @@ def err_implied_std_coroutine_traits_promise_type_not_class : Error<
def err_coroutine_traits_missing_specialization : Error<
"this function cannot be a coroutine: missing definition of "
"specialization %q0">;
+def err_implied_std_current_exception_not_found : Error<
+ "you need to include <exception> before defining a coroutine that implicitly "
+ "uses 'set_exception'">;
+def err_malformed_std_current_exception : Error<
+ "'std::current_exception' must be a function">;
+def err_coroutine_promise_return_ill_formed : Error<
+ "%0 declares both 'return_value' and 'return_void'">;
}
let CategoryName = "Documentation Issue" in {
@@ -8510,6 +8788,19 @@ def warn_nullability_missing : Warning<
"%select{pointer|block pointer|member pointer}0 is missing a nullability "
"type specifier (_Nonnull, _Nullable, or _Null_unspecified)">,
InGroup<NullabilityCompleteness>;
+def warn_nullability_missing_array : Warning<
+ "array parameter is missing a nullability type specifier (_Nonnull, "
+ "_Nullable, or _Null_unspecified)">,
+ InGroup<NullabilityCompletenessOnArrays>;
+def note_nullability_fix_it : Note<
+ "insert '%select{_Nonnull|_Nullable|_Null_unspecified}0' if the "
+ "%select{pointer|block pointer|member pointer|array parameter}1 "
+ "%select{should never be null|may be null|should not declare nullability}0">;
+
+def warn_nullability_inferred_on_nested_type : Warning<
+ "inferring '_Nonnull' for pointer type within %select{array|reference}0 is "
+ "deprecated">,
+ InGroup<NullabilityInferredOnNestedType>;
def err_objc_type_arg_explicit_nullability : Error<
"type argument %0 cannot explicitly specify nullability">;
@@ -8603,4 +8894,8 @@ def warn_block_literal_qualifiers_on_omitted_return_type : Warning<
"'%0' qualifier on omitted return type %1 has no effect">,
InGroup<IgnoredQualifiers>;
+def ext_warn_gnu_final : ExtWarn<
+ "__final is a GNU extension, consider using C++11 final">,
+ InGroup<GccCompat>;
+
} // end of sema component.
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 16c77435558f..066a1f5fa68f 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -21,6 +21,12 @@ def err_fe_pch_malformed_block : Error<
def err_fe_pch_file_modified : Error<
"file '%0' has been modified since the precompiled header '%1' was built">,
DefaultFatal;
+def err_fe_module_file_modified : Error<
+ "file '%0' has been modified since the module file '%1' was built">,
+ DefaultFatal;
+def err_fe_ast_file_modified : Error<
+ "file '%0' has been modified since the AST file '%1' was built">,
+ DefaultFatal;
def err_fe_pch_file_overridden : Error<
"file '%0' from the precompiled header has been overridden">;
def note_pch_required_by : Note<"'%0' required by '%1'">;
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index b6a9ca702842..b817dd20c301 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -16,7 +16,6 @@
#define LLVM_CLANG_BASIC_FILEMANAGER_H
#include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/LLVM.h"
#include "clang/Basic/VirtualFileSystem.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -24,25 +23,32 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
+#include <ctime>
#include <memory>
#include <map>
+#include <string>
namespace llvm {
+
class MemoryBuffer;
-}
+
+} // end namespace llvm
namespace clang {
-class FileManager;
+
class FileSystemStatCache;
/// \brief Cached information about one directory (either on disk or in
/// the virtual file system).
class DirectoryEntry {
- const char *Name; // Name of the directory.
friend class FileManager;
+
+ StringRef Name; // Name of the directory.
+
public:
- DirectoryEntry() : Name(nullptr) {}
- const char *getName() const { return Name; }
+ StringRef getName() const { return Name; }
};
/// \brief Cached information about one file (either on disk
@@ -51,7 +57,9 @@ public:
/// If the 'File' member is valid, then this FileEntry has an open file
/// descriptor for the file.
class FileEntry {
- const char *Name; // Name of the file.
+ friend class FileManager;
+
+ StringRef Name; // Name of the file.
std::string RealPathName; // Real path to the file; could be empty.
off_t Size; // File size in bytes.
time_t ModTime; // Modification time of file.
@@ -64,25 +72,16 @@ class FileEntry {
/// \brief The open file, if it is owned by the \p FileEntry.
mutable std::unique_ptr<vfs::File> File;
- friend class FileManager;
-
- void operator=(const FileEntry &) = delete;
public:
FileEntry()
: UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false)
{}
- // FIXME: this is here to allow putting FileEntry in std::map. Once we have
- // emplace, we shouldn't need a copy constructor anymore.
- /// Intentionally does not copy fields that are not set in an uninitialized
- /// \c FileEntry.
- FileEntry(const FileEntry &FE) : UniqueID(FE.UniqueID),
- IsNamedPipe(FE.IsNamedPipe), InPCH(FE.InPCH), IsValid(FE.IsValid) {
- assert(!isValid() && "Cannot copy an initialized FileEntry");
- }
+ FileEntry(const FileEntry &) = delete;
+ FileEntry &operator=(const FileEntry &) = delete;
- const char *getName() const { return Name; }
+ StringRef getName() const { return Name; }
StringRef tryGetRealPathName() const { return RealPathName; }
bool isValid() const { return IsValid; }
off_t getSize() const { return Size; }
@@ -165,7 +164,7 @@ class FileManager : public RefCountedBase<FileManager> {
// Caching.
std::unique_ptr<FileSystemStatCache> StatCache;
- bool getStatValue(const char *Path, FileData &Data, bool isFile,
+ bool getStatValue(StringRef Path, FileData &Data, bool isFile,
std::unique_ptr<vfs::File> *F);
/// Add all ancestors of the given path (pointing to either a file
@@ -285,6 +284,6 @@ public:
void PrintStats() const;
};
-} // end namespace clang
+} // end namespace clang
-#endif
+#endif // LLVM_CLANG_BASIC_FILEMANAGER_H
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
index cad91893489b..75f986b59bdd 100644
--- a/include/clang/Basic/FileSystemStatCache.h
+++ b/include/clang/Basic/FileSystemStatCache.h
@@ -68,7 +68,7 @@ public:
/// success for directories (not files). On a successful file lookup, the
/// implementation can optionally fill in \p F with a valid \p File object and
/// the client guarantees that it will close it.
- static bool get(const char *Path, FileData &Data, bool isFile,
+ static bool get(StringRef Path, FileData &Data, bool isFile,
std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache,
vfs::FileSystem &FS);
@@ -92,11 +92,11 @@ protected:
// FIXME: The pointer here is a non-owning/optional reference to the
// unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but
// Optional needs some work to support references so this isn't possible yet.
- virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
+ virtual LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
std::unique_ptr<vfs::File> *F,
vfs::FileSystem &FS) = 0;
- LookupResult statChained(const char *Path, FileData &Data, bool isFile,
+ LookupResult statChained(StringRef Path, FileData &Data, bool isFile,
std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
if (FileSystemStatCache *Next = getNextStatCache())
return Next->getStat(Path, Data, isFile, F, FS);
@@ -121,7 +121,7 @@ public:
iterator begin() const { return StatCalls.begin(); }
iterator end() const { return StatCalls.end(); }
- LookupResult getStat(const char *Path, FileData &Data, bool isFile,
+ LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
std::unique_ptr<vfs::File> *F,
vfs::FileSystem &FS) override;
};
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index fffb50493bfe..3001d0b1b0c7 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -18,16 +18,26 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/TokenKinds.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <new>
#include <string>
+#include <utility>
namespace llvm {
+
template <typename T> struct DenseMapInfo;
-}
+
+} // end namespace llvm
namespace clang {
+
class LangOptions;
class IdentifierInfo;
class IdentifierTable;
@@ -38,13 +48,14 @@ namespace clang {
/// \brief A simple pair of identifier info and location.
typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
-
/// One of these records is kept for each identifier that
/// is lexed. This contains information about whether the token was \#define'd,
/// is a language keyword, or if it is a front-end token of some sort (e.g. a
/// variable or function name). The preprocessor keeps this information in a
/// set, and all tok::identifier tokens have a pointer to one of these.
class IdentifierInfo {
+ friend class IdentifierTable;
+
unsigned TokenID : 9; // Front-end token ID or tok::identifier.
// Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
// First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values
@@ -77,21 +88,18 @@ class IdentifierInfo {
void *FETokenInfo; // Managed by the language front-end.
llvm::StringMapEntry<IdentifierInfo*> *Entry;
- IdentifierInfo(const IdentifierInfo&) = delete;
- void operator=(const IdentifierInfo&) = delete;
-
- friend class IdentifierTable;
-
public:
IdentifierInfo();
-
+ IdentifierInfo(const IdentifierInfo &) = delete;
+ IdentifierInfo &operator=(const IdentifierInfo &) = delete;
/// \brief Return true if this is the identifier for the specified string.
///
/// This is intended to be used for string literals only: II->isStr("foo").
template <std::size_t StrLen>
bool isStr(const char (&Str)[StrLen]) const {
- return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1);
+ return getLength() == StrLen-1 &&
+ memcmp(getNameStart(), Str, StrLen-1) == 0;
}
/// \brief Return the beginning of the actual null-terminated string for this
@@ -137,7 +145,7 @@ public:
HasMacro = Val;
if (Val) {
- NeedsHandleIdentifier = 1;
+ NeedsHandleIdentifier = true;
HadMacro = true;
} else {
RecomputeNeedsHandleIdentifier();
@@ -205,8 +213,7 @@ public:
/// \brief Return a value indicating whether this is a builtin function.
///
- /// 0 is not-built-in. 1 is builtin-for-some-nonprimary-target.
- /// 2+ are specific builtin functions.
+ /// 0 is not-built-in. 1+ are specific builtin functions.
unsigned getBuiltinID() const {
if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
@@ -229,7 +236,7 @@ public:
void setIsExtensionToken(bool Val) {
IsExtension = Val;
if (Val)
- NeedsHandleIdentifier = 1;
+ NeedsHandleIdentifier = true;
else
RecomputeNeedsHandleIdentifier();
}
@@ -243,7 +250,7 @@ public:
void setIsFutureCompatKeyword(bool Val) {
IsFutureCompatKeyword = Val;
if (Val)
- NeedsHandleIdentifier = 1;
+ NeedsHandleIdentifier = true;
else
RecomputeNeedsHandleIdentifier();
}
@@ -253,7 +260,7 @@ public:
void setIsPoisoned(bool Value = true) {
IsPoisoned = Value;
if (Value)
- NeedsHandleIdentifier = 1;
+ NeedsHandleIdentifier = true;
else
RecomputeNeedsHandleIdentifier();
}
@@ -266,7 +273,7 @@ public:
void setIsCPlusPlusOperatorKeyword(bool Val = true) {
IsCPPOperatorKeyword = Val;
if (Val)
- NeedsHandleIdentifier = 1;
+ NeedsHandleIdentifier = true;
else
RecomputeNeedsHandleIdentifier();
}
@@ -371,6 +378,7 @@ private:
class PoisonIdentifierRAIIObject {
IdentifierInfo *const II;
const bool OldValue;
+
public:
PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue)
: II(II), OldValue(II ? II->isPoisoned() : false) {
@@ -395,14 +403,13 @@ public:
/// operation. Subclasses of this iterator type will provide the
/// actual functionality.
class IdentifierIterator {
-private:
- IdentifierIterator(const IdentifierIterator &) = delete;
- void operator=(const IdentifierIterator &) = delete;
-
protected:
- IdentifierIterator() { }
+ IdentifierIterator() = default;
public:
+ IdentifierIterator(const IdentifierIterator &) = delete;
+ IdentifierIterator &operator=(const IdentifierIterator &) = delete;
+
virtual ~IdentifierIterator();
/// \brief Retrieve the next string in the identifier table and
@@ -537,7 +544,7 @@ public:
iterator begin() const { return HashTable.begin(); }
iterator end() const { return HashTable.end(); }
- unsigned size() const { return HashTable.size(); }
+ unsigned size() const { return HashTable.size(); }
/// \brief Print some statistics to stderr that indicate how well the
/// hashing is doing.
@@ -654,6 +661,7 @@ class Selector {
return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
return nullptr;
}
+
MultiKeywordSelector *getMultiKeywordSelector() const {
return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags);
}
@@ -682,6 +690,7 @@ public:
bool operator!=(Selector RHS) const {
return InfoPtr != RHS.InfoPtr;
}
+
void *getAsOpaquePtr() const {
return reinterpret_cast<void*>(InfoPtr);
}
@@ -693,12 +702,13 @@ public:
bool isKeywordSelector() const {
return getIdentifierInfoFlag() != ZeroArg;
}
+
bool isUnarySelector() const {
return getIdentifierInfoFlag() == ZeroArg;
}
+
unsigned getNumArgs() const;
-
/// \brief Retrieve the identifier at a given position in the selector.
///
/// Note that the identifier pointer returned may be NULL. Clients that only
@@ -743,6 +753,7 @@ public:
static Selector getEmptyMarker() {
return Selector(uintptr_t(-1));
}
+
static Selector getTombstoneMarker() {
return Selector(uintptr_t(-2));
}
@@ -754,10 +765,11 @@ public:
/// multi-keyword caching.
class SelectorTable {
void *Impl; // Actually a SelectorTableImpl
- SelectorTable(const SelectorTable &) = delete;
- void operator=(const SelectorTable &) = delete;
+
public:
SelectorTable();
+ SelectorTable(const SelectorTable &) = delete;
+ SelectorTable &operator=(const SelectorTable &) = delete;
~SelectorTable();
/// \brief Can create any sort of selector.
@@ -826,6 +838,7 @@ public:
} // end namespace clang
namespace llvm {
+
/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
/// DenseSets.
template <>
@@ -833,6 +846,7 @@ struct DenseMapInfo<clang::Selector> {
static inline clang::Selector getEmptyKey() {
return clang::Selector::getEmptyMarker();
}
+
static inline clang::Selector getTombstoneKey() {
return clang::Selector::getTombstoneMarker();
}
@@ -855,9 +869,11 @@ public:
static inline const void *getAsVoidPointer(clang::Selector P) {
return P.getAsOpaquePtr();
}
+
static inline clang::Selector getFromVoidPointer(const void *P) {
return clang::Selector(reinterpret_cast<uintptr_t>(P));
}
+
enum { NumLowBitsAvailable = 0 };
};
@@ -869,9 +885,11 @@ public:
static inline void *getAsVoidPointer(clang::IdentifierInfo* P) {
return P;
}
+
static inline clang::IdentifierInfo *getFromVoidPointer(void *P) {
return static_cast<clang::IdentifierInfo*>(P);
}
+
enum { NumLowBitsAvailable = 1 };
};
@@ -881,11 +899,14 @@ public:
static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
return P;
}
+
static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
return static_cast<const clang::IdentifierInfo*>(P);
}
+
enum { NumLowBitsAvailable = 1 };
};
-} // end namespace llvm
-#endif
+} // end namespace llvm
+
+#endif // LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h
index 0e6ff9259a15..f32ab5e11bd4 100644
--- a/include/clang/Basic/LLVM.h
+++ b/include/clang/Basic/LLVM.h
@@ -30,6 +30,7 @@ namespace llvm {
class Twine;
template<typename T> class ArrayRef;
template<typename T> class MutableArrayRef;
+ template<typename T> class OwningArrayRef;
template<unsigned InternalLen> class SmallString;
template<typename T, unsigned N> class SmallVector;
template<typename T> class SmallVectorImpl;
@@ -42,7 +43,6 @@ namespace llvm {
template <typename T> class IntrusiveRefCntPtr;
template <typename T> struct IntrusiveRefCntPtrInfo;
template <class Derived> class RefCountedBase;
- class RefCountedBaseVPTR;
class raw_ostream;
class raw_pwrite_stream;
@@ -65,6 +65,7 @@ namespace clang {
using llvm::Twine;
using llvm::ArrayRef;
using llvm::MutableArrayRef;
+ using llvm::OwningArrayRef;
using llvm::SmallString;
using llvm::SmallVector;
using llvm::SmallVectorImpl;
@@ -74,7 +75,6 @@ namespace clang {
using llvm::IntrusiveRefCntPtr;
using llvm::IntrusiveRefCntPtrInfo;
using llvm::RefCountedBase;
- using llvm::RefCountedBaseVPTR;
using llvm::raw_ostream;
using llvm::raw_pwrite_stream;
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index 03561961dd21..47db50c52b74 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -133,7 +133,8 @@ LANGOPT(Freestanding, 1, 0, "freestanding implementation")
LANGOPT(NoBuiltin , 1, 0, "disable builtin functions")
LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions")
LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly")
-LANGOPT(Coroutines , 1, 0, "C++ coroutines")
+LANGOPT(CoroutinesTS , 1, 0, "C++ coroutines TS")
+LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments")
BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers")
LANGOPT(POSIXThreads , 1, 0, "POSIX thread support")
@@ -142,7 +143,9 @@ BENIGN_LANGOPT(EmitAllDecls , 1, 0, "emitting all declarations")
LANGOPT(MathErrno , 1, 1, "errno in math functions")
BENIGN_LANGOPT(HeinousExtensions , 1, 0, "extensions that we really don't like and may be ripped out at any time")
LANGOPT(Modules , 1, 0, "modules extension to C")
-BENIGN_LANGOPT(CompilingModule, 1, 0, "compiling a module interface")
+COMPATIBLE_LANGOPT(ModulesTS , 1, 0, "C++ Modules TS")
+BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 2, CMK_None,
+ "compiling a module interface")
COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses")
BENIGN_LANGOPT(ModulesSearchAll , 1, 1, "searching even non-imported modules to find unresolved references")
COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "requiring declaration of module uses and all headers to be in modules")
@@ -193,7 +196,9 @@ LANGOPT(CUDAHostDeviceConstexpr, 1, 1, "treating unattributed constexpr function
LANGOPT(CUDADeviceFlushDenormalsToZero, 1, 0, "flushing denormals to zero")
LANGOPT(CUDADeviceApproxTranscendentals, 1, 0, "using approximate transcendental functions")
-LANGOPT(SizedDeallocation , 1, 0, "enable sized deallocation functions")
+LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
+LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
+LANGOPT(NewAlignOverride , 32, 0, "maximum alignment guaranteed by '::operator new(size_t)'")
LANGOPT(ConceptsTS , 1, 0, "enable C++ Extensions for Concepts")
BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records")
@@ -234,7 +239,7 @@ ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
BENIGN_LANGOPT(ArrowDepth, 32, 256,
"maximum number of operator->s to follow")
-BENIGN_LANGOPT(InstantiationDepth, 32, 256,
+BENIGN_LANGOPT(InstantiationDepth, 32, 1024,
"maximum template instantiation depth")
BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
"maximum constexpr call depth")
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 6ec499f1c74a..10635b11225e 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -58,6 +58,12 @@ public:
SOB_Trapping // -ftrapv
};
+ enum CompilingModuleKind {
+ CMK_None, ///< Not compiling a module interface at all.
+ CMK_ModuleMap, ///< Compiling a module from a module map.
+ CMK_ModuleInterface ///< Compiling a C++ modules TS module interface unit.
+ };
+
enum PragmaMSPointersToMembersKind {
PPTMK_BestCase,
PPTMK_FullGeneralitySingleInheritance,
@@ -126,6 +132,10 @@ public:
/// host code generation.
std::string OMPHostIRFile;
+ /// \brief Indicates whether the front-end is explicitly told that the
+ /// input is a header file (i.e. -x c-header).
+ bool IsHeaderFile;
+
LangOptions();
// Define accessors/mutators for language options of enumeration type.
@@ -134,7 +144,12 @@ public:
Type get##Name() const { return static_cast<Type>(Name); } \
void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
#include "clang/Basic/LangOptions.def"
-
+
+ /// Are we compiling a module interface (.cppm or module map)?
+ bool isCompilingModule() const {
+ return getCompilingModule() != CMK_None;
+ }
+
bool isSignedOverflowDefined() const {
return getSignedOverflowBehavior() == SOB_Defined;
}
@@ -154,7 +169,7 @@ public:
/// \brief Is this a libc/libm function that is no longer recognized as a
/// builtin because a -fno-builtin-* option has been specified?
- bool isNoBuiltinFunc(const char *Name) const;
+ bool isNoBuiltinFunc(StringRef Name) const;
};
/// \brief Floating point control options
diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h
index 8b15c8ed6ee8..e96fb568c009 100644
--- a/include/clang/Basic/Linkage.h
+++ b/include/clang/Basic/Linkage.h
@@ -69,6 +69,10 @@ enum GVALinkage {
GVA_StrongODR
};
+inline bool isDiscardableGVALinkage(GVALinkage L) {
+ return L <= GVA_DiscardableODR;
+}
+
inline bool isExternallyVisible(Linkage L) {
return L == ExternalLinkage || L == VisibleNoLinkage;
}
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 1702fb1114d7..31c5c7ec9ca8 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -201,6 +201,10 @@ public:
/// built.
unsigned ConfigMacrosExhaustive : 1;
+ /// \brief Whether files in this module can only include non-modular headers
+ /// and headers from used modules.
+ unsigned NoUndeclaredIncludes : 1;
+
/// \brief Describes the visibility of the various names within a
/// particular module.
enum NameVisibilityKind {
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index 6975b6c9bb9e..78fc89988245 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -312,6 +312,7 @@ public:
bool hasARCUnsafeClaimAutoreleasedReturnValue() const {
switch (getKind()) {
case MacOSX:
+ case FragileMacOSX:
return getVersion() >= VersionTuple(10, 11);
case iOS:
return getVersion() >= VersionTuple(9);
diff --git a/include/clang/Basic/OpenCLExtensions.def b/include/clang/Basic/OpenCLExtensions.def
index c5776d3bab43..360fec4281ac 100644
--- a/include/clang/Basic/OpenCLExtensions.def
+++ b/include/clang/Basic/OpenCLExtensions.def
@@ -67,6 +67,7 @@ OPENCLEXT_INTERNAL(cl_khr_spir, 120, ~0U)
// OpenCL 2.0.
OPENCLEXT_INTERNAL(cl_khr_egl_event, 200, ~0U)
OPENCLEXT_INTERNAL(cl_khr_egl_image, 200, ~0U)
+OPENCLEXT_INTERNAL(cl_khr_mipmap_image, 200, ~0U)
OPENCLEXT_INTERNAL(cl_khr_srgb_image_writes, 200, ~0U)
OPENCLEXT_INTERNAL(cl_khr_subgroups, 200, ~0U)
OPENCLEXT_INTERNAL(cl_khr_terminate_context, 200, ~0U)
@@ -74,6 +75,10 @@ OPENCLEXT_INTERNAL(cl_khr_terminate_context, 200, ~0U)
// Clang Extensions.
OPENCLEXT_INTERNAL(cl_clang_storage_class_specifiers, 100, ~0U)
+// AMD OpenCL extensions
+OPENCLEXT_INTERNAL(cl_amd_media_ops, 100, ~0U)
+OPENCLEXT_INTERNAL(cl_amd_media_ops2, 100, ~0U)
+
#undef OPENCLEXT_INTERNAL
#ifdef OPENCLEXT
diff --git a/include/clang/Basic/OpenCLImageTypes.def b/include/clang/Basic/OpenCLImageTypes.def
index 9b929929e2ba..1ca12f683beb 100644
--- a/include/clang/Basic/OpenCLImageTypes.def
+++ b/include/clang/Basic/OpenCLImageTypes.def
@@ -7,76 +7,82 @@
//
//===----------------------------------------------------------------------===//
// This file extends builtin types database with OpenCL image singleton types.
-// Custom code should define one of those two macros:
-// GENERIC_IMAGE_TYPE(Type, Id) - a generic image with its Id without an
+// Custom code should define one of those three macros:
+// GENERIC_IMAGE_TYPE(Type, Id) - a generic image with its Id without an
// access type
// IMAGE_TYPE(Type, Id, SingletonId, AccessType, CGSuffix) - an image type
-// with given ID, singleton ID access type and a codegen suffix
+// with given ID, singleton ID access type and a codegen suffix
+// GENERIC_IMAGE_TYPE_EXT(Type, Id, Ext) - a generic image with its Id and
+// required extension without an access type
#ifdef GENERIC_IMAGE_TYPE
-#define IMAGE_READ_TYPE(Type, Id) GENERIC_IMAGE_TYPE(Type, Id)
-#define IMAGE_WRITE_TYPE(Type, Id)
-#define IMAGE_READ_WRITE_TYPE(Type, Id)
+#define IMAGE_READ_TYPE(Type, Id, Ext) GENERIC_IMAGE_TYPE(Type, Id)
+#define IMAGE_WRITE_TYPE(Type, Id, Ext)
+#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
-#else
+#elif defined(GENERIC_IMAGE_TYPE_EXT)
+#define IMAGE_READ_TYPE(Type, Id, Ext) GENERIC_IMAGE_TYPE_EXT(Type, Id##ROTy, Ext)
+#define IMAGE_WRITE_TYPE(Type, Id, Ext) GENERIC_IMAGE_TYPE_EXT(Type, Id##WOTy, Ext)
+#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext) GENERIC_IMAGE_TYPE_EXT(Type, Id##RWTy, Ext)
+#else
#ifndef IMAGE_READ_TYPE
-#define IMAGE_READ_TYPE(Type, Id) \
+#define IMAGE_READ_TYPE(Type, Id, Ext) \
IMAGE_TYPE(Type, Id##RO, Id##ROTy, read_only, ro)
#endif
#ifndef IMAGE_WRITE_TYPE
-#define IMAGE_WRITE_TYPE(Type, Id) \
+#define IMAGE_WRITE_TYPE(Type, Id, Ext) \
IMAGE_TYPE(Type, Id##WO, Id##WOTy, write_only, wo)
#endif
#ifndef IMAGE_READ_WRITE_TYPE
-#define IMAGE_READ_WRITE_TYPE(Type, Id) \
+#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext) \
IMAGE_TYPE(Type, Id##RW, Id##RWTy, read_write, rw)
#endif
#endif
-IMAGE_READ_TYPE(image1d, OCLImage1d)
-IMAGE_READ_TYPE(image1d_array, OCLImage1dArray)
-IMAGE_READ_TYPE(image1d_buffer, OCLImage1dBuffer)
-IMAGE_READ_TYPE(image2d, OCLImage2d)
-IMAGE_READ_TYPE(image2d_array, OCLImage2dArray)
-IMAGE_READ_TYPE(image2d_depth, OCLImage2dDepth)
-IMAGE_READ_TYPE(image2d_array_depth, OCLImage2dArrayDepth)
-IMAGE_READ_TYPE(image2d_msaa, OCLImage2dMSAA)
-IMAGE_READ_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA)
-IMAGE_READ_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth)
-IMAGE_READ_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth)
-IMAGE_READ_TYPE(image3d, OCLImage3d)
+IMAGE_READ_TYPE(image1d, OCLImage1d, "")
+IMAGE_READ_TYPE(image1d_array, OCLImage1dArray, "")
+IMAGE_READ_TYPE(image1d_buffer, OCLImage1dBuffer, "")
+IMAGE_READ_TYPE(image2d, OCLImage2d, "")
+IMAGE_READ_TYPE(image2d_array, OCLImage2dArray, "")
+IMAGE_READ_TYPE(image2d_depth, OCLImage2dDepth, "")
+IMAGE_READ_TYPE(image2d_array_depth, OCLImage2dArrayDepth, "")
+IMAGE_READ_TYPE(image2d_msaa, OCLImage2dMSAA, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_TYPE(image3d, OCLImage3d, "")
-IMAGE_WRITE_TYPE(image1d, OCLImage1d)
-IMAGE_WRITE_TYPE(image1d_array, OCLImage1dArray)
-IMAGE_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer)
-IMAGE_WRITE_TYPE(image2d, OCLImage2d)
-IMAGE_WRITE_TYPE(image2d_array, OCLImage2dArray)
-IMAGE_WRITE_TYPE(image2d_depth, OCLImage2dDepth)
-IMAGE_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth)
-IMAGE_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA)
-IMAGE_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA)
-IMAGE_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth)
-IMAGE_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth)
-IMAGE_WRITE_TYPE(image3d, OCLImage3d)
+IMAGE_WRITE_TYPE(image1d, OCLImage1d, "")
+IMAGE_WRITE_TYPE(image1d_array, OCLImage1dArray, "")
+IMAGE_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer, "")
+IMAGE_WRITE_TYPE(image2d, OCLImage2d, "")
+IMAGE_WRITE_TYPE(image2d_array, OCLImage2dArray, "")
+IMAGE_WRITE_TYPE(image2d_depth, OCLImage2dDepth, "")
+IMAGE_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth, "")
+IMAGE_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA, "cl_khr_gl_msaa_sharing")
+IMAGE_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA, "cl_khr_gl_msaa_sharing")
+IMAGE_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth, "cl_khr_gl_msaa_sharing")
+IMAGE_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth, "cl_khr_gl_msaa_sharing")
+IMAGE_WRITE_TYPE(image3d, OCLImage3d, "")
-IMAGE_READ_WRITE_TYPE(image1d, OCLImage1d)
-IMAGE_READ_WRITE_TYPE(image1d_array, OCLImage1dArray)
-IMAGE_READ_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer)
-IMAGE_READ_WRITE_TYPE(image2d, OCLImage2d)
-IMAGE_READ_WRITE_TYPE(image2d_array, OCLImage2dArray)
-IMAGE_READ_WRITE_TYPE(image2d_depth, OCLImage2dDepth)
-IMAGE_READ_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth)
-IMAGE_READ_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA)
-IMAGE_READ_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA)
-IMAGE_READ_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth)
-IMAGE_READ_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth)
-IMAGE_READ_WRITE_TYPE(image3d, OCLImage3d)
+IMAGE_READ_WRITE_TYPE(image1d, OCLImage1d, "")
+IMAGE_READ_WRITE_TYPE(image1d_array, OCLImage1dArray, "")
+IMAGE_READ_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer, "")
+IMAGE_READ_WRITE_TYPE(image2d, OCLImage2d, "")
+IMAGE_READ_WRITE_TYPE(image2d_array, OCLImage2dArray, "")
+IMAGE_READ_WRITE_TYPE(image2d_depth, OCLImage2dDepth, "")
+IMAGE_READ_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth, "")
+IMAGE_READ_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth, "cl_khr_gl_msaa_sharing")
+IMAGE_READ_WRITE_TYPE(image3d, OCLImage3d, "")
#undef IMAGE_TYPE
#undef GENERIC_IMAGE_TYPE
#undef IMAGE_READ_TYPE
#undef IMAGE_WRITE_TYPE
-#undef IMAGE_READ_WRITE_TYPE \ No newline at end of file
+#undef IMAGE_READ_WRITE_TYPE
diff --git a/include/clang/Basic/OpenCLOptions.h b/include/clang/Basic/OpenCLOptions.h
index 4aaa3d74ccbf..cc850f0b0b24 100644
--- a/include/clang/Basic/OpenCLOptions.h
+++ b/include/clang/Basic/OpenCLOptions.h
@@ -15,52 +15,122 @@
#ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H
#define LLVM_CLANG_BASIC_OPENCLOPTIONS_H
-#include <string>
-#include <vector>
+#include "llvm/ADT/StringMap.h"
namespace clang {
/// \brief OpenCL supported extensions and optional core features
class OpenCLOptions {
+ struct Info {
+ bool Supported; // Is this option supported
+ bool Enabled; // Is this option enabled
+ unsigned Avail; // Option starts to be available in this OpenCL version
+ unsigned Core; // Option becomes (optional) core feature in this OpenCL
+ // version
+ Info(bool S = false, bool E = false, unsigned A = 100, unsigned C = ~0U)
+ :Supported(S), Enabled(E), Avail(A), Core(C){}
+ };
+ llvm::StringMap<Info> OptMap;
public:
-#define OPENCLEXT(nm) unsigned nm : 1;
-#include "clang/Basic/OpenCLExtensions.def"
+ bool isKnown(llvm::StringRef Ext) const {
+ return OptMap.find(Ext) != OptMap.end();
+ }
- OpenCLOptions() {
-#define OPENCLEXT(nm) nm = 0;
-#include "clang/Basic/OpenCLExtensions.def"
+ bool isEnabled(llvm::StringRef Ext) const {
+ return OptMap.find(Ext)->second.Enabled;
}
- // Enable all options.
- void setAll() {
-#define OPENCLEXT(nm) nm = 1;
-#include "clang/Basic/OpenCLExtensions.def"
+ // Is supported as either an extension or an (optional) core feature for
+ // OpenCL version \p CLVer.
+ bool isSupported(llvm::StringRef Ext, unsigned CLVer) const {
+ auto I = OptMap.find(Ext)->getValue();
+ return I.Supported && I.Avail <= CLVer;
}
- // Is supported with OpenCL version \p OCLVer.
-#define OPENCLEXT_INTERNAL(Ext, Avail, ...) \
- bool is_##Ext##_supported(unsigned OCLVer) const { \
- return Ext && OCLVer >= Avail; \
+ // Is supported (optional) OpenCL core features for OpenCL version \p CLVer.
+ // For supported extension, return false.
+ bool isSupportedCore(llvm::StringRef Ext, unsigned CLVer) const {
+ auto I = OptMap.find(Ext)->getValue();
+ return I.Supported && I.Avail <= CLVer &&
+ I.Core != ~0U && CLVer >= I.Core;
}
-#include "clang/Basic/OpenCLExtensions.def"
+ // Is supported OpenCL extension for OpenCL version \p CLVer.
+ // For supported (optional) core feature, return false.
+ bool isSupportedExtension(llvm::StringRef Ext, unsigned CLVer) const {
+ auto I = OptMap.find(Ext)->getValue();
+ return I.Supported && I.Avail <= CLVer &&
+ (I.Core == ~0U || CLVer < I.Core);
+ }
- // Is supported OpenCL extension with OpenCL version \p OCLVer.
- // For supported optional core feature, return false.
-#define OPENCLEXT_INTERNAL(Ext, Avail, Core) \
- bool is_##Ext##_supported_extension(unsigned CLVer) const { \
- return is_##Ext##_supported(CLVer) && (Core == ~0U || CLVer < Core); \
+ void enable(llvm::StringRef Ext, bool V = true) {
+ OptMap[Ext].Enabled = V;
}
-#include "clang/Basic/OpenCLExtensions.def"
- // Is supported OpenCL core features with OpenCL version \p OCLVer.
- // For supported extension, return false.
-#define OPENCLEXT_INTERNAL(Ext, Avail, Core) \
- bool is_##Ext##_supported_core(unsigned CLVer) const { \
- return is_##Ext##_supported(CLVer) && Core != ~0U && CLVer >= Core; \
+ /// \brief Enable or disable support for OpenCL extensions
+ /// \param Ext name of the extension optionally prefixed with
+ /// '+' or '-'
+ /// \param V used when \p Ext is not prefixed by '+' or '-'
+ void support(llvm::StringRef Ext, bool V = true) {
+ assert(!Ext.empty() && "Extension is empty.");
+
+ switch (Ext[0]) {
+ case '+':
+ V = true;
+ Ext = Ext.drop_front();
+ break;
+ case '-':
+ V = false;
+ Ext = Ext.drop_front();
+ break;
+ }
+
+ if (Ext.equals("all")) {
+ supportAll(V);
+ return;
+ }
+ OptMap[Ext].Supported = V;
}
+
+ OpenCLOptions(){
+#define OPENCLEXT_INTERNAL(Ext, AvailVer, CoreVer) \
+ OptMap[#Ext].Avail = AvailVer; \
+ OptMap[#Ext].Core = CoreVer;
#include "clang/Basic/OpenCLExtensions.def"
+ }
+
+ void addSupport(const OpenCLOptions &Opts) {
+ for (auto &I:Opts.OptMap)
+ if (I.second.Supported)
+ OptMap[I.getKey()].Supported = true;
+ }
+
+ void copy(const OpenCLOptions &Opts) {
+ OptMap = Opts.OptMap;
+ }
+
+ // Turn on or off support of all options.
+ void supportAll(bool On = true) {
+ for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
+ E = OptMap.end(); I != E; ++I)
+ I->second.Supported = On;
+ }
+
+ void disableAll() {
+ for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
+ E = OptMap.end(); I != E; ++I)
+ I->second.Enabled = false;
+ }
+
+ void enableSupportedCore(unsigned CLVer) {
+ for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
+ E = OptMap.end(); I != E; ++I)
+ if (isSupportedCore(I->getKey(), CLVer))
+ I->second.Enabled = true;
+ }
+ friend class ASTWriter;
+ friend class ASTReader;
};
} // end namespace clang
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index 5189779809b8..808e0d2bb0c7 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -138,6 +138,30 @@
#ifndef OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE
#define OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(Name)
#endif
+#ifndef OPENMP_TARGET_SIMD_CLAUSE
+#define OPENMP_TARGET_SIMD_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TEAMS_DISTRIBUTE_CLAUSE
+#define OPENMP_TEAMS_DISTRIBUTE_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE
+#define OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE
+#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE
+#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TARGET_TEAMS_CLAUSE
+#define OPENMP_TARGET_TEAMS_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE
+#define OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE
+#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name)
+#endif
// OpenMP directives.
OPENMP_DIRECTIVE(threadprivate)
@@ -182,6 +206,14 @@ OPENMP_DIRECTIVE_EXT(distribute_parallel_for, "distribute parallel for")
OPENMP_DIRECTIVE_EXT(distribute_parallel_for_simd, "distribute parallel for simd")
OPENMP_DIRECTIVE_EXT(distribute_simd, "distribute simd")
OPENMP_DIRECTIVE_EXT(target_parallel_for_simd, "target parallel for simd")
+OPENMP_DIRECTIVE_EXT(target_simd, "target simd")
+OPENMP_DIRECTIVE_EXT(teams_distribute, "teams distribute")
+OPENMP_DIRECTIVE_EXT(teams_distribute_simd, "teams distribute simd")
+OPENMP_DIRECTIVE_EXT(teams_distribute_parallel_for_simd, "teams distribute parallel for simd")
+OPENMP_DIRECTIVE_EXT(teams_distribute_parallel_for, "teams distribute parallel for")
+OPENMP_DIRECTIVE_EXT(target_teams, "target teams")
+OPENMP_DIRECTIVE_EXT(target_teams_distribute, "target teams distribute")
+OPENMP_DIRECTIVE_EXT(target_teams_distribute_parallel_for, "target teams distribute parallel for")
// OpenMP clauses.
OPENMP_CLAUSE(if, OMPIfClause)
@@ -431,7 +463,6 @@ OPENMP_TARGET_EXIT_DATA_CLAUSE(nowait)
OPENMP_TARGET_EXIT_DATA_CLAUSE(depend)
// Clauses allowed for OpenMP directive 'target parallel'.
-// TODO: add target clauses 'is_device_ptr'
OPENMP_TARGET_PARALLEL_CLAUSE(if)
OPENMP_TARGET_PARALLEL_CLAUSE(device)
OPENMP_TARGET_PARALLEL_CLAUSE(map)
@@ -445,6 +476,7 @@ OPENMP_TARGET_PARALLEL_CLAUSE(default)
OPENMP_TARGET_PARALLEL_CLAUSE(proc_bind)
OPENMP_TARGET_PARALLEL_CLAUSE(shared)
OPENMP_TARGET_PARALLEL_CLAUSE(reduction)
+OPENMP_TARGET_PARALLEL_CLAUSE(is_device_ptr)
// Clauses allowed for OpenMP directive 'target parallel for'.
// TODO: add target clauses 'is_device_ptr'
@@ -620,6 +652,147 @@ OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(safelen)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned)
+// Clauses allowed for OpenMP directive 'target simd'.
+OPENMP_TARGET_SIMD_CLAUSE(if)
+OPENMP_TARGET_SIMD_CLAUSE(device)
+OPENMP_TARGET_SIMD_CLAUSE(map)
+OPENMP_TARGET_SIMD_CLAUSE(private)
+OPENMP_TARGET_SIMD_CLAUSE(nowait)
+OPENMP_TARGET_SIMD_CLAUSE(depend)
+OPENMP_TARGET_SIMD_CLAUSE(defaultmap)
+OPENMP_TARGET_SIMD_CLAUSE(firstprivate)
+OPENMP_TARGET_SIMD_CLAUSE(is_device_ptr)
+OPENMP_TARGET_SIMD_CLAUSE(lastprivate)
+OPENMP_TARGET_SIMD_CLAUSE(linear)
+OPENMP_TARGET_SIMD_CLAUSE(aligned)
+OPENMP_TARGET_SIMD_CLAUSE(safelen)
+OPENMP_TARGET_SIMD_CLAUSE(simdlen)
+OPENMP_TARGET_SIMD_CLAUSE(collapse)
+OPENMP_TARGET_SIMD_CLAUSE(reduction)
+
+// Clauses allowed for OpenMP directive 'teams distribute'.
+OPENMP_TEAMS_DISTRIBUTE_CLAUSE(default)
+OPENMP_TEAMS_DISTRIBUTE_CLAUSE(private)
+OPENMP_TEAMS_DISTRIBUTE_CLAUSE(firstprivate)
+OPENMP_TEAMS_DISTRIBUTE_CLAUSE(shared)
+OPENMP_TEAMS_DISTRIBUTE_CLAUSE(reduction)
+OPENMP_TEAMS_DISTRIBUTE_CLAUSE(num_teams)
+OPENMP_TEAMS_DISTRIBUTE_CLAUSE(thread_limit)
+OPENMP_TEAMS_DISTRIBUTE_CLAUSE(lastprivate)
+OPENMP_TEAMS_DISTRIBUTE_CLAUSE(collapse)
+OPENMP_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule)
+
+// Clauses allowed for OpenMP directive 'teams distribute simd'
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(default)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(private)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(firstprivate)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(shared)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(reduction)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(num_teams)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(thread_limit)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(lastprivate)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(collapse)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(dist_schedule)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen)
+
+// Clauses allowed for OpenMP directive 'teams distribute parallel for simd'
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_teams)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(thread_limit)
+
+// Clauses allowed for OpenMP directive 'teams distribute parallel for'
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(linear)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit)
+
+// Clauses allowed for OpenMP directive 'target teams'.
+OPENMP_TARGET_TEAMS_CLAUSE(if)
+OPENMP_TARGET_TEAMS_CLAUSE(device)
+OPENMP_TARGET_TEAMS_CLAUSE(map)
+OPENMP_TARGET_TEAMS_CLAUSE(private)
+OPENMP_TARGET_TEAMS_CLAUSE(nowait)
+OPENMP_TARGET_TEAMS_CLAUSE(depend)
+OPENMP_TARGET_TEAMS_CLAUSE(defaultmap)
+OPENMP_TARGET_TEAMS_CLAUSE(firstprivate)
+OPENMP_TARGET_TEAMS_CLAUSE(is_device_ptr)
+OPENMP_TARGET_TEAMS_CLAUSE(default)
+OPENMP_TARGET_TEAMS_CLAUSE(shared)
+OPENMP_TARGET_TEAMS_CLAUSE(reduction)
+OPENMP_TARGET_TEAMS_CLAUSE(num_teams)
+OPENMP_TARGET_TEAMS_CLAUSE(thread_limit)
+
+// Clauses allowed for OpenMP directive 'target teams distribute'.
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(if)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(device)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(map)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(private)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(nowait)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(depend)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(defaultmap)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(firstprivate)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(is_device_ptr)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(default)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(shared)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(reduction)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(num_teams)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(thread_limit)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(lastprivate)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(collapse)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule)
+
+// Clauses allowed for OpenMP directive 'target teams distribute parallel for'.
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(device)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(map)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(nowait)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(depend)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(defaultmap)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(is_device_ptr)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(linear)
+
#undef OPENMP_TASKLOOP_SIMD_CLAUSE
#undef OPENMP_TASKLOOP_CLAUSE
#undef OPENMP_LINEAR_KIND
@@ -662,3 +835,11 @@ OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned)
#undef OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE
#undef OPENMP_DISTRIBUTE_SIMD_CLAUSE
#undef OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE
+#undef OPENMP_TARGET_SIMD_CLAUSE
+#undef OPENMP_TEAMS_DISTRIBUTE_CLAUSE
+#undef OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE
+#undef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE
+#undef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE
+#undef OPENMP_TARGET_TEAMS_CLAUSE
+#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE
+#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE
diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h
index 0a8e890b7c44..60b9fcef9219 100644
--- a/include/clang/Basic/OpenMPKinds.h
+++ b/include/clang/Basic/OpenMPKinds.h
@@ -179,10 +179,18 @@ bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind);
/// otherwise - false.
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind);
-/// \brief Checks if the specified directive is a teams-kind directive.
+/// Checks if the specified composite/combined directive constitutes a teams
+/// directive in the outermost nest. For example
+/// 'omp teams distribute' or 'omp teams distribute parallel for'.
/// \param DKind Specified directive.
-/// \return true - the directive is a teams-like directive like 'omp teams',
-/// otherwise - false.
+/// \return true - the directive has teams on the outermost nest, otherwise -
+/// false.
+bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind);
+
+/// Checks if the specified directive is a teams-kind directive. For example,
+/// 'omp teams distribute' or 'omp target teams'.
+/// \param DKind Specified directive.
+/// \return true - the directive is a teams-like directive, otherwise - false.
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind);
/// \brief Checks if the specified directive is a simd directive.
@@ -198,6 +206,14 @@ bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind);
/// otherwise - false.
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind);
+/// Checks if the specified composite/combined directive constitutes a
+/// distribute directive in the outermost nest. For example,
+/// 'omp distribute parallel for' or 'omp distribute'.
+/// \param DKind Specified directive.
+/// \return true - the directive has distribute on the outermost nest.
+/// otherwise - false.
+bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind);
+
/// \brief Checks if the specified clause is one of private clauses like
/// 'private', 'firstprivate', 'reduction' etc..
/// \param Kind Clause kind.
diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h
index 84dd29138a80..61de82450cf7 100644
--- a/include/clang/Basic/PlistSupport.h
+++ b/include/clang/Basic/PlistSupport.h
@@ -10,7 +10,6 @@
#ifndef LLVM_CLANG_BASIC_PLISTSUPPORT_H
#define LLVM_CLANG_BASIC_PLISTSUPPORT_H
-#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 23ad73894fd3..c8fe2ab90c29 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -44,30 +44,34 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/Support/AlignOf.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
+#include <algorithm>
#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <map>
#include <memory>
+#include <string>
+#include <utility>
#include <vector>
namespace clang {
+class ASTReader;
+class ASTWriter;
class DiagnosticsEngine;
-class SourceManager;
-class FileManager;
-class FileEntry;
class LineTableInfo;
-class ASTWriter;
-class ASTReader;
+class SourceManager;
/// \brief Public enums and private classes that are part of the
/// SourceManager implementation.
///
namespace SrcMgr {
+
/// \brief Indicates whether a file or directory holds normal user code,
/// system code, or system code which is implicitly 'extern "C"' in C++ mode.
///
@@ -146,8 +150,6 @@ namespace SrcMgr {
SourceLineCache(nullptr), NumLines(0), BufferOverridden(false),
IsSystemFile(false), IsTransient(false) {}
- ~ContentCache();
-
/// The copy ctor does not allow copies where source object has either
/// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
/// is not transferred, so this is a logical error.
@@ -164,6 +166,10 @@ namespace SrcMgr {
NumLines = RHS.NumLines;
}
+ ContentCache &operator=(const ContentCache& RHS) = delete;
+
+ ~ContentCache();
+
/// \brief Returns the memory buffer for the associated content.
///
/// \param Diag Object through which diagnostics will be emitted if the
@@ -219,15 +225,11 @@ namespace SrcMgr {
bool shouldFreeBuffer() const {
return (Buffer.getInt() & DoNotFreeFlag) == 0;
}
-
- private:
- // Disable assignments.
- ContentCache &operator=(const ContentCache& RHS) = delete;
};
// Assert that the \c ContentCache objects will always be 8-byte aligned so
// that we can pack 3 bits of integer into pointers to such objects.
- static_assert(llvm::AlignOf<ContentCache>::Alignment >= 8,
+ static_assert(alignof(ContentCache) >= 8,
"ContentCache must be 8-byte aligned.");
/// \brief Information about a FileID, basically just the logical file
@@ -259,6 +261,7 @@ namespace SrcMgr {
friend class clang::SourceManager;
friend class clang::ASTWriter;
friend class clang::ASTReader;
+
public:
/// \brief Return a FileInfo object.
static FileInfo get(SourceLocation IL, const ContentCache *Con,
@@ -276,6 +279,7 @@ namespace SrcMgr {
SourceLocation getIncludeLoc() const {
return SourceLocation::getFromRawEncoding(IncludeLoc);
}
+
const ContentCache* getContentCache() const {
return reinterpret_cast<const ContentCache*>(Data & ~uintptr_t(7));
}
@@ -316,9 +320,11 @@ namespace SrcMgr {
SourceLocation getSpellingLoc() const {
return SourceLocation::getFromRawEncoding(SpellingLoc);
}
+
SourceLocation getExpansionLocStart() const {
return SourceLocation::getFromRawEncoding(ExpansionLocStart);
}
+
SourceLocation getExpansionLocEnd() const {
SourceLocation EndLoc =
SourceLocation::getFromRawEncoding(ExpansionLocEnd);
@@ -399,6 +405,7 @@ namespace SrcMgr {
FileInfo File;
ExpansionInfo Expansion;
};
+
public:
unsigned getOffset() const { return Offset; }
@@ -433,6 +440,7 @@ namespace SrcMgr {
return E;
}
};
+
} // end SrcMgr namespace.
/// \brief External source of source location entries.
@@ -453,7 +461,6 @@ public:
virtual std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID) = 0;
};
-
/// \brief Holds the cache used by isBeforeInTranslationUnit.
///
/// The cache structure is complex enough to be worth breaking out of
@@ -479,6 +486,7 @@ class InBeforeInTUCacheEntry {
/// if LQueryFID is a parent of RQueryFID (or vice versa) then these can be a
/// random token in the parent.
unsigned LCommonOffset, RCommonOffset;
+
public:
/// \brief Return true if the currently cached values match up with
/// the specified LHS/RHS query.
@@ -526,13 +534,12 @@ public:
LCommonOffset = lCommonOffset;
RCommonOffset = rCommonOffset;
}
-
};
/// \brief The stack used when building modules on demand, which is used
/// to provide a link between the source managers of the different compiler
/// instances.
-typedef ArrayRef<std::pair<std::string, FullSourceLoc> > ModuleBuildStack;
+typedef ArrayRef<std::pair<std::string, FullSourceLoc>> ModuleBuildStack;
/// \brief This class handles loading and caching of source files into memory.
///
@@ -667,7 +674,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
///
/// Used to cache results from and speed-up \c getDecomposedIncludedLoc
/// function.
- mutable llvm::DenseMap<FileID, std::pair<FileID, unsigned> > IncludedLocMap;
+ mutable llvm::DenseMap<FileID, std::pair<FileID, unsigned>> IncludedLocMap;
/// The key value into the IsBeforeInTUCache table.
typedef std::pair<FileID, FileID> IsBeforeInTUCacheKey;
@@ -694,7 +701,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// source location.
typedef std::map<unsigned, SourceLocation> MacroArgsMap;
- mutable llvm::DenseMap<FileID, MacroArgsMap *> MacroArgsCacheMap;
+ mutable llvm::DenseMap<FileID, std::unique_ptr<MacroArgsMap>>
+ MacroArgsCacheMap;
/// \brief The stack of modules being built, which is used to detect
/// cycles in the module dependency graph as modules are being built, as
@@ -705,12 +713,11 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// we can add a cc1-level option to do so.
SmallVector<std::pair<std::string, FullSourceLoc>, 2> StoredModuleBuildStack;
- // SourceManager doesn't support copy construction.
- explicit SourceManager(const SourceManager&) = delete;
- void operator=(const SourceManager&) = delete;
public:
SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr,
bool UserFilesAreVolatile = false);
+ explicit SourceManager(const SourceManager &) = delete;
+ SourceManager &operator=(const SourceManager &) = delete;
~SourceManager();
void clearIDTables();
@@ -1292,7 +1299,7 @@ public:
///
/// Note that this name does not respect \#line directives. Use
/// getPresumedLoc for normal clients.
- const char *getBufferName(SourceLocation Loc, bool *Invalid = nullptr) const;
+ StringRef getBufferName(SourceLocation Loc, bool *Invalid = nullptr) const;
/// \brief Return the file characteristic of the specified source
/// location, indicating whether this is a normal file, a system
@@ -1358,7 +1365,7 @@ public:
}
/// \brief Returns whether \p Loc is expanded from a macro in a system header.
- bool isInSystemMacro(SourceLocation loc) {
+ bool isInSystemMacro(SourceLocation loc) const {
return loc.isMacroID() && isInSystemHeader(getSpellingLoc(loc));
}
@@ -1673,7 +1680,7 @@ private:
std::pair<FileID, unsigned>
getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
unsigned Offset) const;
- void computeMacroArgsCache(MacroArgsMap *&MacroArgsCache, FileID FID) const;
+ void computeMacroArgsCache(MacroArgsMap &MacroArgsCache, FileID FID) const;
void associateFileChunkWithMacroArgExp(MacroArgsMap &MacroArgsCache,
FileID FID,
SourceLocation SpellLoc,
@@ -1713,7 +1720,6 @@ public:
}
};
-} // end namespace clang
-
+} // end namespace clang
-#endif
+#endif // LLVM_CLANG_BASIC_SOURCEMANAGER_H
diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h
index 27dea9f84b5a..e65c97b0031d 100644
--- a/include/clang/Basic/SourceManagerInternals.h
+++ b/include/clang/Basic/SourceManagerInternals.h
@@ -95,9 +95,9 @@ public:
}
unsigned getLineTableFilenameID(StringRef Str);
- const char *getFilename(unsigned ID) const {
+ StringRef getFilename(unsigned ID) const {
assert(ID < FilenamesByID.size() && "Invalid FilenameID");
- return FilenamesByID[ID]->getKeyData();
+ return FilenamesByID[ID]->getKey();
}
unsigned getNumFilenames() const { return FilenamesByID.size(); }
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index fffd4b1cd20b..369a36f3dca6 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -237,6 +237,7 @@ namespace clang {
CC_X86Pascal, // __attribute__((pascal))
CC_X86_64Win64, // __attribute__((ms_abi))
CC_X86_64SysV, // __attribute__((sysv_abi))
+ CC_X86RegCall, // __attribute__((regcall))
CC_AAPCS, // __attribute__((pcs("aapcs")))
CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
@@ -254,6 +255,7 @@ namespace clang {
case CC_X86StdCall:
case CC_X86FastCall:
case CC_X86ThisCall:
+ case CC_X86RegCall:
case CC_X86Pascal:
case CC_X86VectorCall:
case CC_SpirFunction:
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index 973b3bb6fd17..d8eed553d86e 100644
--- a/include/clang/Basic/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -85,6 +85,8 @@ def DesignatedInitExpr : DStmt<Expr>;
def DesignatedInitUpdateExpr : DStmt<Expr>;
def ImplicitValueInitExpr : DStmt<Expr>;
def NoInitExpr : DStmt<Expr>;
+def ArrayInitLoopExpr : DStmt<Expr>;
+def ArrayInitIndexExpr : DStmt<Expr>;
def ParenListExpr : DStmt<Expr>;
def VAArgExpr : DStmt<Expr>;
def GenericSelectionExpr : DStmt<Expr>;
@@ -233,3 +235,11 @@ def OMPDistributeParallelForDirective : DStmt<OMPLoopDirective>;
def OMPDistributeParallelForSimdDirective : DStmt<OMPLoopDirective>;
def OMPDistributeSimdDirective : DStmt<OMPLoopDirective>;
def OMPTargetParallelForSimdDirective : DStmt<OMPLoopDirective>;
+def OMPTargetSimdDirective : DStmt<OMPLoopDirective>;
+def OMPTeamsDistributeDirective : DStmt<OMPLoopDirective>;
+def OMPTeamsDistributeSimdDirective : DStmt<OMPLoopDirective>;
+def OMPTeamsDistributeParallelForSimdDirective : DStmt<OMPLoopDirective>;
+def OMPTeamsDistributeParallelForDirective : DStmt<OMPLoopDirective>;
+def OMPTargetTeamsDirective : DStmt<OMPExecutableDirective>;
+def OMPTargetTeamsDistributeDirective : DStmt<OMPLoopDirective>;
+def OMPTargetTeamsDistributeParallelForDirective : DStmt<OMPLoopDirective>;
diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h
index 623c0b64dbf3..5d45e162d9f6 100644
--- a/include/clang/Basic/TargetBuiltins.h
+++ b/include/clang/Basic/TargetBuiltins.h
@@ -85,12 +85,16 @@ namespace clang {
/// \brief X86 builtins
namespace X86 {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+ enum {
+ LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsX86.def"
- LastTSBuiltin
- };
+ FirstX86_64Builtin,
+ LastX86CommonBuiltin = FirstX86_64Builtin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsX86_64.def"
+ LastTSBuiltin
+ };
}
/// \brief Flags to identify the types for overloaded Neon builtins.
diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h
index f7d4b920ca15..7fb1f826b0f6 100644
--- a/include/clang/Basic/TargetCXXABI.h
+++ b/include/clang/Basic/TargetCXXABI.h
@@ -16,7 +16,6 @@
#ifndef LLVM_CLANG_BASIC_TARGETCXXABI_H
#define LLVM_CLANG_BASIC_TARGETCXXABI_H
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
namespace clang {
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index f458c166a7a8..208f8e8c7137 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -26,7 +26,6 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Support/DataTypes.h"
@@ -41,7 +40,9 @@ struct fltSemantics;
namespace clang {
class DiagnosticsEngine;
class LangOptions;
+class CodeGenOptions;
class MacroBuilder;
+class QualType;
class SourceLocation;
class SourceManager;
@@ -76,6 +77,7 @@ protected:
unsigned short MaxVectorAlign;
unsigned short MaxTLSAlign;
unsigned short SimdDefaultAlign;
+ unsigned short NewAlign;
std::unique_ptr<llvm::DataLayout> DataLayout;
const char *MCountName;
const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat,
@@ -93,6 +95,8 @@ protected:
unsigned HasBuiltinMSVaList : 1;
+ unsigned IsRenderScriptTarget : 1;
+
// TargetInfo Constructor. Default initializes all fields.
TargetInfo(const llvm::Triple &T);
@@ -292,6 +296,17 @@ public:
return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
}
+ /// \brief Return the maximum width of pointers on this target.
+ virtual uint64_t getMaxPointerWidth() const {
+ return PointerWidth;
+ }
+
+ /// \brief Get integer value for null pointer.
+ /// \param AddrSpace address space of pointee in source language.
+ virtual uint64_t getNullPointerValue(unsigned AddrSpace) const {
+ return 0;
+ }
+
/// \brief Return the size of '_Bool' and C++ 'bool' for this target, in bits.
unsigned getBoolWidth() const { return BoolWidth; }
@@ -346,6 +361,13 @@ public:
/// unless its alignment is explicitly reduced via attributes.
unsigned getMinGlobalAlign() const { return MinGlobalAlign; }
+ /// Return the largest alignment for which a suitably-sized allocation with
+ /// '::operator new(size_t)' is guaranteed to produce a correctly-aligned
+ /// pointer.
+ unsigned getNewAlign() const {
+ return NewAlign ? NewAlign : std::max(LongDoubleAlign, LongLongAlign);
+ }
+
/// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
/// bits.
unsigned getWCharWidth() const { return getTypeWidth(WCharType); }
@@ -566,6 +588,9 @@ public:
/// available on this target.
bool hasBuiltinMSVaList() const { return HasBuiltinMSVaList; }
+ /// Returns true for RenderScript.
+ bool isRenderScriptTarget() const { return IsRenderScriptTarget; }
+
/// \brief Returns whether the passed in string is a valid clobber in an
/// inline asm statement.
///
@@ -580,8 +605,16 @@ public:
/// \brief Returns the "normalized" GCC register name.
///
- /// For example, on x86 it will return "ax" when "eax" is passed in.
- StringRef getNormalizedGCCRegisterName(StringRef Name) const;
+ /// ReturnCannonical true will return the register name without any additions
+ /// such as "{}" or "%" in it's canonical form, for example:
+ /// ReturnCanonical = true and Name = "rax", will return "ax".
+ StringRef getNormalizedGCCRegisterName(StringRef Name,
+ bool ReturnCanonical = false) const;
+
+ virtual StringRef getConstraintRegister(const StringRef &Constraint,
+ const StringRef &Expression) const {
+ return "";
+ }
struct ConstraintInfo {
enum {
@@ -793,6 +826,10 @@ public:
/// language options which change the target configuration.
virtual void adjust(const LangOptions &Opts);
+ /// \brief Adjust target options based on codegen options.
+ virtual void adjustTargetOptions(const CodeGenOptions &CGOpts,
+ TargetOptions &TargetOpts) const {}
+
/// \brief Initialize the map with the default set of target features for the
/// CPU this should include all legal feature strings on the target.
///
@@ -925,6 +962,7 @@ public:
VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; }
bool isBigEndian() const { return BigEndian; }
+ bool isLittleEndian() const { return !BigEndian; }
enum CallingConvMethodType {
CCMT_Unknown,
@@ -966,12 +1004,19 @@ public:
return false;
}
- /// \brief Whether target allows to overalign ABI-specified prefered alignment
+ /// \brief Whether target allows to overalign ABI-specified preferred alignment
virtual bool allowsLargerPreferedTypeAlignment() const { return true; }
/// \brief Set supported OpenCL extensions and optional core features.
virtual void setSupportedOpenCLOpts() {}
+ /// \brief Set supported OpenCL extensions as written on command line
+ virtual void setOpenCLExtensionOpts() {
+ for (const auto &Ext : getTargetOpts().OpenCLExtensionsAsWritten) {
+ getTargetOpts().SupportedOpenCLOptions.support(Ext);
+ }
+ }
+
/// \brief Get supported OpenCL extensions and optional core features.
OpenCLOptions &getSupportedOpenCLOpts() {
return getTargetOpts().SupportedOpenCLOptions;
@@ -982,6 +1027,11 @@ public:
return getTargetOpts().SupportedOpenCLOptions;
}
+ /// \brief Get OpenCL image type address space.
+ virtual LangAS::ID getOpenCLImageAddrSpace() const {
+ return LangAS::opencl_global;
+ }
+
/// \brief Check the target is valid after it is fully initialized.
virtual bool validateTarget(DiagnosticsEngine &Diags) const {
return true;
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index fde294c92251..2889cce5963b 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -58,6 +58,10 @@ public:
/// Supported OpenCL extensions and optional core features.
OpenCLOptions SupportedOpenCLOptions;
+
+ /// \brief The list of OpenCL extensions to enable or disable, as written on
+ /// the command line.
+ std::vector<std::string> OpenCLExtensionsAsWritten;
};
} // end namespace clang
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 882c6e4cac2c..104b053a14af 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -30,6 +30,9 @@
#ifndef CONCEPTS_KEYWORD
#define CONCEPTS_KEYWORD(X) KEYWORD(X,KEYCONCEPTS)
#endif
+#ifndef MODULES_KEYWORD
+#define MODULES_KEYWORD(X) KEYWORD(X,KEYMODULES)
+#endif
#ifndef TYPE_TRAIT
#define TYPE_TRAIT(N,I,K) KEYWORD(I,K)
#endif
@@ -235,6 +238,8 @@ PUNCTUATOR(caretcaret, "^^")
// KEYCXX11 - This is a C++ keyword introduced to C++ in C++11
// KEYCONCEPTS - This is a keyword if the C++ extensions for concepts
// are enabled.
+// KEYMODULES - This is a keyword if the C++ extensions for modules
+// are enabled.
// KEYGNU - This is a keyword if GNU extensions are enabled
// KEYMS - This is a keyword if Microsoft extensions are enabled
// KEYNOMS18 - This is a keyword that must never be enabled under
@@ -366,6 +371,10 @@ KEYWORD(co_await , KEYCOROUTINES)
KEYWORD(co_return , KEYCOROUTINES)
KEYWORD(co_yield , KEYCOROUTINES)
+// C++ modules TS keywords
+MODULES_KEYWORD(module)
+MODULES_KEYWORD(import)
+
// GNU Extensions (in impl-reserved namespace)
KEYWORD(_Decimal32 , KEYALL)
KEYWORD(_Decimal64 , KEYALL)
@@ -493,6 +502,7 @@ KEYWORD(__cdecl , KEYALL)
KEYWORD(__stdcall , KEYALL)
KEYWORD(__fastcall , KEYALL)
KEYWORD(__thiscall , KEYALL)
+KEYWORD(__regcall , KEYALL)
KEYWORD(__vectorcall , KEYALL)
KEYWORD(__forceinline , KEYMS)
KEYWORD(__unaligned , KEYMS)
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
index 02da432a40db..57dcf92c3b28 100644
--- a/include/clang/Basic/Version.h
+++ b/include/clang/Basic/Version.h
@@ -19,26 +19,6 @@
#include "clang/Basic/Version.inc"
#include "llvm/ADT/StringRef.h"
-/// \brief Helper macro for CLANG_VERSION_STRING.
-#define CLANG_MAKE_VERSION_STRING2(X) #X
-
-#ifdef CLANG_VERSION_PATCHLEVEL
-/// \brief Helper macro for CLANG_VERSION_STRING.
-#define CLANG_MAKE_VERSION_STRING(X,Y,Z) CLANG_MAKE_VERSION_STRING2(X.Y.Z)
-
-/// \brief A string that describes the Clang version number, e.g., "1.0".
-#define CLANG_VERSION_STRING \
- CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR, \
- CLANG_VERSION_PATCHLEVEL)
-#else
-/// \brief Helper macro for CLANG_VERSION_STRING.
-#define CLANG_MAKE_VERSION_STRING(X,Y) CLANG_MAKE_VERSION_STRING2(X.Y)
-
-/// \brief A string that describes the Clang version number, e.g., "1.0".
-#define CLANG_VERSION_STRING \
- CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR)
-#endif
-
namespace clang {
/// \brief Retrieves the repository path (e.g., Subversion path) that
/// identifies the particular Clang branch, tag, or trunk from which this
diff --git a/include/clang/Basic/Version.inc.in b/include/clang/Basic/Version.inc.in
index ccf8430c8ba2..fd80af4b5110 100644
--- a/include/clang/Basic/Version.inc.in
+++ b/include/clang/Basic/Version.inc.in
@@ -1,6 +1,5 @@
#define CLANG_VERSION @CLANG_VERSION@
+#define CLANG_VERSION_STRING "@CLANG_VERSION@"
#define CLANG_VERSION_MAJOR @CLANG_VERSION_MAJOR@
#define CLANG_VERSION_MINOR @CLANG_VERSION_MINOR@
-#if @CLANG_HAS_VERSION_PATCHLEVEL@
#define CLANG_VERSION_PATCHLEVEL @CLANG_VERSION_PATCHLEVEL@
-#endif
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
index 6ac0812dbb17..39dab6cbf045 100644
--- a/include/clang/Basic/VirtualFileSystem.h
+++ b/include/clang/Basic/VirtualFileSystem.h
@@ -16,15 +16,30 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Chrono.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <ctime>
+#include <memory>
+#include <stack>
+#include <string>
+#include <system_error>
#include <utility>
+#include <vector>
namespace llvm {
+
class MemoryBuffer;
-}
+
+} // end namespace llvm
namespace clang {
namespace vfs {
@@ -33,7 +48,7 @@ namespace vfs {
class Status {
std::string Name;
llvm::sys::fs::UniqueID UID;
- llvm::sys::TimeValue MTime;
+ llvm::sys::TimePoint<> MTime;
uint32_t User;
uint32_t Group;
uint64_t Size;
@@ -47,7 +62,7 @@ public:
Status() : Type(llvm::sys::fs::file_type::status_error) {}
Status(const llvm::sys::fs::file_status &Status);
Status(StringRef Name, llvm::sys::fs::UniqueID UID,
- llvm::sys::TimeValue MTime, uint32_t User, uint32_t Group,
+ llvm::sys::TimePoint<> MTime, uint32_t User, uint32_t Group,
uint64_t Size, llvm::sys::fs::file_type Type,
llvm::sys::fs::perms Perms);
@@ -63,7 +78,7 @@ public:
/// @{
llvm::sys::fs::file_type getType() const { return Type; }
llvm::sys::fs::perms getPermissions() const { return Perms; }
- llvm::sys::TimeValue getLastModificationTime() const { return MTime; }
+ llvm::sys::TimePoint<> getLastModificationTime() const { return MTime; }
llvm::sys::fs::UniqueID getUniqueID() const { return UID; }
uint32_t getUser() const { return User; }
uint32_t getGroup() const { return Group; }
@@ -89,8 +104,10 @@ public:
/// Sub-classes should generally call close() inside their destructors. We
/// cannot do that from the base class, since close is virtual.
virtual ~File();
+
/// \brief Get the status of the file.
virtual llvm::ErrorOr<Status> status() = 0;
+
/// \brief Get the name of the file
virtual llvm::ErrorOr<std::string> getName() {
if (auto Status = status())
@@ -98,24 +115,30 @@ public:
else
return Status.getError();
}
+
/// \brief Get the contents of the file as a \p MemoryBuffer.
virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBuffer(const Twine &Name, int64_t FileSize = -1,
bool RequiresNullTerminator = true, bool IsVolatile = false) = 0;
+
/// \brief Closes the file.
virtual std::error_code close() = 0;
};
namespace detail {
+
/// \brief An interface for virtual file systems to provide an iterator over the
/// (non-recursive) contents of a directory.
struct DirIterImpl {
virtual ~DirIterImpl();
+
/// \brief Sets \c CurrentEntry to the next entry in the directory on success,
/// or returns a system-defined \c error_code.
virtual std::error_code increment() = 0;
+
Status CurrentEntry;
};
+
} // end namespace detail
/// \brief An input iterator over the entries in a virtual path, similar to
@@ -132,7 +155,7 @@ public:
}
/// \brief Construct an 'end' iterator.
- directory_iterator() { }
+ directory_iterator() = default;
/// \brief Equivalent to operator++, with an error code.
directory_iterator &increment(std::error_code &EC) {
@@ -171,7 +194,7 @@ public:
recursive_directory_iterator(FileSystem &FS, const Twine &Path,
std::error_code &EC);
/// \brief Construct an 'end' iterator.
- recursive_directory_iterator() { }
+ recursive_directory_iterator() = default;
/// \brief Equivalent to operator++, with an error code.
recursive_directory_iterator &increment(std::error_code &EC);
@@ -185,6 +208,7 @@ public:
bool operator!=(const recursive_directory_iterator &RHS) const {
return !(*this == RHS);
}
+
/// \brief Gets the current level. Starting path is at level 0.
int level() const {
assert(State->size() && "Cannot get level without any iteration state");
@@ -280,7 +304,9 @@ public:
};
namespace detail {
+
class InMemoryDirectory;
+
} // end namespace detail
/// An in-memory file system.
@@ -292,6 +318,7 @@ class InMemoryFileSystem : public FileSystem {
public:
explicit InMemoryFileSystem(bool UseNormalizedPaths = true);
~InMemoryFileSystem() override;
+
/// Add a buffer to the VFS with a path. The VFS owns the buffer.
/// \return true if the file was successfully added, false if the file already
/// exists in the file system with different contents.
@@ -335,22 +362,41 @@ struct YAMLVFSEntry {
std::string RPath;
};
+/// \brief Collect all pairs of <virtual path, real path> entries from the
+/// \p YAMLFilePath. This is used by the module dependency collector to forward
+/// the entries into the reproducer output VFS YAML file.
+void collectVFSFromYAML(
+ std::unique_ptr<llvm::MemoryBuffer> Buffer,
+ llvm::SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath,
+ SmallVectorImpl<YAMLVFSEntry> &CollectedEntries,
+ void *DiagContext = nullptr,
+ IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem());
+
class YAMLVFSWriter {
std::vector<YAMLVFSEntry> Mappings;
Optional<bool> IsCaseSensitive;
Optional<bool> IsOverlayRelative;
Optional<bool> UseExternalNames;
+ Optional<bool> IgnoreNonExistentContents;
std::string OverlayDir;
public:
- YAMLVFSWriter() {}
+ YAMLVFSWriter() = default;
+
void addFileMapping(StringRef VirtualPath, StringRef RealPath);
+
void setCaseSensitivity(bool CaseSensitive) {
IsCaseSensitive = CaseSensitive;
}
+
void setUseExternalNames(bool UseExtNames) {
UseExternalNames = UseExtNames;
}
+
+ void setIgnoreNonExistentContents(bool IgnoreContents) {
+ IgnoreNonExistentContents = IgnoreContents;
+ }
+
void setOverlayDir(StringRef OverlayDirectory) {
IsOverlayRelative = true;
OverlayDir.assign(OverlayDirectory.str());
@@ -361,4 +407,5 @@ public:
} // end namespace vfs
} // end namespace clang
-#endif
+
+#endif // LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H
diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h
index 8dd6ad1c21ee..2703f299d217 100644
--- a/include/clang/CodeGen/CGFunctionInfo.h
+++ b/include/clang/CodeGen/CGFunctionInfo.h
@@ -664,29 +664,6 @@ public:
}
};
-/// CGCalleeInfo - Class to encapsulate the information about a callee to be
-/// used during the generation of call/invoke instructions.
-class CGCalleeInfo {
- /// \brief The function proto type of the callee.
- const FunctionProtoType *CalleeProtoTy;
- /// \brief The function declaration of the callee.
- const Decl *CalleeDecl;
-
-public:
- explicit CGCalleeInfo() : CalleeProtoTy(nullptr), CalleeDecl(nullptr) {}
- CGCalleeInfo(const FunctionProtoType *calleeProtoTy, const Decl *calleeDecl)
- : CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {}
- CGCalleeInfo(const FunctionProtoType *calleeProtoTy)
- : CalleeProtoTy(calleeProtoTy), CalleeDecl(nullptr) {}
- CGCalleeInfo(const Decl *calleeDecl)
- : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {}
-
- const FunctionProtoType *getCalleeFunctionProtoType() {
- return CalleeProtoTy;
- }
- const Decl *getCalleeDecl() { return CalleeDecl; }
-};
-
} // end namespace CodeGen
} // end namespace clang
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index ce7696dd00cf..58638348653f 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -20,6 +20,7 @@ namespace llvm {
class Constant;
class LLVMContext;
class Module;
+ class StringRef;
}
namespace clang {
diff --git a/include/clang/CodeGen/ObjectFilePCHContainerOperations.h b/include/clang/CodeGen/ObjectFilePCHContainerOperations.h
index 6437f4f9b4f5..67be6718fec4 100644
--- a/include/clang/CodeGen/ObjectFilePCHContainerOperations.h
+++ b/include/clang/CodeGen/ObjectFilePCHContainerOperations.h
@@ -35,10 +35,8 @@ class ObjectFilePCHContainerWriter : public PCHContainerWriter {
class ObjectFilePCHContainerReader : public PCHContainerReader {
StringRef getFormat() const override { return "obj"; }
- /// Initialize an llvm::BitstreamReader with the serialized
- /// AST inside the PCH container Buffer.
- void ExtractPCH(llvm::MemoryBufferRef Buffer,
- llvm::BitstreamReader &StreamFile) const override;
+ /// Returns the serialized AST inside the PCH container Buffer.
+ StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
};
}
diff --git a/include/clang/CodeGen/SwiftCallingConv.h b/include/clang/CodeGen/SwiftCallingConv.h
index f9c2fd94ca8d..23db43e6739c 100644
--- a/include/clang/CodeGen/SwiftCallingConv.h
+++ b/include/clang/CodeGen/SwiftCallingConv.h
@@ -17,7 +17,6 @@
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Type.h"
-#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/TrailingObjects.h"
#include <cassert>
@@ -91,7 +90,7 @@ public:
bool shouldPassIndirectly(bool asReturnValue) const;
using EnumerationCallback =
- llvm::function_ref<void(CharUnits offset, llvm::Type *type)>;
+ llvm::function_ref<void(CharUnits offset, CharUnits end, llvm::Type *type)>;
/// Enumerate the expanded components of this type.
///
@@ -161,6 +160,9 @@ ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type);
/// private interface for Clang.
void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
+/// Is swifterror lowered to a register by the target ABI.
+bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM);
+
} // end namespace swiftcall
} // end namespace CodeGen
} // end namespace clang
diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
index e5a1d0dac837..55f0ca94dedc 100644
--- a/include/clang/Config/config.h.cmake
+++ b/include/clang/Config/config.h.cmake
@@ -8,9 +8,15 @@
/* Bug report URL. */
#define BUG_REPORT_URL "${BUG_REPORT_URL}"
+/* Default linker to use. */
+#define CLANG_DEFAULT_LINKER "${CLANG_DEFAULT_LINKER}"
+
/* Default C++ stdlib to use. */
#define CLANG_DEFAULT_CXX_STDLIB "${CLANG_DEFAULT_CXX_STDLIB}"
+/* Default runtime library to use. */
+#define CLANG_DEFAULT_RTLIB "${CLANG_DEFAULT_RTLIB}"
+
/* Default OpenMP runtime used by -fopenmp. */
#define CLANG_DEFAULT_OPENMP_RUNTIME "${CLANG_DEFAULT_OPENMP_RUNTIME}"
@@ -32,6 +38,9 @@
/* Define if we have libxml2 */
#cmakedefine CLANG_HAVE_LIBXML ${CLANG_HAVE_LIBXML}
+/* Define if we have sys/resource.h (rlimits) */
+#cmakedefine CLANG_HAVE_RLIMITS ${CLANG_HAVE_RLIMITS}
+
/* The LLVM product name and version */
#define BACKEND_PACKAGE_STRING "${BACKEND_PACKAGE_STRING}"
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
index 3fe6510fec98..72456d34a0d9 100644
--- a/include/clang/Driver/Action.h
+++ b/include/clang/Driver/Action.h
@@ -66,9 +66,11 @@ public:
DsymutilJobClass,
VerifyDebugInfoJobClass,
VerifyPCHJobClass,
+ OffloadBundlingJobClass,
+ OffloadUnbundlingJobClass,
JobClassFirst = PreprocessJobClass,
- JobClassLast = VerifyPCHJobClass
+ JobClassLast = OffloadUnbundlingJobClass
};
// The offloading kind determines if this action is binded to a particular
@@ -80,6 +82,7 @@ public:
OFK_Host = 0x01,
// The device offloading tool chains - one bit for each programming model.
OFK_Cuda = 0x02,
+ OFK_OpenMP = 0x04,
};
static const char *getClassName(ActionClass AC);
@@ -92,6 +95,12 @@ private:
ActionList Inputs;
+ /// Flag that is set to true if this action can be collapsed with others
+ /// actions that depend on it. This is true by default and set to false when
+ /// the action is used by two different tool chains, which is enabled by the
+ /// offloading support implementation.
+ bool CanBeCollapsedWithNextDependentAction = true;
+
protected:
///
/// Offload information.
@@ -136,12 +145,26 @@ public:
return input_const_range(input_begin(), input_end());
}
+ /// Mark this action as not legal to collapse.
+ void setCannotBeCollapsedWithNextDependentAction() {
+ CanBeCollapsedWithNextDependentAction = false;
+ }
+ /// Return true if this function can be collapsed with others.
+ bool isCollapsingWithNextDependentActionLegal() const {
+ return CanBeCollapsedWithNextDependentAction;
+ }
+
/// Return a string containing the offload kind of the action.
std::string getOffloadingKindPrefix() const;
/// Return a string that can be used as prefix in order to generate unique
- /// files for each offloading kind.
- std::string
- getOffloadingFileNamePrefix(llvm::StringRef NormalizedTriple) const;
+ /// files for each offloading kind. By default, no prefix is used for
+ /// non-device kinds, except if \a CreatePrefixForHost is set.
+ static std::string
+ GetOffloadingFileNamePrefix(OffloadKind Kind,
+ llvm::StringRef NormalizedTriple,
+ bool CreatePrefixForHost = false);
+ /// Return a string containing a offload kind name.
+ static StringRef GetOffloadKindName(OffloadKind Kind);
/// Set the device offload info of this action and propagate it to its
/// dependences.
@@ -190,12 +213,12 @@ class BindArchAction : public Action {
virtual void anchor();
/// The architecture to bind, or 0 if the default architecture
/// should be bound.
- const char *ArchName;
+ StringRef ArchName;
public:
- BindArchAction(Action *Input, const char *ArchName);
+ BindArchAction(Action *Input, StringRef ArchName);
- const char *getArchName() const { return ArchName; }
+ StringRef getArchName() const { return ArchName; }
static bool classof(const Action *A) {
return A->getKind() == BindArchClass;
@@ -465,6 +488,64 @@ public:
}
};
+class OffloadBundlingJobAction : public JobAction {
+ void anchor() override;
+
+public:
+ // Offloading bundling doesn't change the type of output.
+ OffloadBundlingJobAction(ActionList &Inputs);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == OffloadBundlingJobClass;
+ }
+};
+
+class OffloadUnbundlingJobAction final : public JobAction {
+ void anchor() override;
+
+public:
+ /// Type that provides information about the actions that depend on this
+ /// unbundling action.
+ struct DependentActionInfo final {
+ /// \brief The tool chain of the dependent action.
+ const ToolChain *DependentToolChain = nullptr;
+ /// \brief The bound architecture of the dependent action.
+ StringRef DependentBoundArch;
+ /// \brief The offload kind of the dependent action.
+ const OffloadKind DependentOffloadKind = OFK_None;
+ DependentActionInfo(const ToolChain *DependentToolChain,
+ StringRef DependentBoundArch,
+ const OffloadKind DependentOffloadKind)
+ : DependentToolChain(DependentToolChain),
+ DependentBoundArch(DependentBoundArch),
+ DependentOffloadKind(DependentOffloadKind){};
+ };
+
+private:
+ /// Container that keeps information about each dependence of this unbundling
+ /// action.
+ SmallVector<DependentActionInfo, 6> DependentActionInfoArray;
+
+public:
+ // Offloading unbundling doesn't change the type of output.
+ OffloadUnbundlingJobAction(Action *Input);
+
+ /// Register information about a dependent action.
+ void registerDependentActionInfo(const ToolChain *TC, StringRef BoundArch,
+ OffloadKind Kind) {
+ DependentActionInfoArray.push_back({TC, BoundArch, Kind});
+ }
+
+ /// Return the information about all depending actions.
+ ArrayRef<DependentActionInfo> getDependentActionsInfo() const {
+ return DependentActionInfoArray;
+ }
+
+ static bool classof(const Action *A) {
+ return A->getKind() == OffloadUnbundlingJobClass;
+ }
+};
+
} // end namespace driver
} // end namespace clang
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 1401984c2a34..2910b8521bab 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -114,6 +114,9 @@ def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">,
def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">,
HelpText<"Display the list of analyzer checkers that are available">;
+def analyzer_list_enabled_checkers : Flag<["-"], "analyzer-list-enabled-checkers">,
+ HelpText<"Display the list of enabled analyzer checkers">;
+
def analyzer_config : Separate<["-"], "analyzer-config">,
HelpText<"Choose analyzer options to enable">;
@@ -157,13 +160,13 @@ def fno_math_builtin : Flag<["-"], "fno-math-builtin">,
HelpText<"Disable implicit builtin knowledge of math functions">;
}
-def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">,
- HelpText<"Don't run LLVM optimization passes">;
def disable_llvm_verifier : Flag<["-"], "disable-llvm-verifier">,
HelpText<"Don't run the LLVM IR verifier pass">;
def disable_llvm_passes : Flag<["-"], "disable-llvm-passes">,
HelpText<"Use together with -emit-llvm to get pristine LLVM IR from the "
"frontend by not running any LLVM passes at all">;
+def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">,
+ Alias<disable_llvm_passes>;
def disable_red_zone : Flag<["-"], "disable-red-zone">,
HelpText<"Do not emit code that uses the red zone.">;
def dwarf_column_info : Flag<["-"], "dwarf-column-info">,
@@ -189,9 +192,14 @@ def femit_coverage_notes : Flag<["-"], "femit-coverage-notes">,
HelpText<"Emit a gcov coverage notes file when compiling.">;
def femit_coverage_data: Flag<["-"], "femit-coverage-data">,
HelpText<"Instrument the program to emit gcov coverage data when run.">;
-def coverage_file : Separate<["-"], "coverage-file">,
- HelpText<"Emit coverage data to this filename. The extension will be replaced.">;
-def coverage_file_EQ : Joined<["-"], "coverage-file=">, Alias<coverage_file>;
+def coverage_data_file : Separate<["-"], "coverage-data-file">,
+ HelpText<"Emit coverage data to this filename.">;
+def coverage_data_file_EQ : Joined<["-"], "coverage-data-file=">,
+ Alias<coverage_data_file>;
+def coverage_notes_file : Separate<["-"], "coverage-notes-file">,
+ HelpText<"Emit coverage notes to this filename.">;
+def coverage_notes_file_EQ : Joined<["-"], "coverage-notes-file=">,
+ Alias<coverage_notes_file>;
def coverage_cfg_checksum : Flag<["-"], "coverage-cfg-checksum">,
HelpText<"Emit CFG checksum for functions in .gcno files.">;
def coverage_no_function_names_in_data : Flag<["-"], "coverage-no-function-names-in-data">,
@@ -269,12 +277,21 @@ def fsanitize_coverage_trace_bb
def fsanitize_coverage_trace_cmp
: Flag<["-"], "fsanitize-coverage-trace-cmp">,
HelpText<"Enable cmp instruction tracing in sanitizer coverage">;
+def fsanitize_coverage_trace_div
+ : Flag<["-"], "fsanitize-coverage-trace-div">,
+ HelpText<"Enable div instruction tracing in sanitizer coverage">;
+def fsanitize_coverage_trace_gep
+ : Flag<["-"], "fsanitize-coverage-trace-gep">,
+ HelpText<"Enable gep instruction tracing in sanitizer coverage">;
def fsanitize_coverage_8bit_counters
: Flag<["-"], "fsanitize-coverage-8bit-counters">,
HelpText<"Enable frequency counters in sanitizer coverage">;
def fsanitize_coverage_trace_pc
: Flag<["-"], "fsanitize-coverage-trace-pc">,
HelpText<"Enable PC tracing in sanitizer coverage">;
+def fsanitize_coverage_trace_pc_guard
+ : Flag<["-"], "fsanitize-coverage-trace-pc-guard">,
+ HelpText<"Enable PC tracing with guard in sanitizer coverage">;
def fprofile_instrument_EQ : Joined<["-"], "fprofile-instrument=">,
HelpText<"Enable PGO instrumentation. The accepted value is clang, llvm, "
"or none">;
@@ -454,6 +471,8 @@ def print_decl_contexts : Flag<["-"], "print-decl-contexts">,
HelpText<"Print DeclContexts and their Decls">;
def emit_module : Flag<["-"], "emit-module">,
HelpText<"Generate pre-compiled module file from a module map">;
+def emit_module_interface : Flag<["-"], "emit-module-interface">,
+ HelpText<"Generate pre-compiled module file from a C++ module interface">;
def emit_pth : Flag<["-"], "emit-pth">,
HelpText<"Generate pre-tokenized header file">;
def emit_pch : Flag<["-"], "emit-pch">,
@@ -488,8 +507,13 @@ def arcmt_modify : Flag<["-"], "arcmt-modify">,
def arcmt_migrate : Flag<["-"], "arcmt-migrate">,
HelpText<"Apply modifications and produces temporary files that conform to ARC">;
+def opt_record_file : Separate<["-"], "opt-record-file">,
+ HelpText<"File name to use for YAML optimization record output">;
+
def print_stats : Flag<["-"], "print-stats">,
HelpText<"Print performance metrics and statistics">;
+def stats_file : Joined<["-"], "stats-file=">,
+ HelpText<"Filename to write statistics to">;
def fdump_record_layouts : Flag<["-"], "fdump-record-layouts">,
HelpText<"Dump record layout information">;
def fdump_record_layouts_simple : Flag<["-"], "fdump-record-layouts-simple">,
@@ -617,9 +641,11 @@ def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">,
def finclude_default_header : Flag<["-"], "finclude-default-header">,
HelpText<"Include the default header file for OpenCL">;
-// C++ TSes.
-def fcoroutines : Flag<["-"], "fcoroutines">,
- HelpText<"Enable support for the C++ Coroutines TS">;
+// FIXME: Remove these entirely once functionality/tests have been excised.
+def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group<f_Group>,
+ HelpText<"Use GC exclusively for Objective-C related memory management">;
+def fobjc_gc : Flag<["-"], "fobjc-gc">, Group<f_Group>,
+ HelpText<"Enable Objective-C garbage collection">;
//===----------------------------------------------------------------------===//
// Header Search Options
@@ -666,6 +692,13 @@ def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record">
HelpText<"include a detailed record of preprocessing actions">;
//===----------------------------------------------------------------------===//
+// OpenCL Options
+//===----------------------------------------------------------------------===//
+
+def cl_ext_EQ : CommaJoined<["-"], "cl-ext=">,
+ HelpText<"OpenCL only. Enable or disable OpenCL extensions. The argument is a comma-separated sequence of one or more extension names, each prefixed by '+' or '-'.">;
+
+//===----------------------------------------------------------------------===//
// CUDA Options
//===----------------------------------------------------------------------===//
@@ -716,4 +749,6 @@ def show_inst : Flag<["-"], "show-inst">,
def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">,
HelpText<"The string to embed in the Dwarf debug AT_producer record.">;
+def defsym : Separate<["-"], "defsym">,
+ HelpText<"Define a value for a symbol">;
} // let Flags = [CC1AsOption]
diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td
index b1d2459f71cf..cb2745afb7e4 100644
--- a/include/clang/Driver/CLCompatOptions.td
+++ b/include/clang/Driver/CLCompatOptions.td
@@ -54,10 +54,10 @@ class CLRemainingArgsJoined<string name> : Option<["/", "-"], name,
def _SLASH_Brepro : CLFlag<"Brepro">,
HelpText<"Emit an object file which can be reproduced over time">,
- Alias<mincremental_linker_compatible>;
+ Alias<mno_incremental_linker_compatible>;
def _SLASH_Brepro_ : CLFlag<"Brepro-">,
HelpText<"Emit an object file which cannot be reproduced over time">,
- Alias<mno_incremental_linker_compatible>;
+ Alias<mincremental_linker_compatible>;
def _SLASH_C : CLFlag<"C">,
HelpText<"Don't discard comments when preprocessing">, Alias<C>;
def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias<c>;
@@ -120,10 +120,18 @@ def _SLASH_Qvec_ : CLFlag<"Qvec-">,
def _SLASH_showIncludes : CLFlag<"showIncludes">,
HelpText<"Print info about included files to stderr">,
Alias<show_includes>;
+def _SLASH_source_charset : CLCompileJoined<"source-charset:">,
+ HelpText<"Source encoding, supports only UTF-8">, Alias<finput_charset_EQ>;
+def _SLASH_execution_charset : CLCompileJoined<"execution-charset:">,
+ HelpText<"Runtime encoding, supports only UTF-8">, Alias<fexec_charset_EQ>;
def _SLASH_std : CLCompileJoined<"std:">,
HelpText<"Language standard to compile for">;
def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">,
MetaVarName<"<macro>">, Alias<U>;
+def _SLASH_validate_charset : CLFlag<"validate-charset">,
+ Alias<W_Joined>, AliasArgs<["invalid-source-encoding"]>;
+def _SLASH_validate_charset_ : CLFlag<"validate-charset-">,
+ Alias<W_Joined>, AliasArgs<["no-invalid-source-encoding"]>;
def _SLASH_W0 : CLFlag<"W0">, HelpText<"Disable all warnings">, Alias<w>;
def _SLASH_W1 : CLFlag<"W1">, HelpText<"Enable -Wall">, Alias<Wall>;
def _SLASH_W2 : CLFlag<"W2">, HelpText<"Enable -Wall">, Alias<Wall>;
@@ -289,8 +297,8 @@ def _SLASH_cgthreads : CLIgnoredJoined<"cgthreads">;
def _SLASH_d2FastFail : CLIgnoredFlag<"d2FastFail">;
def _SLASH_d2Zi_PLUS : CLIgnoredFlag<"d2Zi+">;
def _SLASH_errorReport : CLIgnoredJoined<"errorReport">;
-def _SLASH_Fd : CLIgnoredJoined<"Fd">;
def _SLASH_FC : CLIgnoredFlag<"FC">;
+def _SLASH_Fd : CLIgnoredJoined<"Fd">;
def _SLASH_FS : CLIgnoredFlag<"FS">, HelpText<"Force synchronous PDB writes">;
def _SLASH_GF : CLIgnoredFlag<"GF">;
def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">;
@@ -300,6 +308,7 @@ def _SLASH_openmp_ : CLIgnoredFlag<"openmp-">;
def _SLASH_RTC : CLIgnoredJoined<"RTC">;
def _SLASH_sdl : CLIgnoredFlag<"sdl">;
def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;
+def _SLASH_utf8 : CLIgnoredFlag<"utf-8">;
def _SLASH_w : CLIgnoredJoined<"w">;
def _SLASH_Zc_auto : CLIgnoredFlag<"Zc:auto">;
def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">;
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
index 3f387151a3d4..114e0b33c75a 100644
--- a/include/clang/Driver/Compilation.h
+++ b/include/clang/Driver/Compilation.h
@@ -14,7 +14,6 @@
#include "clang/Driver/Job.h"
#include "clang/Driver/Util.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/Path.h"
#include <map>
namespace llvm {
@@ -68,10 +67,27 @@ class Compilation {
/// The root list of jobs.
JobList Jobs;
- /// Cache of translated arguments for a particular tool chain and bound
- /// architecture.
- llvm::DenseMap<std::pair<const ToolChain *, const char *>,
- llvm::opt::DerivedArgList *> TCArgs;
+ /// Cache of translated arguments for a particular tool chain, bound
+ /// architecture, and device offload kind.
+ struct TCArgsKey final {
+ const ToolChain *TC = nullptr;
+ StringRef BoundArch;
+ Action::OffloadKind DeviceOffloadKind = Action::OFK_None;
+ bool operator<(const TCArgsKey &K) const {
+ if (TC < K.TC)
+ return true;
+ else if (TC == K.TC && BoundArch < K.BoundArch)
+ return true;
+ else if (TC == K.TC && BoundArch == K.BoundArch &&
+ DeviceOffloadKind < K.DeviceOffloadKind)
+ return true;
+ return false;
+ }
+ TCArgsKey(const ToolChain *TC, StringRef BoundArch,
+ Action::OffloadKind DeviceOffloadKind)
+ : TC(TC), BoundArch(BoundArch), DeviceOffloadKind(DeviceOffloadKind) {}
+ };
+ std::map<TCArgsKey, llvm::opt::DerivedArgList *> TCArgs;
/// Temporary files which should be removed on exit.
llvm::opt::ArgStringList TempFiles;
@@ -116,6 +132,12 @@ public:
return OrderedOffloadingToolchains.equal_range(Kind);
}
+ /// Return true if an offloading tool chain of a given kind exists.
+ template <Action::OffloadKind Kind> bool hasOffloadToolChain() const {
+ return OrderedOffloadingToolchains.find(Kind) !=
+ OrderedOffloadingToolchains.end();
+ }
+
/// Return an offload toolchain of the provided kind. Only one is expected to
/// exist.
template <Action::OffloadKind Kind>
@@ -176,10 +198,15 @@ public:
/// getArgsForToolChain - Return the derived argument list for the
/// tool chain \p TC (or the default tool chain, if TC is not specified).
+ /// If a device offloading kind is specified, a translation specific for that
+ /// kind is performed, if any.
///
/// \param BoundArch - The bound architecture name, or 0.
- const llvm::opt::DerivedArgList &getArgsForToolChain(const ToolChain *TC,
- const char *BoundArch);
+ /// \param DeviceOffloadKind - The offload device kind that should be used in
+ /// the translation, if any.
+ const llvm::opt::DerivedArgList &
+ getArgsForToolChain(const ToolChain *TC, StringRef BoundArch,
+ Action::OffloadKind DeviceOffloadKind);
/// addTempFile - Add a file to remove on exit, and returns its
/// argument.
diff --git a/include/clang/Driver/Distro.h b/include/clang/Driver/Distro.h
new file mode 100644
index 000000000000..e2fb8b643350
--- /dev/null
+++ b/include/clang/Driver/Distro.h
@@ -0,0 +1,122 @@
+//===--- Distro.h - Linux distribution detection support --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DRIVER_DISTRO_H
+#define LLVM_CLANG_DRIVER_DISTRO_H
+
+#include "clang/Basic/VirtualFileSystem.h"
+
+namespace clang {
+namespace driver {
+
+/// Distro - Helper class for detecting and classifying Linux distributions.
+///
+/// This class encapsulates the clang Linux distribution detection mechanism
+/// as well as helper functions that match the specific (versioned) results
+/// into wider distribution classes.
+class Distro {
+public:
+ enum DistroType {
+ // NB: Releases of a particular Linux distro should be kept together
+ // in this enum, because some tests are done by integer comparison against
+ // the first and last known member in the family, e.g. IsRedHat().
+ ArchLinux,
+ DebianLenny,
+ DebianSqueeze,
+ DebianWheezy,
+ DebianJessie,
+ DebianStretch,
+ Exherbo,
+ RHEL5,
+ RHEL6,
+ RHEL7,
+ Fedora,
+ OpenSUSE,
+ UbuntuHardy,
+ UbuntuIntrepid,
+ UbuntuJaunty,
+ UbuntuKarmic,
+ UbuntuLucid,
+ UbuntuMaverick,
+ UbuntuNatty,
+ UbuntuOneiric,
+ UbuntuPrecise,
+ UbuntuQuantal,
+ UbuntuRaring,
+ UbuntuSaucy,
+ UbuntuTrusty,
+ UbuntuUtopic,
+ UbuntuVivid,
+ UbuntuWily,
+ UbuntuXenial,
+ UbuntuYakkety,
+ UbuntuZesty,
+ UnknownDistro
+ };
+
+private:
+ /// The distribution, possibly with specific version.
+ DistroType DistroVal;
+
+public:
+ /// @name Constructors
+ /// @{
+
+ /// Default constructor leaves the distribution unknown.
+ Distro() : DistroVal() {}
+
+ /// Constructs a Distro type for specific distribution.
+ Distro(DistroType D) : DistroVal(D) {}
+
+ /// Detects the distribution using specified VFS.
+ explicit Distro(clang::vfs::FileSystem& VFS);
+
+ bool operator==(const Distro &Other) const {
+ return DistroVal == Other.DistroVal;
+ }
+
+ bool operator!=(const Distro &Other) const {
+ return DistroVal != Other.DistroVal;
+ }
+
+ bool operator>=(const Distro &Other) const {
+ return DistroVal >= Other.DistroVal;
+ }
+
+ bool operator<=(const Distro &Other) const {
+ return DistroVal <= Other.DistroVal;
+ }
+
+ /// @}
+ /// @name Convenience Predicates
+ /// @{
+
+ bool IsRedhat() const {
+ return DistroVal == Fedora || (DistroVal >= RHEL5 && DistroVal <= RHEL7);
+ }
+
+ bool IsOpenSUSE() const {
+ return DistroVal == OpenSUSE;
+ }
+
+ bool IsDebian() const {
+ return DistroVal >= DebianLenny && DistroVal <= DebianStretch;
+ }
+
+ bool IsUbuntu() const {
+ return DistroVal >= UbuntuHardy && DistroVal <= UbuntuZesty;
+ }
+
+ /// @}
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 9ecf434a87e2..0ce461ca61e1 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -12,21 +12,20 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Driver/Action.h"
#include "clang/Driver/Phases.h"
#include "clang/Driver/Types.h"
#include "clang/Driver/Util.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Support/Path.h" // FIXME: Kill when CompilationInfo lands.
#include <list>
#include <map>
-#include <memory>
-#include <set>
#include <string>
namespace llvm {
+class Triple;
+
namespace opt {
class Arg;
class ArgList;
@@ -44,7 +43,6 @@ class FileSystem;
namespace driver {
- class Action;
class Command;
class Compilation;
class InputInfo;
@@ -93,6 +91,26 @@ class Driver {
LTOKind LTOMode;
public:
+ enum OpenMPRuntimeKind {
+ /// An unknown OpenMP runtime. We can't generate effective OpenMP code
+ /// without knowing what runtime to target.
+ OMPRT_Unknown,
+
+ /// The LLVM OpenMP runtime. When completed and integrated, this will become
+ /// the default for Clang.
+ OMPRT_OMP,
+
+ /// The GNU OpenMP runtime. Clang doesn't support generating OpenMP code for
+ /// this runtime but can swallow the pragmas, and find and link against the
+ /// runtime library itself.
+ OMPRT_GOMP,
+
+ /// The legacy name for the LLVM OpenMP runtime from when it was the Intel
+ /// OpenMP runtime. We support this mode for users with existing
+ /// dependencies on this runtime library name.
+ OMPRT_IOMP5
+ };
+
// Diag - Forwarding function for diagnostics.
DiagnosticBuilder Diag(unsigned DiagID) const {
return Diags.Report(DiagID);
@@ -132,9 +150,6 @@ public:
/// If the standard library is used
bool UseStdLib;
- /// Default target triple.
- std::string DefaultTargetTriple;
-
/// Driver title to use with help.
std::string DriverTitle;
@@ -160,6 +175,9 @@ public:
/// Whether the driver is just the preprocessor.
bool CCCIsCPP() const { return Mode == CPPMode; }
+ /// Whether the driver should follow gcc like behavior.
+ bool CCCIsCC() const { return Mode == GCCMode; }
+
/// Whether the driver should follow cl.exe like behavior.
bool IsCLMode() const { return Mode == CLMode; }
@@ -183,6 +201,9 @@ public:
unsigned CCGenDiagnostics : 1;
private:
+ /// Default target triple.
+ std::string DefaultTargetTriple;
+
/// Name to use when invoking gcc/g++.
std::string CCCGenericGCCName;
@@ -222,9 +243,23 @@ private:
// Before executing jobs, sets up response files for commands that need them.
void setUpResponseFiles(Compilation &C, Command &Cmd);
- void generatePrefixedToolNames(const char *Tool, const ToolChain &TC,
+ void generatePrefixedToolNames(StringRef Tool, const ToolChain &TC,
SmallVectorImpl<std::string> &Names) const;
+ /// \brief Find the appropriate .crash diagonostic file for the child crash
+ /// under this driver and copy it out to a temporary destination with the
+ /// other reproducer related files (.sh, .cache, etc). If not found, suggest a
+ /// directory for the user to look at.
+ ///
+ /// \param ReproCrashFilename The file path to copy the .crash to.
+ /// \param CrashDiagDir The suggested directory for the user to look at
+ /// in case the search or copy fails.
+ ///
+ /// \returns If the .crash is found and successfully copied return true,
+ /// otherwise false and return the suggested directory in \p CrashDiagDir.
+ bool getCrashDiagnosticFile(StringRef ReproCrashFilename,
+ SmallString<128> &CrashDiagDir);
+
public:
Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple,
DiagnosticsEngine &Diags,
@@ -268,8 +303,17 @@ public:
bool isSaveTempsEnabled() const { return SaveTemps != SaveTempsNone; }
bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; }
- bool embedBitcodeEnabled() const { return BitcodeEmbed == EmbedBitcode; }
- bool embedBitcodeMarkerOnly() const { return BitcodeEmbed == EmbedMarker; }
+ bool embedBitcodeEnabled() const { return BitcodeEmbed != EmbedNone; }
+ bool embedBitcodeInObject() const {
+ // LTO has no object file output so ignore embed bitcode option in LTO.
+ return (BitcodeEmbed == EmbedBitcode) && !isUsingLTO();
+ }
+ bool embedBitcodeMarkerOnly() const {
+ return (BitcodeEmbed == EmbedMarker) && !isUsingLTO();
+ }
+
+ /// Compute the desired OpenMP runtime from the flags provided.
+ OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const;
/// @}
/// @name Primary Functionality
@@ -293,7 +337,7 @@ public:
/// @{
/// ParseDriverMode - Look for and handle the driver mode option in Args.
- void ParseDriverMode(ArrayRef<const char *> Args);
+ void ParseDriverMode(StringRef ProgramName, ArrayRef<const char *> Args);
/// ParseArgStrings - Parse the given list of strings into an
/// ArgList.
@@ -340,7 +384,7 @@ public:
/// 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).
///
@@ -368,7 +412,7 @@ public:
/// directories to search.
//
// FIXME: This should be in CompilationInfo.
- std::string GetFilePath(const char *Name, const ToolChain &TC) const;
+ std::string GetFilePath(StringRef Name, const ToolChain &TC) const;
/// GetProgramPath - Lookup \p Name in the list of program search paths.
///
@@ -376,7 +420,7 @@ public:
/// directories to search.
//
// FIXME: This should be in CompilationInfo.
- std::string GetProgramPath(const char *Name, const ToolChain &TC) const;
+ std::string GetProgramPath(StringRef Name, const ToolChain &TC) const;
/// HandleImmediateArgs - Handle any arguments which should be
/// treated before building actions or binding tools.
@@ -393,14 +437,14 @@ public:
/// BuildJobsForAction - Construct the jobs to perform for the action \p A and
/// return an InputInfo for the result of running \p A. Will only construct
- /// jobs for a given (Action, ToolChain, BoundArch) tuple once.
+ /// jobs for a given (Action, ToolChain, BoundArch, DeviceKind) tuple once.
InputInfo
BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC,
- const char *BoundArch, bool AtTopLevel, bool MultipleArchs,
+ StringRef BoundArch, bool AtTopLevel, bool MultipleArchs,
const char *LinkingOutput,
std::map<std::pair<const Action *, std::string>, InputInfo>
&CachedResults,
- bool BuildForOffloadDevice) const;
+ Action::OffloadKind TargetDeviceOffloadKind) const;
/// Returns the default name for linked images (e.g., "a.out").
const char *getDefaultImageName() const;
@@ -418,7 +462,7 @@ public:
/// \param MultipleArchs - Whether multiple -arch options were supplied.
/// \param NormalizedTriple - The normalized triple of the relevant target.
const char *GetNamedOutputPath(Compilation &C, const JobAction &JA,
- const char *BaseInput, const char *BoundArch,
+ const char *BaseInput, StringRef BoundArch,
bool AtTopLevel, bool MultipleArchs,
StringRef NormalizedTriple) const;
@@ -426,7 +470,7 @@ public:
/// as part of compilation; the file will have the given prefix and suffix.
///
/// GCC goes to extra lengths here to be a bit more robust.
- std::string GetTemporaryPath(StringRef Prefix, const char *Suffix) const;
+ std::string GetTemporaryPath(StringRef Prefix, StringRef Suffix) const;
/// Return the pathname of the pch file in clang-cl mode.
std::string GetClPchPath(Compilation &C, StringRef BaseName) const;
@@ -442,6 +486,10 @@ public:
LTOKind getLTOMode() const { return LTOMode; }
private:
+ /// Set the driver mode (cl, gcc, etc) from an option string of the form
+ /// --driver-mode=<mode>.
+ void setDriverModeFromOption(StringRef Opt);
+
/// Parse the \p Args list for LTO options and record the type of LTO
/// compilation based on which -f(no-)?lto(=.*)? option occurs last.
void setLTOMode(const llvm::opt::ArgList &Args);
@@ -463,12 +511,11 @@ private:
/// jobs specifically for the given action, but will use the cache when
/// building jobs for the Action's inputs.
InputInfo BuildJobsForActionNoCache(
- Compilation &C, const Action *A, const ToolChain *TC,
- const char *BoundArch, bool AtTopLevel, bool MultipleArchs,
- const char *LinkingOutput,
+ Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch,
+ bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput,
std::map<std::pair<const Action *, std::string>, InputInfo>
&CachedResults,
- bool BuildForOffloadDevice) const;
+ Action::OffloadKind TargetDeviceOffloadKind) const;
public:
/// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and
@@ -478,9 +525,8 @@ public:
/// \return True if the entire string was parsed (9.2), or all
/// groups were parsed (10.3.5extrastuff). HadExtra is true if all
/// groups were parsed but extra characters remain at the end.
- static bool GetReleaseVersion(const char *Str, unsigned &Major,
- unsigned &Minor, unsigned &Micro,
- bool &HadExtra);
+ static bool GetReleaseVersion(StringRef Str, unsigned &Major, unsigned &Minor,
+ unsigned &Micro, bool &HadExtra);
/// Parse digits from a string \p Str and fulfill \p Digits with
/// the parsed numbers. This method assumes that the max number of
@@ -488,7 +534,7 @@ public:
///
/// \return True if the entire string was parsed and there are
/// no extra characters remaining at the end.
- static bool GetReleaseVersion(const char *Str,
+ static bool GetReleaseVersion(StringRef Str,
MutableArrayRef<unsigned> Digits);
};
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index 3366fc48d711..54bed09e0adf 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -116,7 +116,7 @@ public:
const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
/// Print a command argument, and optionally quote it.
- static void printArg(llvm::raw_ostream &OS, const char *Arg, bool Quote);
+ static void printArg(llvm::raw_ostream &OS, StringRef Arg, bool Quote);
};
/// Like Command, but with a fallback which is executed in case
@@ -175,6 +175,7 @@ public:
const list_type &getJobs() const { return Jobs; }
+ bool empty() const { return Jobs.empty(); }
size_type size() const { return Jobs.size(); }
iterator begin() { return Jobs.begin(); }
const_iterator begin() const { return Jobs.begin(); }
diff --git a/include/clang/Driver/Multilib.h b/include/clang/Driver/Multilib.h
index 6b54d72d7c49..0419186b745d 100644
--- a/include/clang/Driver/Multilib.h
+++ b/include/clang/Driver/Multilib.h
@@ -12,7 +12,6 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Option/Option.h"
#include <functional>
#include <string>
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index d03ab0435a6e..1f1222e10636 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -266,6 +266,8 @@ def MF : JoinedOrSeparate<["-"], "MF">, Group<M_Group>,
MetaVarName<"<file>">;
def MG : Flag<["-"], "MG">, Group<M_Group>, Flags<[CC1Option]>,
HelpText<"Add missing headers to depfile">;
+def MJ : JoinedOrSeparate<["-"], "MJ">, Group<M_Group>,
+ HelpText<"Write a compilation database entry per input">;
def MP : Flag<["-"], "MP">, Group<M_Group>, Flags<[CC1Option]>,
HelpText<"Create phony target for each dependency (other than main file)">;
def MQ : JoinedOrSeparate<["-"], "MQ">, Group<M_Group>, Flags<[CC1Option]>,
@@ -389,6 +391,8 @@ def cl_std_EQ : Joined<["-"], "cl-std=">, Group<opencl_Group>, Flags<[CC1Option]
HelpText<"OpenCL language standard to compile for.">;
def cl_denorms_are_zero : Flag<["-"], "cl-denorms-are-zero">, Group<opencl_Group>, Flags<[CC1Option]>,
HelpText<"OpenCL only. Allow denormals to be flushed to zero.">;
+def cl_fp32_correctly_rounded_divide_sqrt : Flag<["-"], "cl-fp32-correctly-rounded-divide-sqrt">, Group<opencl_Group>, Flags<[CC1Option]>,
+ HelpText<"OpenCL only. Specify that single precision floating-point divide and sqrt used in the program source are correctly rounded.">;
def client__name : JoinedOrSeparate<["-"], "client_name">;
def combine : Flag<["-", "--"], "combine">, Flags<[DriverOption, Unsupported]>;
def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">;
@@ -410,6 +414,9 @@ def cuda_compile_host_device : Flag<["--"], "cuda-compile-host-device">,
"effect on non-CUDA compilations.">;
def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption]>,
HelpText<"CUDA GPU architecture (e.g. sm_35). May be specified more than once.">;
+def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[DriverOption]>,
+ HelpText<"Remove GPU architecture (e.g. sm_35) from the list of GPUs to compile for. "
+ "'all' resets the list to its default value.">;
def cuda_noopt_device_debug : Flag<["--"], "cuda-noopt-device-debug">,
HelpText<"Enable device-side debug info generation. Disables ptxas optimizations.">;
def no_cuda_version_check : Flag<["--"], "no-cuda-version-check">,
@@ -418,6 +425,8 @@ def no_cuda_version_check : Flag<["--"], "no-cuda-version-check">,
def no_cuda_noopt_device_debug : Flag<["--"], "no-cuda-noopt-device-debug">;
def cuda_path_EQ : Joined<["--"], "cuda-path=">, Group<i_Group>,
HelpText<"CUDA installation path">;
+def ptxas_path_EQ : Joined<["--"], "ptxas-path=">, Group<i_Group>,
+ HelpText<"Path to ptxas (used for compiling CUDA code)">;
def fcuda_flush_denormals_to_zero : Flag<["-"], "fcuda-flush-denormals-to-zero">,
Flags<[CC1Option]>, HelpText<"Flush denormal floating point values to zero in CUDA device mode.">;
def fno_cuda_flush_denormals_to_zero : Flag<["-"], "fno-cuda-flush-denormals-to-zero">;
@@ -427,6 +436,8 @@ def fno_cuda_approx_transcendentals : Flag<["-"], "fno-cuda-approx-transcendenta
def dA : Flag<["-"], "dA">, Group<d_Group>;
def dD : Flag<["-"], "dD">, Group<d_Group>, Flags<[CC1Option]>,
HelpText<"Print macro definitions in -E mode in addition to normal output">;
+def dI : Flag<["-"], "dI">, Group<d_Group>, Flags<[CC1Option]>,
+ HelpText<"Print include directives in -E mode in addition to normal output">;
def dM : Flag<["-"], "dM">, Group<d_Group>, Flags<[CC1Option]>,
HelpText<"Print macro definitions in -E mode instead of normal output">;
def dead__strip : Flag<["-"], "dead_strip">;
@@ -479,6 +490,13 @@ def fno_autolink : Flag <["-"], "fno-autolink">, Group<f_Group>,
Flags<[DriverOption, CC1Option]>,
HelpText<"Disable generation of linker directives for automatic library linking">;
+// C++ Coroutines TS
+def fcoroutines_ts : Flag <["-"], "fcoroutines-ts">, Group<f_Group>,
+ Flags<[DriverOption, CC1Option]>,
+ HelpText<"Enable support for the C++ Coroutines TS">;
+def fno_coroutines_ts : Flag <["-"], "fno-coroutines-ts">, Group<f_Group>,
+ Flags<[DriverOption]>;
+
def fembed_bitcode_EQ : Joined<["-"], "fembed-bitcode=">,
Group<f_Group>, Flags<[DriverOption, CC1Option]>, MetaVarName<"<option>">,
HelpText<"Embed LLVM bitcode (option: off, all, bitcode, marker)">;
@@ -499,15 +517,15 @@ def fprofile_sample_use_EQ : Joined<["-"], "fprofile-sample-use=">,
def fauto_profile_EQ : Joined<["-"], "fauto-profile=">,
Alias<fprofile_sample_use_EQ>;
def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">,
- Group<f_Group>, Flags<[DriverOption]>,
+ Group<f_Group>, Flags<[CoreOption]>,
HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overriden by '=' form of option or LLVM_PROFILE_FILE env var)">;
def fprofile_instr_generate_EQ : Joined<["-"], "fprofile-instr-generate=">,
- Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<file>">,
+ Group<f_Group>, Flags<[CoreOption]>, MetaVarName<"<file>">,
HelpText<"Generate instrumented code to collect execution counts into <file> (overridden by LLVM_PROFILE_FILE env var)">;
def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group<f_Group>,
- Flags<[DriverOption]>;
+ Flags<[CoreOption]>;
def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">,
- Group<f_Group>, Flags<[DriverOption]>,
+ Group<f_Group>, Flags<[CoreOption]>,
HelpText<"Use instrumentation data for profile-guided optimization">;
def fcoverage_mapping : Flag<["-"], "fcoverage-mapping">,
Group<f_Group>, Flags<[CC1Option]>,
@@ -544,6 +562,8 @@ def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>;
def fborland_extensions : Flag<["-"], "fborland-extensions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Accept non-standard constructs supported by the Borland compiler">;
def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>;
+def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group<f_Group>,
+ Flags<[DriverOption]>, HelpText<"Load the clang builtins module map file.">;
def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>;
def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>,
@@ -581,6 +601,8 @@ def fdiagnostics_parseable_fixits : Flag<["-"], "fdiagnostics-parseable-fixits">
def fdiagnostics_print_source_range_info : Flag<["-"], "fdiagnostics-print-source-range-info">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Print source range spans in numeric form">;
+def fdiagnostics_show_hotness : Flag<["-"], "fdiagnostics-show-hotness">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Enable profile hotness information in diagnostic line">;
def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Print option name with mappable diagnostics">;
def fdiagnostics_show_note_include_stack : Flag<["-"], "fdiagnostics-show-note-include-stack">,
@@ -624,6 +646,7 @@ def : Flag<["-"], "fno-defer-pop">, Group<clang_ignored_gcc_optimization_f_Group
def : Flag<["-"], "fextended-identifiers">, Group<clang_ignored_f_Group>;
def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>, Flags<[Unsupported]>;
def fhosted : Flag<["-"], "fhosted">, Group<f_Group>;
+def fdenormal_fp_math_EQ : Joined<["-"], "fdenormal-fp-math=">, Group<f_Group>, Flags<[CC1Option]>;
def ffast_math : Flag<["-"], "ffast-math">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Allow aggressive, lossy floating-point optimizations">;
def fno_fast_math : Flag<["-"], "fno-fast-math">, Group<f_Group>;
@@ -675,6 +698,9 @@ def fsanitize_address_field_padding : Joined<["-"], "fsanitize-address-field-pad
def fsanitize_address_use_after_scope : Flag<["-"], "fsanitize-address-use-after-scope">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Enable use-after-scope detection in AddressSanitizer">;
+def fno_sanitize_address_use_after_scope : Flag<["-"], "fno-sanitize-address-use-after-scope">,
+ Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Disable use-after-scope detection in AddressSanitizer">;
def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>,
Flags<[CoreOption]>;
def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
@@ -711,6 +737,24 @@ def fsanitize_stats : Flag<["-"], "fsanitize-stats">,
def fno_sanitize_stats : Flag<["-"], "fno-sanitize-stats">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Disable sanitizer statistics gathering.">;
+def fsanitize_thread_memory_access : Flag<["-"], "fsanitize-thread-memory-access">,
+ Group<f_clang_Group>,
+ HelpText<"Enable memory access instrumentation in ThreadSanitizer (default)">;
+def fno_sanitize_thread_memory_access : Flag<["-"], "fno-sanitize-thread-memory-access">,
+ Group<f_clang_Group>,
+ HelpText<"Disable memory access instrumentation in ThreadSanitizer">;
+def fsanitize_thread_func_entry_exit : Flag<["-"], "fsanitize-thread-func-entry-exit">,
+ Group<f_clang_Group>,
+ HelpText<"Enable function entry/exit instrumentation in ThreadSanitizer (default)">;
+def fno_sanitize_thread_func_entry_exit : Flag<["-"], "fno-sanitize-thread-func-entry-exit">,
+ Group<f_clang_Group>,
+ HelpText<"Disable function entry/exit instrumentation in ThreadSanitizer">;
+def fsanitize_thread_atomics : Flag<["-"], "fsanitize-thread-atomics">,
+ Group<f_clang_Group>,
+ HelpText<"Enable atomic operations instrumentation in ThreadSanitizer (default)">;
+def fno_sanitize_thread_atomics : Flag<["-"], "fno-sanitize-thread-atomics">,
+ Group<f_clang_Group>,
+ HelpText<"Disable atomic operations instrumentation in ThreadSanitizer">;
def fsanitize_undefined_strip_path_components_EQ : Joined<["-"], "fsanitize-undefined-strip-path-components=">,
Group<f_clang_Group>, Flags<[CC1Option]>, MetaVarName<"<number>">,
HelpText<"Strip (or keep only, if negative) a given number of path components "
@@ -738,8 +782,8 @@ def fno_honor_infinities : Flag<["-"], "fno-honor-infinities">, Group<f_Group>;
// This option was originally misspelt "infinites" [sic].
def : Flag<["-"], "fhonor-infinites">, Alias<fhonor_infinities>;
def : Flag<["-"], "fno-honor-infinites">, Alias<fno_honor_infinities>;
-def ftrapping_math : Flag<["-"], "ftrapping-math">, Group<f_Group>;
-def fno_trapping_math : Flag<["-"], "fno-trapping-math">, Group<f_Group>;
+def ftrapping_math : Flag<["-"], "ftrapping-math">, Group<f_Group>, Flags<[CC1Option]>;
+def fno_trapping_math : Flag<["-"], "fno-trapping-math">, Group<f_Group>, Flags<[CC1Option]>;
def ffp_contract : Joined<["-"], "ffp-contract=">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Form fused FP ops (e.g. FMAs): fast (everywhere)"
" | on (according to FP_CONTRACT pragma, default) | off (never fuse)">;
@@ -779,6 +823,9 @@ def finline_functions : Flag<["-"], "finline-functions">, Group<f_clang_Group>,
def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Inline functions wich are (explicitly or implicitly) marked inline">;
def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
+def fexperimental_new_pass_manager : Flag<["-"], "fexperimental-new-pass-manager">,
+ Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Enables an experimental new pass manager in LLVM.">;
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]>,
@@ -803,10 +850,15 @@ def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Gr
def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;
def flto_EQ : Joined<["-"], "flto=">, Flags<[CC1Option]>, Group<f_Group>,
HelpText<"Set LTO mode to either 'full' or 'thin'">;
-def flto : Flag<["-"], "flto">, Flags<[CC1Option]>, Group<f_Group>,
+def flto : Flag<["-"], "flto">, Flags<[CoreOption, CC1Option]>, Group<f_Group>,
HelpText<"Enable LTO in 'full' mode">;
def fno_lto : Flag<["-"], "fno-lto">, Group<f_Group>,
HelpText<"Disable LTO mode (default)">;
+def flto_jobs_EQ : Joined<["-"], "flto-jobs=">,
+ Flags<[CC1Option]>, Group<f_Group>,
+ HelpText<"Controls the backend parallelism of -flto=thin (default "
+ "of 0 means the number of threads will be derived from "
+ "the number of CPUs detected)">;
def fthinlto_index_EQ : Joined<["-"], "fthinlto-index=">,
Flags<[CC1Option]>, Group<f_Group>,
HelpText<"Perform ThinLTO importing using provided function summary index">;
@@ -838,6 +890,9 @@ def fmodules_cache_path : Joined<["-"], "fmodules-cache-path=">, Group<i_Group>,
def fmodules_user_build_path : Separate<["-"], "fmodules-user-build-path">, Group<i_Group>,
Flags<[DriverOption, CC1Option]>, MetaVarName<"<directory>">,
HelpText<"Specify the module user build path">;
+def fprebuilt_module_path : Joined<["-"], "fprebuilt-module-path=">, Group<i_Group>,
+ Flags<[DriverOption, CC1Option]>, MetaVarName<"<directory>">,
+ HelpText<"Specify the prebuilt module path">;
def fmodules_prune_interval : Joined<["-"], "fmodules-prune-interval=">, Group<i_Group>,
Flags<[CC1Option]>, MetaVarName<"<seconds>">,
HelpText<"Specify the interval (in seconds) between attempts to prune the module cache">;
@@ -857,6 +912,9 @@ def fmodules_validate_once_per_build_session : Flag<["-"], "fmodules-validate-on
Group<i_Group>, Flags<[CC1Option]>,
HelpText<"Don't verify input files for the modules if the module has been "
"successfully validated or loaded during this build session">;
+def fmodules_disable_diagnostic_validation : Flag<["-"], "fmodules-disable-diagnostic-validation">,
+ Group<i_Group>, Flags<[CC1Option]>,
+ HelpText<"Disable validation of the diagnostic options when loading the module">;
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">;
@@ -866,6 +924,8 @@ def fmodules : Flag <["-"], "fmodules">, Group<f_Group>,
def fimplicit_module_maps : Flag <["-"], "fimplicit-module-maps">, Group<f_Group>,
Flags<[DriverOption, CC1Option]>,
HelpText<"Implicitly search the file system for module map files.">;
+def fmodules_ts : Flag <["-"], "fmodules-ts">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Enable support for the C++ Modules TS">;
def fmodule_maps : Flag <["-"], "fmodule-maps">, Alias<fimplicit_module_maps>;
def fmodule_name_EQ : Joined<["-"], "fmodule-name=">, Group<f_Group>,
Flags<[DriverOption,CC1Option]>, MetaVarName<"<name>">,
@@ -928,6 +988,7 @@ def fno_cxx_modules : Flag <["-"], "fno-cxx-modules">, Group<f_Group>,
Flags<[DriverOption]>;
def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Do not include fixit information in diagnostics">;
+def fno_diagnostics_show_hotness : Flag<["-"], "fno-diagnostics-show-hotness">, Group<f_Group>;
def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group<f_Group>;
def fno_diagnostics_show_note_include_stack : Flag<["-"], "fno-diagnostics-show-note-include-stack">,
Flags<[CC1Option]>, Group<f_Group>;
@@ -942,6 +1003,9 @@ 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 fno_experimental_new_pass_manager : Flag<["-"], "fno-experimental-new-pass-manager">,
+ Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Disables an experimental new pass manager in LLVM.">;
def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use the given vector functions library">;
def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>,
@@ -983,6 +1047,8 @@ def fno_show_column : Flag<["-"], "fno-show-column">, Group<f_Group>, Flags<[CC1
HelpText<"Do not include column number on diagnostics">;
def fno_show_source_location : Flag<["-"], "fno-show-source-location">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Do not include source location information with diagnostics">;
+def fdiagnostics_absolute_paths : Flag<["-"], "fdiagnostics-absolute-paths">, Group<f_Group>,
+ Flags<[CC1Option, CoreOption]>, HelpText<"Print absolute paths in diagnostics">;
def fno_spell_checking : Flag<["-"], "fno-spell-checking">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Disable spell-checking">;
def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>,
@@ -1022,14 +1088,26 @@ def fapplication_extension : Flag<["-"], "fapplication-extension">,
HelpText<"Restrict code to those available for App Extensions">;
def fno_application_extension : Flag<["-"], "fno-application-extension">,
Group<f_Group>;
+def frelaxed_template_template_args : Flag<["-"], "frelaxed-template-template-args">,
+ Flags<[CC1Option]>, HelpText<"Enable C++17 relaxed template template argument matching">,
+ Group<f_Group>;
+def fno_relaxed_template_template_args : Flag<["-"], "fno-relaxed-template-template-args">,
+ Group<f_Group>;
def fsized_deallocation : Flag<["-"], "fsized-deallocation">, Flags<[CC1Option]>,
HelpText<"Enable C++14 sized global deallocation functions">, Group<f_Group>;
def fno_sized_deallocation: Flag<["-"], "fno-sized-deallocation">, Group<f_Group>;
+def faligned_allocation : Flag<["-"], "faligned-allocation">, Flags<[CC1Option]>,
+ HelpText<"Enable C++17 aligned allocation functions">, Group<f_Group>;
+def fno_aligned_allocation: Flag<["-"], "fno-aligned-allocation">,
+ Group<f_Group>, Flags<[CC1Option]>;
+def fnew_alignment_EQ : Joined<["-"], "fnew-alignment=">,
+ HelpText<"Specifies the largest alignment guaranteed by '::operator new(size_t)'">,
+ MetaVarName<"<align>">, Group<f_Group>, Flags<[CC1Option]>;
+def : Separate<["-"], "fnew-alignment">, Alias<fnew_alignment_EQ>;
+def : Flag<["-"], "faligned-new">, Alias<faligned_allocation>;
+def : Flag<["-"], "fno-aligned-new">, Alias<fno_aligned_allocation>;
+def faligned_new_EQ : Joined<["-"], "faligned-new=">;
-def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Use GC exclusively for Objective-C related memory management">;
-def fobjc_gc : Flag<["-"], "fobjc-gc">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Enable Objective-C garbage collection">;
def fobjc_legacy_dispatch : Flag<["-"], "fobjc-legacy-dispatch">, Group<f_Group>;
def fobjc_new_property : Flag<["-"], "fobjc-new-property">, Group<clang_ignored_f_Group>;
def fobjc_infer_related_result_type : Flag<["-"], "fobjc-infer-related-result-type">,
@@ -1061,6 +1139,8 @@ def fopenmp_use_tls : Flag<["-"], "fopenmp-use-tls">, Group<f_Group>, Flags<[NoA
def fnoopenmp_use_tls : Flag<["-"], "fnoopenmp-use-tls">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
def fopenmp_targets_EQ : CommaJoined<["-"], "fopenmp-targets=">, Flags<[DriverOption, CC1Option]>,
HelpText<"Specify comma-separated list of triples OpenMP offloading targets to be supported">;
+def fopenmp_dump_offload_linker_script : Flag<["-"], "fopenmp-dump-offload-linker-script">, Group<f_Group>,
+ Flags<[NoArgumentUnused]>;
def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;
@@ -1084,8 +1164,15 @@ def fpic : Flag<["-"], "fpic">, Group<f_Group>;
def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>;
def fpie : Flag<["-"], "fpie">, Group<f_Group>;
def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>;
+def fropi : Flag<["-"], "fropi">, Group<f_Group>;
+def fno_ropi : Flag<["-"], "fno-ropi">, Group<f_Group>;
+def frwpi : Flag<["-"], "frwpi">, Group<f_Group>;
+def fno_rwpi : Flag<["-"], "fno-rwpi">, Group<f_Group>;
def fplugin_EQ : Joined<["-"], "fplugin=">, Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<dsopath>">,
HelpText<"Load the named plugin (dynamic shared object)">;
+def fpreserve_as_comments : Flag<["-"], "fpreserve-as-comments">, Group<f_Group>;
+def fno_preserve_as_comments : Flag<["-"], "fno-preserve-as-comments">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Do not preserve comments in inline assembly">;
def fprofile_arcs : Flag<["-"], "fprofile-arcs">, Group<f_Group>;
def fno_profile_arcs : Flag<["-"], "fno-profile-arcs">, Group<f_Group>;
def framework : Separate<["-"], "framework">, Flags<[LinkerInput]>;
@@ -1118,12 +1205,12 @@ def fstack_protector_strong : Flag<["-"], "fstack-protector-strong">, Group<f_Gr
HelpText<"Use a strong heuristic to apply stack protectors to functions">;
def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>,
HelpText<"Enable stack protectors for functions potentially vulnerable to stack smashing">;
-def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>,
+def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>, Flags<[CoreOption]>,
HelpText<"Emit full debug info for all types used by the program">;
-def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>,
+def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>, Flags<[CoreOption]>,
HelpText<"Limit debug information produced to reduce size of debug binary">;
-def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Alias<fno_standalone_debug>;
-def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Alias<fstandalone_debug>;
+def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Flags<[CoreOption]>, Alias<fno_standalone_debug>;
+def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Flags<[CoreOption]>, Alias<fstandalone_debug>;
def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>,
Flags<[DriverOption, CoreOption]>;
def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>,
@@ -1143,6 +1230,15 @@ def ftemplate_backtrace_limit_EQ : Joined<["-"], "ftemplate-backtrace-limit=">,
Group<f_Group>;
def foperator_arrow_depth_EQ : Joined<["-"], "foperator-arrow-depth=">,
Group<f_Group>;
+
+def fsave_optimization_record : Flag<["-"], "fsave-optimization-record">,
+ Group<f_Group>, HelpText<"Generate a YAML optimization record file">;
+def fno_save_optimization_record : Flag<["-"], "fno-save-optimization-record">,
+ Group<f_Group>, Flags<[NoArgumentUnused]>;
+def foptimization_record_file_EQ : Joined<["-"], "foptimization-record-file=">,
+ Group<f_Group>,
+ HelpText<"Specify the file name of any generated YAML optimization record">;
+
def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>;
def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>,
HelpText<"Enable the loop vectorization passes">;
@@ -1240,6 +1336,10 @@ def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">;
def fno_debug_types_section: Flag<["-"], "fno-debug-types-section">, Group<f_Group>,
Flags<[CC1Option]>;
+def fsplit_dwarf_inlining: Flag <["-"], "fsplit-dwarf-inlining">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">;
+def fno_split_dwarf_inlining: Flag<["-"], "fno-split-dwarf-inlining">, Group<f_Group>,
+ Flags<[CC1Option]>;
def fdebug_prefix_map_EQ
: Joined<["-"], "fdebug-prefix-map=">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"remap file source paths in debug info">;
@@ -1286,12 +1386,12 @@ def gno_record_gcc_switches : Flag<["-"], "gno-record-gcc-switches">,
Group<g_flags_Group>;
def gstrict_dwarf : Flag<["-"], "gstrict-dwarf">, Group<g_flags_Group>;
def gno_strict_dwarf : Flag<["-"], "gno-strict-dwarf">, Group<g_flags_Group>;
-def gcolumn_info : Flag<["-"], "gcolumn-info">, Group<g_flags_Group>;
-def gno_column_info : Flag<["-"], "gno-column-info">, Group<g_flags_Group>;
+def gcolumn_info : Flag<["-"], "gcolumn-info">, Group<g_flags_Group>, Flags<[CoreOption]>;
+def gno_column_info : Flag<["-"], "gno-column-info">, Group<g_flags_Group>, Flags<[CoreOption]>;
def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>;
def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>;
def gdwarf_aranges : Flag<["-"], "gdwarf-aranges">, Group<g_flags_Group>;
-def gmodules : Flag <["-"], "gmodules">, Group<f_Group>,
+def gmodules : Flag <["-"], "gmodules">, Group<gN_Group>,
HelpText<"Generate debug info with external references to clang modules"
" or precompiled headers">;
def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">;
@@ -1364,6 +1464,16 @@ def malign_functions_EQ : Joined<["-"], "malign-functions=">, Group<clang_ignore
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 mlong_calls : Flag<["-"], "mlong-calls">, Group<m_Group>,
+ HelpText<"Generate branches with extended addressability, usually via indirect jumps.">;
+def mno_long_calls : Flag<["-"], "mno-long-calls">, Group<m_Group>,
+ HelpText<"Restore the default behaviour of not generating long calls">;
+def mexecute_only : Flag<["-"], "mexecute-only">, Group<m_arm_Features_Group>,
+ HelpText<"Disallow generation of data access to code sections (ARM only)">;
+def mno_execute_only : Flag<["-"], "mno-execute-only">, Group<m_arm_Features_Group>,
+ HelpText<"Allow generation of data access to code sections (ARM only)">;
+def mpure_code : Flag<["-"], "mpure-code">, Alias<mexecute_only>; // Alias for GCC compatibility
+def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias<mno_execute_only>;
def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group<m_Group>;
def mappletvos_version_min_EQ : Joined<["-"], "mappletvos-version-min=">, Alias<mtvos_version_min_EQ>;
def mtvos_simulator_version_min_EQ : Joined<["-"], "mtvos-simulator-version-min=">, Alias<mtvos_version_min_EQ>;
@@ -1374,6 +1484,7 @@ def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=
def march_EQ : Joined<["-"], "march=">, Group<m_Group>;
def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[DriverOption]>;
def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>;
+def mimplicit_it_EQ : Joined<["-"], "mimplicit-it=">, Group<m_Group>;
def mconstant_cfstrings : Flag<["-"], "mconstant-cfstrings">, Group<clang_ignored_m_Group>;
def mconsole : Joined<["-"], "mconsole">, Group<m_Group>, Flags<[DriverOption]>;
def mwindows : Joined<["-"], "mwindows">, Group<m_Group>, Flags<[DriverOption]>;
@@ -1507,10 +1618,6 @@ def mcrc : Flag<["-"], "mcrc">, Group<m_arm_Features_Group>,
HelpText<"Allow use of CRC instructions (ARM only)">;
def mnocrc : Flag<["-"], "mnocrc">, Group<m_arm_Features_Group>,
HelpText<"Disallow use of CRC instructions (ARM only)">;
-def mlong_calls : Flag<["-"], "mlong-calls">, Group<m_arm_Features_Group>,
- HelpText<"Generate an indirect jump to enable jumps further than 64M">;
-def mno_long_calls : Flag<["-"], "mno-long-calls">, Group<m_arm_Features_Group>,
- HelpText<"Restore the default behaviour of not generating long calls">;
def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_aarch64_Features_Group>,
HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">;
@@ -1539,6 +1646,10 @@ 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 mpower9_vector : Flag<["-"], "mpower9-vector">,
+ Group<m_ppc_Features_Group>;
+def mno_power9_vector : Flag<["-"], "mno-power9-vector">,
+ Group<m_ppc_Features_Group>;
def mpower8_crypto : Flag<["-"], "mcrypto">,
Group<m_ppc_Features_Group>;
def mnopower8_crypto : Flag<["-"], "mno-crypto">,
@@ -1574,6 +1685,10 @@ def mfloat128: Flag<["-"], "mfloat128">,
Group<m_ppc_Features_Group>;
def mno_float128 : Flag<["-"], "mno-float128">,
Group<m_ppc_Features_Group>;
+def mlongcall: Flag<["-"], "mlongcall">,
+ Group<m_ppc_Features_Group>;
+def mno_longcall : Flag<["-"], "mno-longcall">,
+ Group<m_ppc_Features_Group>;
def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable AltiVec vector initializer syntax">;
@@ -1620,6 +1735,10 @@ def mno_implicit_float : Flag<["-"], "mno-implicit-float">, Group<m_Group>,
def mimplicit_float : Flag<["-"], "mimplicit-float">, Group<m_Group>;
def mrecip : Flag<["-"], "mrecip">, Group<m_Group>;
def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group<m_Group>, Flags<[CC1Option]>;
+def mpie_copy_relocations : Flag<["-"], "mpie-copy-relocations">, Group<m_Group>,
+ Flags<[CC1Option]>,
+ HelpText<"Use copy relocations support for PIE builds">;
+def mno_pie_copy_relocations : Flag<["-"], "mno-pie-copy-relocations">, Group<m_Group>;
def mx87 : Flag<["-"], "mx87">, Group<m_x86_Features_Group>;
def m80387 : Flag<["-"], "m80387">, Alias<mx87>;
def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>;
@@ -1754,7 +1873,8 @@ def mno_odd_spreg : Flag<["-"], "mno-odd-spreg">, Group<m_Group>,
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 module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
+ HelpText<"Provide information about a particular module file">;
def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>;
def multi__module : Flag<["-"], "multi_module">;
@@ -1802,7 +1922,8 @@ def print_file_name_EQ : Joined<["-", "--"], "print-file-name=">,
def print_ivar_layout : Flag<["-"], "print-ivar-layout">, Flags<[CC1Option]>,
HelpText<"Enable Objective-C Ivar layout bitmap print trace">;
def print_libgcc_file_name : Flag<["-", "--"], "print-libgcc-file-name">,
- HelpText<"Print the library path for \"libgcc.a\"">;
+ HelpText<"Print the library path for the currently used compiler runtime "
+ "library (\"libgcc.a\" or \"libclang_rt.builtins.*.a\")">;
def print_multi_directory : Flag<["-", "--"], "print-multi-directory">;
def print_multi_lib : Flag<["-", "--"], "print-multi-lib">;
def print_multi_os_directory : Flag<["-", "--"], "print-multi-os-directory">,
@@ -1828,16 +1949,22 @@ def rdynamic : Flag<["-"], "rdynamic">;
def resource_dir : Separate<["-"], "resource-dir">,
Flags<[DriverOption, CC1Option, CoreOption, HelpHidden]>,
HelpText<"The directory which holds the compiler resource files">;
-def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[DriverOption]>,
+def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[DriverOption, CoreOption]>,
Alias<resource_dir>;
def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>;
-def rtlib_EQ : Joined<["-", "--"], "rtlib=">;
+def rtlib_EQ : Joined<["-", "--"], "rtlib=">,
+ HelpText<"Compiler runtime library to use">;
def r : Flag<["-"], "r">, Flags<[LinkerInput,NoArgumentUnused]>;
def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[DriverOption]>,
HelpText<"Save intermediate compilation results.">;
def save_temps : Flag<["-", "--"], "save-temps">, Flags<[DriverOption]>,
Alias<save_temps_EQ>, AliasArgs<["cwd"]>,
HelpText<"Save intermediate compilation results">;
+def save_stats_EQ : Joined<["-", "--"], "save-stats=">, Flags<[DriverOption]>,
+ HelpText<"Save llvm statistics.">;
+def save_stats : Flag<["-", "--"], "save-stats">, Flags<[DriverOption]>,
+ Alias<save_stats_EQ>, AliasArgs<["cwd"]>,
+ HelpText<"Save llvm statistics.">;
def via_file_asm : Flag<["-", "--"], "via-file-asm">, InternalDebugOpt,
HelpText<"Write assembly to file for input to assemble jobs">;
def sectalign : MultiArg<["-"], "sectalign", 3>;
@@ -1940,7 +2067,8 @@ def _CLASSPATH : Separate<["--"], "CLASSPATH">, Alias<fclasspath_EQ>;
def _all_warnings : Flag<["--"], "all-warnings">, Alias<Wall>;
def _analyze_auto : Flag<["--"], "analyze-auto">, Flags<[DriverOption]>;
def _analyzer_no_default_checks : Flag<["--"], "analyzer-no-default-checks">, Flags<[DriverOption]>;
-def _analyzer_output : JoinedOrSeparate<["--"], "analyzer-output">, Flags<[DriverOption]>;
+def _analyzer_output : JoinedOrSeparate<["--"], "analyzer-output">, Flags<[DriverOption]>,
+ HelpText<"Static analyzer report output format (html|plist|plist-multi-file|plist-html|text).">;
def _analyze : Flag<["--"], "analyze">, Flags<[DriverOption, CoreOption]>,
HelpText<"Run the static analyzer">;
def _assemble : Flag<["--"], "assemble">, Alias<S>;
@@ -2004,6 +2132,8 @@ def _output_EQ : Joined<["--"], "output=">, Alias<o>;
def _output : Separate<["--"], "output">, Alias<o>;
def _param : Separate<["--"], "param">, Group<CompileOnly_Group>;
def _param_EQ : Joined<["--"], "param=">, Alias<_param>;
+def _precompile : Flag<["--"], "precompile">, Flags<[DriverOption]>,
+ Group<Action_Group>, HelpText<"Only precompile the input">;
def _prefix_EQ : Joined<["--"], "prefix=">, Alias<B>;
def _prefix : Separate<["--"], "prefix">, Alias<B>;
def _preprocess : Flag<["--"], "preprocess">, Alias<E>;
@@ -2086,9 +2216,9 @@ multiclass BooleanFFlag<string name> {
defm : BooleanFFlag<"keep-inline-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
-def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<clang_ignored_gcc_optimization_f_Group>;
+def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<f_Group>;
-def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>;
+def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>, Flags<[CoreOption]>;
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>;
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
index 7b293e03d350..6206680118d5 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -38,6 +38,9 @@ class SanitizerArgs {
bool LinkCXXRuntimes = false;
bool NeedPIE = false;
bool Stats = false;
+ bool TsanMemoryAccess = true;
+ bool TsanFuncEntryExit = true;
+ bool TsanAtomics = true;
public:
/// Parses the sanitizer arguments from an argument list.
@@ -66,6 +69,7 @@ class SanitizerArgs {
bool requiresPIE() const;
bool needsUnwindTables() const;
bool linkCXXRuntimes() const { return LinkCXXRuntimes; }
+ bool hasCrossDsoCfi() const { return CfiCrossDso; }
void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const;
};
diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h
index b9eac1cad65d..5012cc896683 100644
--- a/include/clang/Driver/Tool.h
+++ b/include/clang/Driver/Tool.h
@@ -129,6 +129,20 @@ public:
const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const = 0;
+ /// Construct jobs to perform the action \p JA, writing to the \p Outputs and
+ /// with \p Inputs, and add the jobs to \p C. The default implementation
+ /// assumes a single output and is expected to be overloaded for the tools
+ /// that support multiple inputs.
+ ///
+ /// \param TCArgs The argument list for this toolchain, with any
+ /// tool chain specific translations applied.
+ /// \param LinkingOutput If this output will eventually feed the
+ /// linker, then this is the final output name of the linked image.
+ virtual void ConstructJobMultipleOutputs(Compilation &C, const JobAction &JA,
+ const InputInfoList &Outputs,
+ const InputInfoList &Inputs,
+ const llvm::opt::ArgList &TCArgs,
+ const char *LinkingOutput) const;
};
} // end namespace driver
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 2a15d7ab061c..cca239c4be2a 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -18,7 +18,6 @@
#include "clang/Driver/Util.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/Support/Path.h"
#include "llvm/Target/TargetOptions.h"
#include <memory>
#include <string>
@@ -39,8 +38,10 @@ class FileSystem;
namespace driver {
class Compilation;
+ class CudaInstallationDetector;
class Driver;
class JobAction;
+ class RegisterEffectiveTriple;
class SanitizerArgs;
class Tool;
@@ -85,16 +86,25 @@ private:
mutable std::unique_ptr<Tool> Clang;
mutable std::unique_ptr<Tool> Assemble;
mutable std::unique_ptr<Tool> Link;
+ mutable std::unique_ptr<Tool> OffloadBundler;
Tool *getClang() const;
Tool *getAssemble() const;
Tool *getLink() const;
Tool *getClangAs() const;
+ Tool *getOffloadBundler() const;
mutable std::unique_ptr<SanitizerArgs> SanitizerArguments;
+ /// The effective clang triple for the current Job.
+ mutable llvm::Triple EffectiveTriple;
+
+ /// Set the toolchain's effective clang triple.
+ void setEffectiveTriple(llvm::Triple ET) const { EffectiveTriple = ET; }
+
+ friend class RegisterEffectiveTriple;
+
protected:
MultilibSet Multilibs;
- const char *DefaultLinker = "ld";
ToolChain(const Driver &D, const llvm::Triple &T,
const llvm::opt::ArgList &Args);
@@ -142,6 +152,12 @@ public:
return Triple.getTriple();
}
+ /// Get the toolchain's effective clang triple.
+ const llvm::Triple &getEffectiveTriple() const {
+ assert(!EffectiveTriple.getTriple().empty() && "No effective triple");
+ return EffectiveTriple;
+ }
+
path_list &getFilePaths() { return FilePaths; }
const path_list &getFilePaths() const { return FilePaths; }
@@ -176,12 +192,15 @@ public:
/// TranslateArgs - Create a new derived argument list for any argument
/// translations this ToolChain may wish to perform, or 0 if no tool chain
- /// specific translations are needed.
+ /// specific translations are needed. If \p DeviceOffloadKind is specified
+ /// the translation specific for that offload kind is performed.
///
/// \param BoundArch - The bound architecture name, or 0.
+ /// \param DeviceOffloadKind - The device offload kind used for the
+ /// translation.
virtual llvm::opt::DerivedArgList *
- TranslateArgs(const llvm::opt::DerivedArgList &Args,
- const char *BoundArch) const {
+ TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
+ Action::OffloadKind DeviceOffloadKind) const {
return nullptr;
}
@@ -219,7 +238,7 @@ public:
/// LookupTypeForExtension - Return the default language type to use for the
/// given extension.
- virtual types::ID LookupTypeForExtension(const char *Ext) const;
+ virtual types::ID LookupTypeForExtension(StringRef Ext) const;
/// IsBlocksDefault - Does this tool chain enable -fblocks by default.
virtual bool IsBlocksDefault() const { return false; }
@@ -252,6 +271,11 @@ public:
return 0;
}
+ /// GetDefaultLinker - Get the default linker to use.
+ virtual const char *getDefaultLinker() const {
+ return "ld";
+ }
+
/// GetDefaultRuntimeLibType - Get the default runtime library variant to use.
virtual RuntimeLibType GetDefaultRuntimeLibType() const {
return ToolChain::RLT_Libgcc;
@@ -422,15 +446,28 @@ public:
virtual void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
+ /// \brief On Windows, returns the MSVC compatibility version.
+ virtual VersionTuple computeMSVCVersion(const Driver *D,
+ const llvm::opt::ArgList &Args) const;
+
/// \brief Return sanitizers which are available in this toolchain.
virtual SanitizerMask getSupportedSanitizers() const;
/// \brief Return sanitizers which are enabled by default.
virtual SanitizerMask getDefaultSanitizers() const { return 0; }
+};
+
+/// Set a ToolChain's effective triple. Reset it when the registration object
+/// is destroyed.
+class RegisterEffectiveTriple {
+ const ToolChain &TC;
+
+public:
+ RegisterEffectiveTriple(const ToolChain &TC, llvm::Triple T) : TC(TC) {
+ TC.setEffectiveTriple(T);
+ }
- /// \brief On Windows, returns the version of cl.exe. On other platforms,
- /// returns an empty VersionTuple.
- virtual VersionTuple getMSVCVersionFromExe() const { return VersionTuple(); }
+ ~RegisterEffectiveTriple() { TC.setEffectiveTriple(llvm::Triple()); }
};
} // end namespace driver
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
index f2ff194ee646..2430b5b924c3 100644
--- a/include/clang/Driver/Types.def
+++ b/include/clang/Driver/Types.def
@@ -34,6 +34,7 @@
// a - The type should only be assembled.
// p - The type should only be precompiled.
// u - The type can be user specified (with -x).
+// m - Precompiling this type produces a module file.
// A - The type's temporary suffix should be appended when generating
// outputs of this type.
@@ -65,6 +66,8 @@ TYPE("c++-header-cpp-output", PP_CXXHeader, INVALID, "ii", "p")
TYPE("c++-header", CXXHeader, PP_CXXHeader, "hh", "pu")
TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID, "mii", "p")
TYPE("objective-c++-header", ObjCXXHeader, PP_ObjCXXHeader, "h", "pu")
+TYPE("c++-module", CXXModule, PP_CXXModule, "cppm", "mu")
+TYPE("c++-module-cpp-output", PP_CXXModule, INVALID, "iim", "m")
// Other languages.
TYPE("ada", Ada, INVALID, nullptr, "u")
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
index 22122c7a8eb9..22a26ae46a0b 100644
--- a/include/clang/Driver/Types.h
+++ b/include/clang/Driver/Types.h
@@ -13,6 +13,9 @@
#include "clang/Driver/Phases.h"
#include "llvm/ADT/SmallVector.h"
+namespace llvm {
+class StringRef;
+}
namespace clang {
namespace driver {
namespace types {
@@ -32,6 +35,11 @@ namespace types {
/// preprocessed.
ID getPreprocessedType(ID Id);
+ /// getPrecompiledType - Get the ID of the type for this input when
+ /// it has been precompiled, or INVALID if this input is not
+ /// precompiled.
+ ID getPrecompiledType(ID Id);
+
/// getTypeTempSuffix - Return the suffix to use when creating a
/// temp file of this type, or null if unspecified.
const char *getTypeTempSuffix(ID Id, bool CLMode = false);
@@ -72,9 +80,14 @@ namespace types {
/// isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
bool isObjC(ID Id);
+ /// isSrcFile - Is this a source file, i.e. something that still has to be
+ /// preprocessed. The logic behind this is the same that decides if the first
+ /// compilation phase is a preprocessing one.
+ bool isSrcFile(ID Id);
+
/// lookupTypeForExtension - Lookup the type to use for the file
/// extension \p Ext.
- ID lookupTypeForExtension(const char *Ext);
+ ID lookupTypeForExtension(llvm::StringRef Ext);
/// lookupTypeForTypSpecifier - Lookup the type to use for a user
/// specified type name.
@@ -90,6 +103,10 @@ namespace types {
/// C type (used for clang++ emulation of g++ behaviour)
ID lookupCXXTypeForCType(ID Id);
+ /// Lookup header file input type that corresponds to given
+ /// source file type (used for clang-cl emulation of \Yc).
+ ID lookupHeaderTypeForSourceType(ID Id);
+
} // end namespace types
} // end namespace driver
} // end namespace clang
diff --git a/include/clang/Edit/Rewriters.h b/include/clang/Edit/Rewriters.h
index 5e3425f56f73..980ed1d3363f 100644
--- a/include/clang/Edit/Rewriters.h
+++ b/include/clang/Edit/Rewriters.h
@@ -9,7 +9,6 @@
#ifndef LLVM_CLANG_EDIT_REWRITERS_H
#define LLVM_CLANG_EDIT_REWRITERS_H
-#include "llvm/ADT/SmallVector.h"
namespace clang {
class ObjCMessageExpr;
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index 1ff305d030aa..6c6458b33d85 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -35,7 +35,7 @@ namespace format {
enum class ParseError { Success = 0, Error, Unsuitable };
class ParseErrorCategory final : public std::error_category {
public:
- const char *name() const LLVM_NOEXCEPT override;
+ const char *name() const noexcept override;
std::string message(int EV) const override;
};
const std::error_category &getParseCategory();
@@ -465,6 +465,8 @@ struct FormatStyle {
LK_Java,
/// Should be used for JavaScript.
LK_JavaScript,
+ /// Should be used for ObjC code.
+ LK_ObjC,
/// Should be used for Protocol Buffers
/// (https://developers.google.com/protocol-buffers/).
LK_Proto,
@@ -549,6 +551,9 @@ struct FormatStyle {
/// \brief If ``true``, a space may be inserted after C style casts.
bool SpaceAfterCStyleCast;
+ /// \brief If \c true, a space will be inserted after the 'template' keyword.
+ bool SpaceAfterTemplateKeyword;
+
/// \brief If ``false``, spaces will be removed before assignment operators.
bool SpaceBeforeAssignmentOperators;
@@ -698,6 +703,7 @@ struct FormatStyle {
PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
PointerAlignment == R.PointerAlignment &&
SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
+ SpaceAfterTemplateKeyword == R.SpaceAfterTemplateKeyword &&
SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators &&
SpaceBeforeParens == R.SpaceBeforeParens &&
SpaceInEmptyParentheses == R.SpaceInEmptyParentheses &&
@@ -779,13 +785,25 @@ formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
/// \brief Returns the replacements corresponding to applying \p Replaces and
/// cleaning up the code after that on success; otherwise, return an llvm::Error
/// carrying llvm::StringError.
-/// This also inserts a C++ #include directive into the correct block if the
-/// replacement corresponding to the header insertion has offset UINT_MAX.
+/// This also supports inserting/deleting C++ #include directives:
+/// - If a replacement has offset UINT_MAX, length 0, and a replacement text
+/// that is an #include directive, this will insert the #include into the
+/// correct block in the \p Code. When searching for points to insert new
+/// header, this ignores #include's after the #include block(s) in the
+/// beginning of a file to avoid inserting headers into code sections where
+/// new #include's should not be added by default. These code sections
+/// include:
+/// - raw string literals (containing #include).
+/// - #if blocks.
+/// - Special #include's among declarations (e.g. functions).
+/// - If a replacement has offset UINT_MAX, length 1, and a replacement text
+/// that is the name of the header to be removed, the header will be removed
+/// from \p Code if it exists.
llvm::Expected<tooling::Replacements>
cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
const FormatStyle &Style);
-/// \brief Reformats the given \p Ranges in the file \p ID.
+/// \brief Reformats the given \p Ranges in \p Code.
///
/// 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
@@ -797,31 +815,15 @@ cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
/// If ``IncompleteFormat`` is non-null, its value will be set to true if any
/// of the affected ranges were not formatted due to a non-recoverable syntax
/// error.
-tooling::Replacements reformat(const FormatStyle &Style,
- SourceManager &SourceMgr, FileID ID,
- ArrayRef<CharSourceRange> Ranges,
- bool *IncompleteFormat = nullptr);
-
-/// \brief Reformats the given \p Ranges in \p Code.
-///
-/// Otherwise identical to the reformat() function using a file ID.
tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
ArrayRef<tooling::Range> Ranges,
StringRef FileName = "<stdin>",
bool *IncompleteFormat = nullptr);
-/// \brief Clean up any erroneous/redundant code in the given \p Ranges in the
-/// file \p ID.
-///
-/// Returns the ``Replacements`` that clean up all \p Ranges in the file \p ID.
-tooling::Replacements cleanup(const FormatStyle &Style,
- SourceManager &SourceMgr, FileID ID,
- ArrayRef<CharSourceRange> Ranges);
-
/// \brief Clean up any erroneous/redundant code in the given \p Ranges in \p
/// Code.
///
-/// Otherwise identical to the cleanup() function using a file ID.
+/// Returns the ``Replacements`` that clean up all \p Ranges in \p Code.
tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code,
ArrayRef<tooling::Range> Ranges,
StringRef FileName = "<stdin>");
@@ -852,13 +854,16 @@ extern const char *StyleOptionHelpDescription;
/// == "file".
/// \param[in] FallbackStyle The name of a predefined style used to fallback to
/// in case the style can't be determined from \p StyleName.
+/// \param[in] Code The actual code to be formatted. Used to determine the
+/// language if the filename isn't sufficient.
/// \param[in] FS The underlying file system, in which the file resides. By
/// default, the file system is the real file system.
///
/// \returns FormatStyle as specified by ``StyleName``. If no style could be
/// determined, the default is LLVM Style (see ``getLLVMStyle()``).
FormatStyle getStyle(StringRef StyleName, StringRef FileName,
- StringRef FallbackStyle, vfs::FileSystem *FS = nullptr);
+ StringRef FallbackStyle, StringRef Code = "",
+ vfs::FileSystem *FS = nullptr);
// \brief Returns a string representation of ``Language``.
inline StringRef getLanguageName(FormatStyle::LanguageKind Language) {
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 04e6dce5110e..cc8d4e6e3e70 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -16,7 +16,6 @@
#include "clang-c/Index.h"
#include "clang/AST/ASTContext.h"
-#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
@@ -30,9 +29,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/MD5.h"
-#include "llvm/Support/Path.h"
#include <cassert>
-#include <map>
#include <memory>
#include <string>
#include <sys/types.h>
@@ -47,7 +44,6 @@ namespace clang {
class Sema;
class ASTContext;
class ASTReader;
-class CodeCompleteConsumer;
class CompilerInvocation;
class CompilerInstance;
class Decl;
@@ -58,7 +54,6 @@ class HeaderSearch;
class Preprocessor;
class PCHContainerOperations;
class PCHContainerReader;
-class SourceManager;
class TargetInfo;
class FrontendAction;
class ASTDeserializationListener;
@@ -437,9 +432,6 @@ private:
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);
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 6a4474cfe75f..1f0c83b5bfa7 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -1,4 +1,4 @@
-//===--- CodeGenOptions.def - Code generation option database ------ C++ -*-===//
+//===--- CodeGenOptions.def - Code generation option database ----- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,6 +32,7 @@ CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
CODEGENOPT(CompressDebugSections, 1, 0) ///< -Wa,-compress-debug-sections
CODEGENOPT(RelaxELFRelocations, 1, 0) ///< -Wa,--mrelax-relocations
CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm.
+CODEGENOPT(PreserveAsmComments, 1, 1) ///< -dA, -fno-preserve-as-comments.
CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) operator new
CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink
CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
@@ -48,13 +49,11 @@ CODEGENOPT(DisableFPElim , 1, 0) ///< Set when -fomit-frame-pointer is enabl
CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory.
CODEGENOPT(DiscardValueNames , 1, 0) ///< Discard Value Names from the IR (LLVMContext flag)
CODEGENOPT(DisableGCov , 1, 0) ///< Don't run the GCov pass, for testing.
-CODEGENOPT(DisableLLVMOpts , 1, 0) ///< Don't run any optimizations, for use in
- ///< getting .bc files that correspond to the
- ///< internal state before optimizations are
- ///< done.
CODEGENOPT(DisableLLVMPasses , 1, 0) ///< Don't run any LLVM IR passes to get
///< the pristine IR generated by the
///< frontend.
+CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental
+ ///< pass manager.
CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled.
CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls.
CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what
@@ -106,9 +105,10 @@ CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enable
CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf.
CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero
CODEGENOPT(ReciprocalMath , 1, 0) ///< Allow FP divisions to be reassociated.
-CODEGENOPT(NoInline , 1, 0) ///< Set when -fno-inline is enabled.
- ///< Disables use of the inline keyword.
+CODEGENOPT(NoTrappingMath , 1, 0) ///< Set when -fno-trapping-math is enabled.
CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN.
+CODEGENOPT(FlushDenorm , 1, 0) ///< Allow FP denorm numbers to be flushed to zero
+CODEGENOPT(CorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt
CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss.
/// \brief Method of Objective-C dispatch to use.
ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy)
@@ -148,10 +148,16 @@ CODEGENOPT(SanitizeCoverageTraceBB, 1, 0) ///< Enable basic block tracing in
///< in sanitizer coverage.
CODEGENOPT(SanitizeCoverageTraceCmp, 1, 0) ///< Enable cmp instruction tracing
///< in sanitizer coverage.
+CODEGENOPT(SanitizeCoverageTraceDiv, 1, 0) ///< Enable div instruction tracing
+ ///< in sanitizer coverage.
+CODEGENOPT(SanitizeCoverageTraceGep, 1, 0) ///< Enable GEP instruction tracing
+ ///< in sanitizer coverage.
CODEGENOPT(SanitizeCoverage8bitCounters, 1, 0) ///< Use 8-bit frequency counters
///< in sanitizer coverage.
CODEGENOPT(SanitizeCoverageTracePC, 1, 0) ///< Enable PC tracing
///< in sanitizer coverage.
+CODEGENOPT(SanitizeCoverageTracePCGuard, 1, 0) ///< Enable PC tracing with guard
+ ///< in sanitizer coverage.
CODEGENOPT(SanitizeStats , 1, 0) ///< Collect statistics for sanitizers.
CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.
CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float.
@@ -191,6 +197,9 @@ CODEGENOPT(DebugTypeExtRefs, 1, 0) ///< Whether or not debug info should contain
CODEGENOPT(DebugExplicitImport, 1, 0) ///< Whether or not debug info should
///< contain explicit imports for
///< anonymous namespaces
+CODEGENOPT(SplitDwarfInlining, 1, 1) ///< Whether to include inlining info in the
+ ///< skeleton CU to allow for symbolication
+ ///< of inline stack frames without .dwo files.
CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists.
@@ -224,10 +233,10 @@ VALUE_CODEGENOPT(DwarfVersion, 3, 0)
CODEGENOPT(EmitCodeView, 1, 0)
/// The kind of inlining to perform.
-ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining)
+ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NormalInlining)
// Vector functions library to use.
-ENUM_CODEGENOPT(VecLib, VectorLibrary, 1, NoLibrary)
+ENUM_CODEGENOPT(VecLib, VectorLibrary, 2, NoLibrary)
/// The default TLS model to use.
ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
@@ -236,6 +245,12 @@ ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
/// filename)
VALUE_CODEGENOPT(EmitCheckPathComponentsToStrip, 32, 0)
+/// Whether to report the hotness of the code region for optimization remarks.
+CODEGENOPT(DiagnosticsWithHotness, 1, 0)
+
+/// Whether copy relocations support is available when building as PIE.
+CODEGENOPT(PIECopyRelocations, 1, 0)
+
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
#undef VALUE_CODEGENOPT
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 4bc3120908f0..52bd1c5aff79 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -44,17 +44,18 @@ protected:
class CodeGenOptions : public CodeGenOptionsBase {
public:
enum InliningMethod {
- NoInlining, // Perform no inlining whatsoever.
NormalInlining, // Use the standard function inlining pass.
OnlyHintInlining, // Inline only (implicitly) hinted functions.
OnlyAlwaysInlining // Only run the always inlining pass.
};
enum VectorLibrary {
- NoLibrary, // Don't use any vector library.
- Accelerate // Use the Accelerate framework.
+ NoLibrary, // Don't use any vector library.
+ Accelerate, // Use the Accelerate framework.
+ SVML // Intel short vector math library.
};
+
enum ObjCDispatchMethodKind {
Legacy = 0,
NonLegacy = 1,
@@ -97,9 +98,13 @@ public:
/// The code model to use (-mcmodel).
std::string CodeModel;
- /// The filename with path we use for coverage files. The extension will be
- /// replaced.
- std::string CoverageFile;
+ /// The filename with path we use for coverage data files. The runtime
+ /// allows further manipulation with the GCOV_PREFIX and GCOV_PREFIX_STRIP
+ /// environment variables.
+ std::string CoverageDataFile;
+
+ /// The filename with path we use for coverage notes files.
+ std::string CoverageNotesFile;
/// The version string to put into coverage files.
char CoverageVersion[4];
@@ -119,6 +124,9 @@ public:
/// The ABI to use for passing floating point arguments.
std::string FloatABI;
+ /// The floating-point denormal mode to use.
+ std::string FPDenormalMode;
+
/// The float precision limit to use, if non-empty.
std::string LimitFloatPrecision;
@@ -172,6 +180,10 @@ public:
/// object file.
std::vector<std::string> CudaGpuBinaryFileNames;
+ /// The name of the file to which the backend should save YAML optimization
+ /// records.
+ std::string OptRecordFile;
+
/// Regular expression to select optimizations for which we should enable
/// optimization remarks. Transformation passes whose name matches this
/// expression (and support this feature), will emit a diagnostic
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 1228cf4d5fcd..3f754d999874 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -11,11 +11,12 @@
#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
#include "clang/AST/ASTConsumer.h"
-#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Frontend/Utils.h"
+#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/ModuleLoader.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
@@ -35,7 +36,6 @@ class TimerGroup;
namespace clang {
class ASTContext;
-class ASTConsumer;
class ASTReader;
class CodeCompleteConsumer;
class DiagnosticsEngine;
@@ -96,6 +96,9 @@ class CompilerInstance : public ModuleLoader {
/// The AST context.
IntrusiveRefCntPtr<ASTContext> Context;
+ /// An optional sema source that will be attached to sema.
+ IntrusiveRefCntPtr<ExternalSemaSource> ExternalSemaSrc;
+
/// The AST consumer.
std::unique_ptr<ASTConsumer> Consumer;
@@ -774,6 +777,8 @@ public:
void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
DependencyCollectors.push_back(std::move(Listener));
}
+
+ void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
};
} // end namespace clang
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index 0d5008e9a665..cb037c26546f 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -13,29 +13,29 @@
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Frontend/DependencyOutputOptions.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Frontend/LangStandard.h"
#include "clang/Frontend/MigratorOptions.h"
#include "clang/Frontend/PreprocessorOutputOptions.h"
-#include "clang/Lex/HeaderSearchOptions.h"
-#include "clang/Lex/PreprocessorOptions.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
#include <string>
-#include <vector>
namespace llvm {
+class Triple;
+
namespace opt {
class ArgList;
}
}
namespace clang {
+class PreprocessorOptions;
+class HeaderSearchOptions;
+class TargetOptions;
+class LangOptions;
class CompilerInvocation;
class DiagnosticsEngine;
@@ -48,7 +48,8 @@ class DiagnosticsEngine;
/// report the error(s).
bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args,
DiagnosticsEngine *Diags = nullptr,
- bool DefaultDiagColor = true);
+ bool DefaultDiagColor = true,
+ bool DefaultShowOpt = true);
class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> {
void operator=(const CompilerInvocationBase &) = delete;
diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h
index c372fdd0872f..2588feb2b87d 100644
--- a/include/clang/Frontend/DiagnosticRenderer.h
+++ b/include/clang/Frontend/DiagnosticRenderer.h
@@ -19,7 +19,6 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
namespace clang {
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index 0cbacbb4b122..a073ca5bfd2a 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -91,11 +91,12 @@ public:
};
class GenerateModuleAction : public ASTFrontendAction {
- clang::Module *Module;
- const FileEntry *ModuleMapForUniquing;
- bool IsSystem;
-
+ virtual std::unique_ptr<raw_pwrite_stream>
+ CreateOutputFile(CompilerInstance &CI, StringRef InFile) = 0;
+
protected:
+ bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
+
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override;
@@ -104,22 +105,31 @@ protected:
}
bool hasASTFileSupport() const override { return false; }
+};
+
+class GenerateModuleFromModuleMapAction : public GenerateModuleAction {
+ clang::Module *Module = nullptr;
+ const FileEntry *ModuleMapForUniquing = nullptr;
+ bool IsSystem = false;
+
+private:
+ bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
+
+ std::unique_ptr<raw_pwrite_stream>
+ CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
public:
- GenerateModuleAction(const FileEntry *ModuleMap = nullptr,
- bool IsSystem = false)
- : ASTFrontendAction(), ModuleMapForUniquing(ModuleMap), IsSystem(IsSystem)
- { }
+ GenerateModuleFromModuleMapAction() {}
+ GenerateModuleFromModuleMapAction(const FileEntry *ModuleMap, bool IsSystem)
+ : ModuleMapForUniquing(ModuleMap), IsSystem(IsSystem) {}
+};
+class GenerateModuleInterfaceAction : public GenerateModuleAction {
+private:
bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
- /// \brief Compute the AST consumer arguments that will be used to
- /// create the PCHGenerator instance returned by CreateASTConsumer.
- ///
- /// \returns true if an error occurred, false otherwise.
std::unique_ptr<raw_pwrite_stream>
- ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile,
- std::string &Sysroot, std::string &OutputFile);
+ CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
};
class SyntaxOnlyAction : public ASTFrontendAction {
@@ -138,6 +148,7 @@ class DumpModuleInfoAction : public ASTFrontendAction {
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override;
+ bool BeginInvocation(CompilerInstance &CI) override;
void ExecuteAction() override;
public:
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index a75523f25648..aad397526a03 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -40,7 +40,9 @@ namespace frontend {
EmitCodeGenOnly, ///< Generate machine code, but don't emit anything.
EmitObj, ///< Emit a .o file.
FixIt, ///< Parse and apply any fixits to the source.
- GenerateModule, ///< Generate pre-compiled module.
+ GenerateModule, ///< Generate pre-compiled module from a module map.
+ GenerateModuleInterface,///< Generate pre-compiled module from a C++ module
+ ///< interface file.
GeneratePCH, ///< Generate pre-compiled header.
GeneratePTH, ///< Generate pre-tokenized header.
InitOnly, ///< Only execute frontend initialization.
@@ -271,6 +273,9 @@ public:
// included by this file.
std::string FindPchSource;
+ /// Filename to write statistics to.
+ std::string StatsFile;
+
public:
FrontendOptions() :
DisableFree(false), RelocatablePCH(false), ShowHelp(false),
diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h
index ecab630c1228..9d7ee08d95d4 100644
--- a/include/clang/Frontend/FrontendPluginRegistry.h
+++ b/include/clang/Frontend/FrontendPluginRegistry.h
@@ -13,9 +13,6 @@
#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/LangStandards.def b/include/clang/Frontend/LangStandards.def
index a3036932f049..06fe1a3350ce 100644
--- a/include/clang/Frontend/LangStandards.def
+++ b/include/clang/Frontend/LangStandards.def
@@ -81,7 +81,7 @@ LANGSTANDARD(iso9899_2011,
"iso9899:2011", "ISO C 2011",
LineComment | C99 | C11 | Digraphs | HexFloat)
LANGSTANDARD(iso9899_201x,
- "iso9899:2011", "ISO C 2011",
+ "iso9899:201x", "ISO C 2011",
LineComment | C99 | C11 | Digraphs | HexFloat)
LANGSTANDARD(gnu11, "gnu11",
diff --git a/include/clang/Frontend/PCHContainerOperations.h b/include/clang/Frontend/PCHContainerOperations.h
index 0c1b28e9a51f..d323fb3e8b94 100644
--- a/include/clang/Frontend/PCHContainerOperations.h
+++ b/include/clang/Frontend/PCHContainerOperations.h
@@ -17,7 +17,6 @@
namespace llvm {
class raw_pwrite_stream;
-class BitstreamReader;
}
using llvm::StringRef;
@@ -63,10 +62,8 @@ public:
/// Equivalent to the format passed to -fmodule-format=
virtual StringRef getFormat() const = 0;
- /// Initialize an llvm::BitstreamReader with the serialized AST inside
- /// the PCH container Buffer.
- virtual void ExtractPCH(llvm::MemoryBufferRef Buffer,
- llvm::BitstreamReader &StreamFile) const = 0;
+ /// Returns the serialized AST inside the PCH container Buffer.
+ virtual StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const = 0;
};
/// Implements write operations for a raw pass-through PCH container.
@@ -87,9 +84,8 @@ class RawPCHContainerWriter : public PCHContainerWriter {
class RawPCHContainerReader : public PCHContainerReader {
StringRef getFormat() const override { return "raw"; }
- /// Initialize an llvm::BitstreamReader with Buffer.
- void ExtractPCH(llvm::MemoryBufferRef Buffer,
- llvm::BitstreamReader &StreamFile) const override;
+ /// Simply returns the buffer contained in Buffer.
+ StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
};
/// A registry of PCHContainerWriter and -Reader objects for different formats.
diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h
index f86c49039ed2..3261b6653809 100644
--- a/include/clang/Frontend/PreprocessorOutputOptions.h
+++ b/include/clang/Frontend/PreprocessorOutputOptions.h
@@ -22,6 +22,7 @@ public:
unsigned UseLineDirectives : 1; ///< Use \#line instead of GCC-style \# N.
unsigned ShowMacroComments : 1; ///< Show comments, even in macros.
unsigned ShowMacros : 1; ///< Print macro definitions.
+ unsigned ShowIncludeDirectives : 1; ///< Print includes, imports etc. within preprocessed output.
unsigned RewriteIncludes : 1; ///< Preprocess include directives only.
public:
@@ -32,6 +33,7 @@ public:
UseLineDirectives = 0;
ShowMacroComments = 0;
ShowMacros = 0;
+ ShowIncludeDirectives = 0;
RewriteIncludes = 0;
}
};
diff --git a/include/clang/Frontend/SerializedDiagnosticReader.h b/include/clang/Frontend/SerializedDiagnosticReader.h
index 3db362bf3470..07479844d465 100644
--- a/include/clang/Frontend/SerializedDiagnosticReader.h
+++ b/include/clang/Frontend/SerializedDiagnosticReader.h
@@ -11,7 +11,6 @@
#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"
diff --git a/include/clang/Frontend/TextDiagnostic.h b/include/clang/Frontend/TextDiagnostic.h
index d41f15a1ff72..9b108c28bd1c 100644
--- a/include/clang/Frontend/TextDiagnostic.h
+++ b/include/clang/Frontend/TextDiagnostic.h
@@ -107,6 +107,8 @@ protected:
const SourceManager &SM) override;
private:
+ void emitFilename(StringRef Filename, const SourceManager &SM);
+
void emitSnippetAndCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index cf943a5960bd..60419ff9b41d 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -128,11 +128,11 @@ class ModuleDependencyCollector : public DependencyCollector {
llvm::StringMap<std::string> SymLinkMap;
bool getRealPath(StringRef SrcPath, SmallVectorImpl<char> &Result);
- std::error_code copyToRoot(StringRef Src);
+ std::error_code copyToRoot(StringRef Src, StringRef Dst = "");
public:
StringRef getDest() { return DestDir; }
bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; }
- void addFile(StringRef Filename);
+ void addFile(StringRef Filename, StringRef FileDst = "");
void addFileMapping(StringRef VPath, StringRef RPath) {
VFSWriter.addFileMapping(VPath, RPath);
}
diff --git a/include/clang/Index/CommentToXML.h b/include/clang/Index/CommentToXML.h
index bb7b71ad411b..04f9501288ba 100644
--- a/include/clang/Index/CommentToXML.h
+++ b/include/clang/Index/CommentToXML.h
@@ -22,12 +22,7 @@ class HTMLTagComment;
}
namespace index {
-class SimpleFormatContext;
-
class CommentToXMLConverter {
- std::unique_ptr<SimpleFormatContext> FormatContext;
- unsigned FormatInMemoryUniqueId;
-
public:
CommentToXMLConverter();
~CommentToXMLConverter();
diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h
index b0bc93e464b4..cac0b53a939e 100644
--- a/include/clang/Index/IndexSymbol.h
+++ b/include/clang/Index/IndexSymbol.h
@@ -59,16 +59,18 @@ enum class SymbolLanguage {
CXX,
};
-enum class SymbolSubKind : uint8_t {
+/// Set of properties that provide additional info about a symbol.
+enum class SymbolProperty : uint8_t {
Generic = 1 << 0,
TemplatePartialSpecialization = 1 << 1,
TemplateSpecialization = 1 << 2,
UnitTest = 1 << 3,
IBAnnotated = 1 << 4,
IBOutletCollection = 1 << 5,
+ GKInspectable = 1 << 6,
};
-static const unsigned SymbolSubKindBitNum = 6;
-typedef unsigned SymbolSubKindSet;
+static const unsigned SymbolPropertyBitNum = 7;
+typedef unsigned SymbolPropertySet;
/// Set of roles that are attributed to symbol occurrences.
enum class SymbolRole : uint16_t {
@@ -88,8 +90,10 @@ enum class SymbolRole : uint16_t {
RelationOverrideOf = 1 << 11,
RelationReceivedBy = 1 << 12,
RelationCalledBy = 1 << 13,
+ RelationExtendedBy = 1 << 14,
+ RelationAccessorOf = 1 << 15,
};
-static const unsigned SymbolRoleBitNum = 14;
+static const unsigned SymbolRoleBitNum = 16;
typedef unsigned SymbolRoleSet;
/// Represents a relation to another symbol for a symbol occurrence.
@@ -103,7 +107,7 @@ struct SymbolRelation {
struct SymbolInfo {
SymbolKind Kind;
- SymbolSubKindSet SubKinds;
+ SymbolPropertySet Properties;
SymbolLanguage Lang;
};
@@ -119,9 +123,9 @@ bool printSymbolName(const Decl *D, const LangOptions &LO, raw_ostream &OS);
StringRef getSymbolKindString(SymbolKind K);
StringRef getSymbolLanguageString(SymbolLanguage K);
-void applyForEachSymbolSubKind(SymbolSubKindSet SubKinds,
- llvm::function_ref<void(SymbolSubKind)> Fn);
-void printSymbolSubKinds(SymbolSubKindSet SubKinds, raw_ostream &OS);
+void applyForEachSymbolProperty(SymbolPropertySet Props,
+ llvm::function_ref<void(SymbolProperty)> Fn);
+void printSymbolProperties(SymbolPropertySet Props, raw_ostream &OS);
} // namespace index
} // namespace clang
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
index ee0af292e6fc..dcd58f434fa2 100644
--- a/include/clang/Lex/DirectoryLookup.h
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -88,7 +88,7 @@ public:
/// getName - Return the directory or filename corresponding to this lookup
/// object.
- const char *getName() const;
+ StringRef getName() const;
/// getDir - Return the directory that this entry refers to.
///
diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h
index 8466f1a24d52..58bf79579a6a 100644
--- a/include/clang/Lex/HeaderMap.h
+++ b/include/clang/Lex/HeaderMap.h
@@ -45,7 +45,7 @@ public:
SmallVectorImpl<char> &DestPath) const;
/// Return the filename of the headermap.
- const char *getFileName() const;
+ StringRef getFileName() const;
/// Print the contents of this headermap to stderr.
void dump() const;
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 7bac01ef3a4c..b145d7bae15a 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -464,6 +464,9 @@ public:
/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
const HeaderMap *CreateHeaderMap(const FileEntry *FE);
+ /// \brief Get filenames for all registered header maps.
+ void getHeaderMapFileNames(SmallVectorImpl<std::string> &Names) const;
+
/// \brief Retrieve the name of the module file that should be used to
/// load the given module.
///
@@ -481,9 +484,12 @@ public:
/// \param ModuleMapPath A path that when combined with \c ModuleName
/// uniquely identifies this module. See Module::ModuleMap.
///
+ /// \param UsePrebuiltPath Whether we should use the prebuilt module path.
+ ///
/// \returns The name of the module file that corresponds to this module,
/// or an empty string if this module does not correspond to any module file.
- std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath);
+ std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath,
+ bool UsePrebuiltPath);
/// \brief Lookup a module Search for a module with the given name.
///
@@ -520,8 +526,10 @@ public:
/// \brief Retrieve the module that corresponds to the given file, if any.
///
/// \param File The header that we wish to map to a module.
- ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File) const;
-
+ /// \param AllowTextual Whether we want to find textual headers too.
+ ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File,
+ bool AllowTextual = false) const;
+
/// \brief Read the contents of the given module map file.
///
/// \param File The module map file.
@@ -539,6 +547,19 @@ public:
void loadTopLevelSystemModules();
private:
+
+ /// \brief Lookup a module with the given module name and search-name.
+ ///
+ /// \param ModuleName The name of the module we're looking for.
+ ///
+ /// \param SearchName The "search-name" to derive filesystem paths from
+ /// when looking for the module map; this is usually equal to ModuleName,
+ /// but for compatibility with some buggy frameworks, additional attempts
+ /// may be made to find the module under a related-but-different search-name.
+ ///
+ /// \returns The module named ModuleName.
+ Module *lookupModule(StringRef ModuleName, StringRef SearchName);
+
/// \brief Retrieve a module with the given name, which may be part of the
/// given framework.
///
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index 915dbf74b2a4..815b68c60e80 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -11,6 +11,7 @@
#define LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringRef.h"
@@ -93,6 +94,9 @@ public:
/// \brief The directory used for a user build.
std::string ModuleUserBuildPath;
+ /// \brief The directories used to load prebuilt module files.
+ std::vector<std::string> PrebuiltModulePaths;
+
/// The module/pch container format.
std::string ModuleFormat;
@@ -141,7 +145,7 @@ public:
/// \brief The set of macro names that should be ignored for the purposes
/// of computing the module hash.
- llvm::SmallSetVector<std::string, 16> ModulesIgnoreMacros;
+ llvm::SmallSetVector<llvm::CachedHashString, 16> ModulesIgnoreMacros;
/// \brief The set of user-provided virtual filesystem overlay files.
std::vector<std::string> VFSOverlayFiles;
@@ -172,6 +176,8 @@ public:
/// Whether the module includes debug information (-gmodules).
unsigned UseDebugInfo : 1;
+ unsigned ModulesValidateDiagnosticOptions : 1;
+
HeaderSearchOptions(StringRef _Sysroot = "/")
: Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(0),
ImplicitModuleMaps(0), ModuleMapFileHomeIsCwd(0),
@@ -181,7 +187,7 @@ public:
UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
ModulesValidateOncePerBuildSession(false),
ModulesValidateSystemHeaders(false),
- UseDebugInfo(false) {}
+ UseDebugInfo(false), ModulesValidateDiagnosticOptions(true) {}
/// AddPath - Add the \p Path path to the specified \p Group list.
void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
@@ -199,6 +205,10 @@ public:
void AddVFSOverlayFile(StringRef Name) {
VFSOverlayFiles.push_back(Name);
}
+
+ void AddPrebuiltModulePath(StringRef Name) {
+ PrebuiltModulePaths.push_back(Name);
+ }
};
} // end namespace clang
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index 5f946fc8337e..b66581b428b1 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -259,6 +259,8 @@ public:
return UDSuffixOffset;
}
+ static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix);
+
private:
void init(ArrayRef<Token> StringToks);
bool CopyStringFragment(const Token &Tok, const char *TokBegin,
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
index ae79650d1fd0..70770d17e9ff 100644
--- a/include/clang/Lex/ModuleLoader.h
+++ b/include/clang/Lex/ModuleLoader.h
@@ -31,13 +31,22 @@ typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation> > ModuleIdPath;
/// \brief Describes the result of attempting to load a module.
class ModuleLoadResult {
- llvm::PointerIntPair<Module *, 1, bool> Storage;
-
public:
- ModuleLoadResult() : Storage() { }
+ enum LoadResultKind {
+ // We either succeeded or failed to load the named module.
+ Normal,
+ // The module exists, but does not actually contain the named submodule.
+ // This should only happen if the named submodule was inferred from an
+ // umbrella directory, but not actually part of the umbrella header.
+ MissingExpected,
+ // The module exists but cannot be imported due to a configuration mismatch.
+ ConfigMismatch
+ };
+ llvm::PointerIntPair<Module *, 2, LoadResultKind> Storage;
- ModuleLoadResult(Module *module, bool missingExpected)
- : Storage(module, missingExpected) { }
+ ModuleLoadResult() : Storage() { }
+ ModuleLoadResult(Module *M) : Storage(M, Normal) {}
+ ModuleLoadResult(LoadResultKind Kind) : Storage(nullptr, Kind) {}
operator Module *() const { return Storage.getPointer(); }
@@ -45,7 +54,11 @@ public:
/// actually a submodule that we expected to see (based on implying the
/// submodule from header structure), but didn't materialize in the actual
/// module.
- bool isMissingExpected() const { return Storage.getInt(); }
+ bool isMissingExpected() const { return Storage.getInt() == MissingExpected; }
+
+ /// \brief Determines whether the module failed to load due to a configuration
+ /// mismatch with an explicitly-named .pcm file from the command line.
+ bool isConfigMismatch() const { return Storage.getInt() == ConfigMismatch; }
};
/// \brief Abstract interface for a module loader.
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 1e86f736983f..b3a2421af86e 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -12,22 +12,28 @@
//
//===----------------------------------------------------------------------===//
-
#ifndef LLVM_CLANG_LEX_MODULEMAP_H
#define LLVM_CLANG_LEX_MODULEMAP_H
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include <algorithm>
+#include <memory>
#include <string>
+#include <utility>
namespace clang {
-
+
class DirectoryEntry;
class FileEntry;
class FileManager;
@@ -40,7 +46,7 @@ class ModuleMapParser;
/// reads module map files.
class ModuleMapCallbacks {
public:
- virtual ~ModuleMapCallbacks() {}
+ virtual ~ModuleMapCallbacks() = default;
/// \brief Called when a module map file has been read.
///
@@ -153,7 +159,7 @@ public:
typedef llvm::SmallPtrSet<const FileEntry *, 1> AdditionalModMapsSet;
private:
- typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1> >
+ typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1>>
HeadersMap;
/// \brief Mapping from each header to the module that owns the contents of
@@ -170,7 +176,8 @@ private:
/// \brief The set of attributes that can be attached to a module.
struct Attributes {
- Attributes() : IsSystem(), IsExternC(), IsExhaustive() {}
+ Attributes()
+ : IsSystem(), IsExternC(), IsExhaustive(), NoUndeclaredIncludes() {}
/// \brief Whether this is a system module.
unsigned IsSystem : 1;
@@ -180,6 +187,10 @@ private:
/// \brief Whether this is an exhaustive set of configuration macros.
unsigned IsExhaustive : 1;
+
+ /// \brief Whether files in this module can only include non-modular headers
+ /// and headers from used modules.
+ unsigned NoUndeclaredIncludes : 1;
};
/// \brief A directory for which framework modules can be inferred.
@@ -314,10 +325,15 @@ public:
///
/// \param File The header file that is likely to be included.
///
+ /// \param AllowTextual If \c true and \p File is a textual header, return
+ /// its owning module. Otherwise, no KnownHeader will be returned if the
+ /// file is only known as a textual header.
+ ///
/// \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);
+ KnownHeader findModuleForHeader(const FileEntry *File,
+ bool AllowTextual = false);
/// \brief Retrieve all the modules that contain the given header file. This
/// may not include umbrella modules, nor information from external sources,
@@ -402,6 +418,15 @@ public:
bool IsFramework,
bool IsExplicit);
+ /// \brief Create a new module for a C++ Modules TS module interface unit.
+ /// The module must not already exist, and will be configured for the current
+ /// compilation.
+ ///
+ /// Note that this also sets the current module to the newly-created module.
+ ///
+ /// \returns The newly-created module.
+ Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name);
+
/// \brief Infer the contents of a framework module map from the given
/// framework directory.
Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir,
@@ -529,5 +554,6 @@ public:
module_iterator module_end() const { return Modules.end(); }
};
-}
-#endif
+} // end namespace clang
+
+#endif // LLVM_CLANG_LEX_MODULEMAP_H
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 68b8f1cc7348..2d027f314b5f 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -17,14 +17,12 @@
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Lex/DirectoryLookup.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Lex/ModuleLoader.h"
#include "clang/Lex/Pragma.h"
#include "llvm/ADT/StringRef.h"
-#include <string>
namespace clang {
- class SourceLocation;
class Token;
class IdentifierInfo;
class MacroDefinition;
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index 26178eddf36d..f4e4774429f9 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -14,15 +14,11 @@
#ifndef LLVM_CLANG_LEX_PTHMANAGER_H
#define LLVM_CLANG_LEX_PTHMANAGER_H
-#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Lex/PTHLexer.h"
-#include "llvm/ADT/DenseMap.h"
+#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/OnDiskHashTable.h"
-#include <string>
namespace llvm {
class MemoryBuffer;
@@ -31,6 +27,7 @@ namespace llvm {
namespace clang {
class FileEntry;
+class Preprocessor;
class PTHLexer;
class DiagnosticsEngine;
class FileSystemStatCache;
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 87b8ce1af0de..826ba33fbb72 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -19,7 +19,6 @@
#include "clang/Lex/PPCallbacks.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
@@ -33,11 +32,11 @@ namespace clang {
/// \brief Allocates memory within a Clang preprocessing record.
void *operator new(size_t bytes, clang::PreprocessingRecord &PR,
- unsigned alignment = 8) LLVM_NOEXCEPT;
+ unsigned alignment = 8) noexcept;
/// \brief Frees memory allocated in a Clang preprocessing record.
void operator delete(void *ptr, clang::PreprocessingRecord &PR,
- unsigned) LLVM_NOEXCEPT;
+ unsigned) noexcept;
namespace clang {
class MacroDefinitionRecord;
@@ -99,24 +98,24 @@ namespace clang {
// Only allow allocation of preprocessed entities using the allocator
// in PreprocessingRecord or by doing a placement new.
void *operator new(size_t bytes, PreprocessingRecord &PR,
- unsigned alignment = 8) LLVM_NOEXCEPT {
+ unsigned alignment = 8) noexcept {
return ::operator new(bytes, PR, alignment);
}
- void *operator new(size_t bytes, void *mem) LLVM_NOEXCEPT { return mem; }
+ void *operator new(size_t bytes, void *mem) noexcept { return mem; }
void operator delete(void *ptr, PreprocessingRecord &PR,
- unsigned alignment) LLVM_NOEXCEPT {
+ unsigned alignment) noexcept {
return ::operator delete(ptr, PR, alignment);
}
- void operator delete(void *, std::size_t) LLVM_NOEXCEPT {}
- void operator delete(void *, void *) LLVM_NOEXCEPT {}
+ void operator delete(void *, std::size_t) noexcept {}
+ void operator delete(void *, void *) noexcept {}
private:
// Make vanilla 'new' and 'delete' illegal for preprocessed entities.
- void *operator new(size_t bytes) LLVM_NOEXCEPT;
- void operator delete(void *data) LLVM_NOEXCEPT;
+ void *operator new(size_t bytes) noexcept;
+ void operator delete(void *data) noexcept;
};
/// \brief Records the presence of a preprocessor directive.
@@ -524,12 +523,12 @@ namespace clang {
} // end namespace clang
inline void *operator new(size_t bytes, clang::PreprocessingRecord &PR,
- unsigned alignment) LLVM_NOEXCEPT {
+ unsigned alignment) noexcept {
return PR.Allocate(bytes, alignment);
}
inline void operator delete(void *ptr, clang::PreprocessingRecord &PR,
- unsigned) LLVM_NOEXCEPT {
+ unsigned) noexcept {
PR.Deallocate(ptr);
}
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 30cc37f6f884..bb71f49290b4 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -265,6 +265,10 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// \brief True if we hit the code-completion point.
bool CodeCompletionReached;
+ /// \brief The code completion token containing the information
+ /// on the stem that is to be code completed.
+ IdentifierInfo *CodeCompletionII;
+
/// \brief The directory that the main file should be considered to occupy,
/// if it does not correspond to a real file (as happens when building a
/// module).
@@ -346,14 +350,6 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
ThePPLexer(std::move(ThePPLexer)),
TheTokenLexer(std::move(TheTokenLexer)),
TheDirLookup(std::move(TheDirLookup)) {}
- IncludeStackInfo(IncludeStackInfo &&RHS)
- : CurLexerKind(std::move(RHS.CurLexerKind)),
- TheSubmodule(std::move(RHS.TheSubmodule)),
- TheLexer(std::move(RHS.TheLexer)),
- ThePTHLexer(std::move(RHS.ThePTHLexer)),
- ThePPLexer(std::move(RHS.ThePPLexer)),
- TheTokenLexer(std::move(RHS.TheTokenLexer)),
- TheDirLookup(std::move(RHS.TheDirLookup)) {}
};
std::vector<IncludeStackInfo> IncludeMacroStack;
@@ -394,6 +390,8 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
ModuleMacroInfo *getModuleInfo(Preprocessor &PP,
const IdentifierInfo *II) const {
+ if (II->isOutOfDate())
+ PP.updateOutOfDateIdentifier(const_cast<IdentifierInfo&>(*II));
// FIXME: Find a spare bit on IdentifierInfo and store a
// HasModuleMacros flag.
if (!II->hasMacroDefinition() ||
@@ -418,10 +416,10 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
public:
MacroState() : MacroState(nullptr) {}
MacroState(MacroDirective *MD) : State(MD) {}
- MacroState(MacroState &&O) LLVM_NOEXCEPT : State(O.State) {
+ MacroState(MacroState &&O) noexcept : State(O.State) {
O.State = (MacroDirective *)nullptr;
}
- MacroState &operator=(MacroState &&O) LLVM_NOEXCEPT {
+ MacroState &operator=(MacroState &&O) noexcept {
auto S = O.State;
O.State = (MacroDirective *)nullptr;
State = S;
@@ -649,6 +647,8 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
};
DeserializedMacroInfoChain *DeserialMIChainHead;
+ void updateOutOfDateIdentifier(IdentifierInfo &II) const;
+
public:
Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
DiagnosticsEngine &diags, LangOptions &opts,
@@ -887,7 +887,8 @@ public:
return appendDefMacroDirective(II, MI, MI->getDefinitionLoc());
}
/// \brief Set a MacroDirective that was loaded from a PCH file.
- void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
+ void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED,
+ MacroDirective *MD);
/// \brief Register an exported macro for a module and identifier.
ModuleMacro *addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro,
@@ -896,6 +897,8 @@ public:
/// \brief Get the list of leaf (non-overridden) module macros for a name.
ArrayRef<ModuleMacro*> getLeafModuleMacros(const IdentifierInfo *II) const {
+ if (II->isOutOfDate())
+ updateOutOfDateIdentifier(const_cast<IdentifierInfo&>(*II));
auto I = LeafModuleMacros.find(II);
if (I != LeafModuleMacros.end())
return I->second;
@@ -984,6 +987,18 @@ public:
/// completion point.
void CodeCompleteNaturalLanguage();
+ /// \brief Set the code completion token for filtering purposes.
+ void setCodeCompletionIdentifierInfo(IdentifierInfo *Filter) {
+ CodeCompletionII = Filter;
+ }
+
+ /// \brief Get the code completion token for filtering purposes.
+ StringRef getCodeCompletionFilter() {
+ if (CodeCompletionII)
+ return CodeCompletionII->getName();
+ return {};
+ }
+
/// \brief Retrieve the preprocessing record, or NULL if there is no
/// preprocessing record.
PreprocessingRecord *getPreprocessingRecord() const { return Record; }
@@ -1862,12 +1877,12 @@ private:
/// Handle*Directive - implement the various preprocessor directives. These
/// should side-effect the current preprocessor object so that the next call
/// to Lex() will return the appropriate token next.
- void HandleLineDirective(Token &Tok);
+ void HandleLineDirective();
void HandleDigitDirective(Token &Tok);
void HandleUserDiagnosticDirective(Token &Tok, bool isWarning);
void HandleIdentSCCSDirective(Token &Tok);
void HandleMacroPublicDirective(Token &Tok);
- void HandleMacroPrivateDirective(Token &Tok);
+ void HandleMacroPrivateDirective();
// File inclusion.
void HandleIncludeDirective(SourceLocation HashLoc,
@@ -1907,7 +1922,7 @@ public:
private:
// Macro handling.
void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
- void HandleUndefDirective(Token &Tok);
+ void HandleUndefDirective();
// Conditional Inclusion.
void HandleIfdefDirective(Token &Tok, bool isIfndef,
@@ -1923,7 +1938,7 @@ private:
public:
void HandlePragmaOnce(Token &OnceTok);
void HandlePragmaMark();
- void HandlePragmaPoison(Token &PoisonTok);
+ void HandlePragmaPoison();
void HandlePragmaSystemHeader(Token &SysHeaderTok);
void HandlePragmaDependency(Token &DependencyTok);
void HandlePragmaPushMacro(Token &Tok);
@@ -1956,6 +1971,4 @@ typedef llvm::Registry<PragmaHandler> PragmaHandlerRegistry;
} // end namespace clang
-extern template class llvm::Registry<clang::PragmaHandler>;
-
#endif
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
index 963d95d7f1d1..de652cccb83a 100644
--- a/include/clang/Lex/PreprocessorOptions.h
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -12,7 +12,6 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include <cassert>
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 5838a447c3b9..972f13daca46 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -74,7 +74,8 @@ class Parser : public CodeCompletionHandler {
// a statement).
SourceLocation PrevTokLocation;
- unsigned short ParenCount, BracketCount, BraceCount;
+ unsigned short ParenCount = 0, BracketCount = 0, BraceCount = 0;
+ unsigned short MisplacedModuleBeginCount = 0;
/// Actions - These are the callbacks we invoke as we parse various constructs
/// in the file.
@@ -143,6 +144,7 @@ class Parser : public CodeCompletionHandler {
/// C++0x contextual keywords.
mutable IdentifierInfo *Ident_final;
+ mutable IdentifierInfo *Ident_GNU_final;
mutable IdentifierInfo *Ident_override;
// C++ type trait keywords that can be reverted to identifiers and still be
@@ -171,6 +173,8 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> MSCodeSeg;
std::unique_ptr<PragmaHandler> MSSection;
std::unique_ptr<PragmaHandler> MSRuntimeChecks;
+ std::unique_ptr<PragmaHandler> MSIntrinsic;
+ std::unique_ptr<PragmaHandler> CUDAForceHostDeviceHandler;
std::unique_ptr<PragmaHandler> OptimizeHandler;
std::unique_ptr<PragmaHandler> LoopHintHandler;
std::unique_ptr<PragmaHandler> UnrollHintHandler;
@@ -244,6 +248,11 @@ class Parser : public CodeCompletionHandler {
bool SkipFunctionBodies;
+ /// The location of the expression statement that is being parsed right now.
+ /// Used to determine if an expression that is being parsed is a statement or
+ /// just a regular sub-expression.
+ SourceLocation ExprStatementTokLoc;
+
public:
Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
~Parser() override;
@@ -277,6 +286,9 @@ public:
///
void Initialize();
+ /// Parse the first top-level declaration in a translation unit.
+ bool ParseFirstTopLevelDecl(DeclGroupPtrTy &Result);
+
/// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
/// the EOF was encountered.
bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
@@ -314,6 +326,10 @@ public:
return true;
}
+ SourceLocation getEndOfPreviousToken() {
+ return PP.getLocForEndOfToken(PrevTokLocation);
+ }
+
/// Retrieve the underscored keyword (_Nonnull, _Nullable) that corresponds
/// to the given nullability kind.
IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability) {
@@ -868,8 +884,8 @@ public:
StopAtCodeCompletion = 1 << 2 ///< Stop at code completion
};
- friend LLVM_CONSTEXPR SkipUntilFlags operator|(SkipUntilFlags L,
- SkipUntilFlags R) {
+ friend constexpr SkipUntilFlags operator|(SkipUntilFlags L,
+ SkipUntilFlags R) {
return static_cast<SkipUntilFlags>(static_cast<unsigned>(L) |
static_cast<unsigned>(R));
}
@@ -1002,8 +1018,8 @@ private:
/// (C++ [class.mem]p2).
struct LateParsedDefaultArgument {
explicit LateParsedDefaultArgument(Decl *P,
- CachedTokens *Toks = nullptr)
- : Param(P), Toks(Toks) { }
+ std::unique_ptr<CachedTokens> Toks = nullptr)
+ : Param(P), Toks(std::move(Toks)) { }
/// Param - The parameter declaration for this parameter.
Decl *Param;
@@ -1012,7 +1028,7 @@ private:
/// argument expression, not including the '=' or the terminating
/// ')' or ','. This will be NULL for parameters that have no
/// default argument.
- CachedTokens *Toks;
+ std::unique_ptr<CachedTokens> Toks;
};
/// LateParsedMethodDeclaration - A method declaration inside a class that
@@ -1245,6 +1261,11 @@ private:
ParsedAttributesWithRange(AttributeFactory &factory)
: ParsedAttributes(factory) {}
+ void clear() {
+ ParsedAttributes::clear();
+ Range = SourceRange();
+ }
+
SourceRange Range;
};
@@ -1514,8 +1535,6 @@ private:
bool IsTypename = false,
IdentifierInfo **LastII = nullptr);
- void CheckForLParenAfterColonColon();
-
//===--------------------------------------------------------------------===//
// C++0x 5.1.2: Lambda expressions
@@ -2098,8 +2117,8 @@ private:
void DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
SourceLocation CorrectLocation);
- void handleDeclspecAlignBeforeClassKey(ParsedAttributesWithRange &Attrs,
- DeclSpec &DS, Sema::TagUseKind TUK);
+ void stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs,
+ DeclSpec &DS, Sema::TagUseKind TUK);
void ProhibitAttributes(ParsedAttributesWithRange &attrs) {
if (!attrs.Range.isValid()) return;
@@ -2111,7 +2130,8 @@ private:
// Forbid C++11 attributes that appear on certain syntactic
// locations which standard permits but we don't supported yet,
// for example, attributes appertain to decl specifiers.
- void ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs);
+ void ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs,
+ unsigned DiagID);
/// \brief Skip C++11 attributes and return the end location of the last one.
/// \returns SourceLocation() if there are no attributes.
@@ -2203,6 +2223,7 @@ private:
if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
ParseMicrosoftAttributes(attrs, endLoc);
}
+ void ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs);
void ParseMicrosoftAttributes(ParsedAttributes &attrs,
SourceLocation *endLoc = nullptr);
void MaybeParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
@@ -2352,6 +2373,7 @@ private:
bool AtomicAllowed = true,
bool IdentifierRequired = false);
void ParseDirectDeclarator(Declarator &D);
+ void ParseDecompositionDeclarator(Declarator &D);
void ParseParenDeclarator(Declarator &D);
void ParseFunctionDeclarator(Declarator &D,
ParsedAttributes &attrs,
@@ -2400,21 +2422,40 @@ private:
ParsedAttributes& attrs,
BalancedDelimiterTracker &Tracker);
Decl *ParseLinkage(ParsingDeclSpec &DS, unsigned Context);
- Decl *ParseUsingDirectiveOrDeclaration(unsigned Context,
- const ParsedTemplateInfo &TemplateInfo,
- SourceLocation &DeclEnd,
- ParsedAttributesWithRange &attrs,
- Decl **OwnedType = nullptr);
+ Decl *ParseExportDeclaration();
+ DeclGroupPtrTy ParseUsingDirectiveOrDeclaration(
+ unsigned Context, const ParsedTemplateInfo &TemplateInfo,
+ SourceLocation &DeclEnd, ParsedAttributesWithRange &attrs);
Decl *ParseUsingDirective(unsigned Context,
SourceLocation UsingLoc,
SourceLocation &DeclEnd,
ParsedAttributes &attrs);
- Decl *ParseUsingDeclaration(unsigned Context,
- const ParsedTemplateInfo &TemplateInfo,
- SourceLocation UsingLoc,
- SourceLocation &DeclEnd,
- AccessSpecifier AS = AS_none,
- Decl **OwnedType = nullptr);
+
+ struct UsingDeclarator {
+ SourceLocation TypenameLoc;
+ CXXScopeSpec SS;
+ SourceLocation TemplateKWLoc;
+ UnqualifiedId Name;
+ SourceLocation EllipsisLoc;
+
+ void clear() {
+ TypenameLoc = TemplateKWLoc = EllipsisLoc = SourceLocation();
+ SS.clear();
+ Name.clear();
+ }
+ };
+
+ bool ParseUsingDeclarator(unsigned Context, UsingDeclarator &D);
+ DeclGroupPtrTy ParseUsingDeclaration(unsigned Context,
+ const ParsedTemplateInfo &TemplateInfo,
+ SourceLocation UsingLoc,
+ SourceLocation &DeclEnd,
+ AccessSpecifier AS = AS_none);
+ Decl *ParseAliasDeclarationAfterDeclarator(
+ const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,
+ UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS,
+ ParsedAttributes &Attrs, Decl **OwnedType = nullptr);
+
Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc,
SourceLocation AliasLoc, IdentifierInfo *Alias,
@@ -2649,6 +2690,7 @@ private:
//===--------------------------------------------------------------------===//
// Modules
+ DeclGroupPtrTy ParseModuleDecl();
DeclGroupPtrTy ParseModuleImport(SourceLocation AtLoc);
bool parseMisplacedModuleImport();
bool tryParseMisplacedModuleImport() {
@@ -2659,6 +2701,11 @@ private:
return false;
}
+ bool ParseModuleName(
+ SourceLocation UseLoc,
+ SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path,
+ bool IsImport);
+
//===--------------------------------------------------------------------===//
// C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
ExprResult ParseTypeTrait();
diff --git a/include/clang/Rewrite/Core/HTMLRewrite.h b/include/clang/Rewrite/Core/HTMLRewrite.h
index dafdf51ce63b..1fd7c7a3f84e 100644
--- a/include/clang/Rewrite/Core/HTMLRewrite.h
+++ b/include/clang/Rewrite/Core/HTMLRewrite.h
@@ -62,8 +62,8 @@ namespace html {
void AddLineNumbers(Rewriter& R, FileID FID);
- void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID,
- const char *title = nullptr);
+ void AddHeaderFooterInternalBuiltinCSS(Rewriter &R, FileID FID,
+ StringRef title);
/// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
/// information about keywords, comments, etc.
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index fcddbecc029c..e74bf6a7cc86 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -101,12 +101,14 @@ public:
AS_CXX11,
/// __declspec(...)
AS_Declspec,
+ /// [uuid("...")] class Foo
+ AS_Microsoft,
/// __ptr16, alignas(...), etc.
AS_Keyword,
/// Context-sensitive version of a keyword attribute.
AS_ContextSensitiveKeyword,
/// #pragma ...
- AS_Pragma
+ AS_Pragma,
};
private:
@@ -369,6 +371,7 @@ public:
}
bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
+ bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
bool isCXX11Attribute() const {
return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
}
@@ -745,6 +748,19 @@ public:
list = newList;
}
+ void addAllAtEnd(AttributeList *newList) {
+ if (!list) {
+ list = newList;
+ return;
+ }
+
+ AttributeList *lastInList = list;
+ while (AttributeList *next = lastInList->getNext())
+ lastInList = next;
+
+ lastInList->setNext(newList);
+ }
+
void set(AttributeList *newList) {
list = newList;
}
@@ -869,12 +885,14 @@ enum AttributeDeclKind {
ExpectedFunction,
ExpectedUnion,
ExpectedVariableOrFunction,
+ ExpectedFunctionOrGlobalVar,
ExpectedFunctionVariableOrObjCInterface,
ExpectedFunctionOrMethod,
ExpectedParameter,
ExpectedFunctionMethodOrBlock,
ExpectedFunctionMethodOrClass,
ExpectedFunctionMethodOrParameter,
+ ExpectedFunctionMethodOrGlobalVar,
ExpectedClass,
ExpectedEnum,
ExpectedVariable,
@@ -897,6 +915,7 @@ enum AttributeDeclKind {
ExpectedFunctionVariableOrClass,
ExpectedFunctionVariableClassOrObjCInterface,
ExpectedObjectiveCProtocol,
+ ExpectedStaticOrTLSVar,
ExpectedFunctionGlobalVarMethodOrProperty,
ExpectedStructOrUnionOrTypedef,
ExpectedStructOrTypedef,
@@ -906,7 +925,8 @@ enum AttributeDeclKind {
ExpectedVariableEnumFieldOrTypedef,
ExpectedFunctionMethodEnumOrClass,
ExpectedStructClassVariableFunctionOrInlineNamespace,
- ExpectedForMaybeUnused
+ ExpectedForMaybeUnused,
+ ExpectedEnumOrClass,
};
} // end namespace clang
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 014ea5d61dfd..b80924ea11fc 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -90,7 +90,11 @@ enum {
CCD_ProbablyNotObjCCollection = 15,
/// \brief An Objective-C method being used as a property.
- CCD_MethodAsProperty = 2
+ CCD_MethodAsProperty = 2,
+
+ /// \brief An Objective-C block property completed as a setter with a
+ /// block placeholder.
+ CCD_BlockPropertySetter = 3
};
/// \brief Priority value factors by which we will divide or multiply the
@@ -737,7 +741,7 @@ public:
/// \brief Build a result that refers to a pattern with an associated
/// declaration.
- CodeCompletionResult(CodeCompletionString *Pattern, NamedDecl *D,
+ CodeCompletionResult(CodeCompletionString *Pattern, const NamedDecl *D,
unsigned Priority)
: Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0),
Kind(RK_Pattern), Availability(CXAvailability_Available), Hidden(false),
@@ -913,6 +917,13 @@ public:
/// \brief Deregisters and destroys this code-completion consumer.
virtual ~CodeCompleteConsumer();
+ /// \name Code-completion filtering
+ /// \brief Check if the result should be filtered out.
+ virtual bool isResultFilteredOut(StringRef Filter,
+ CodeCompletionResult Results) {
+ return false;
+ }
+
/// \name Code-completion callbacks
//@{
/// \brief Process the finalized code-completion results.
@@ -966,6 +977,8 @@ public:
OverloadCandidate *Candidates,
unsigned NumCandidates) override;
+ bool isResultFilteredOut(StringRef Filter, CodeCompletionResult Results) override;
+
CodeCompletionAllocator &getAllocator() override {
return CCTUInfo.getAllocator();
}
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index afcd791bca29..331fd0db6724 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -380,7 +380,8 @@ private:
SourceRange Range;
SourceLocation StorageClassSpecLoc, ThreadStorageClassSpecLoc;
- SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
+ SourceRange TSWRange;
+ SourceLocation TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
/// TSTNameLoc - If TypeSpecType is any of class, enum, struct, union,
/// typename, then this is the location of the named type (if present);
/// otherwise, it is the same as TSTLoc. Hence, the pair TSTLoc and
@@ -503,7 +504,8 @@ public:
SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; }
+ SourceLocation getTypeSpecWidthLoc() const { return TSWRange.getBegin(); }
+ SourceRange getTypeSpecWidthRange() const { return TSWRange; }
SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; }
@@ -1186,14 +1188,14 @@ struct DeclaratorChunk {
/// declaration of a member function), it will be stored here as a
/// sequence of tokens to be parsed once the class definition is
/// complete. Non-NULL indicates that there is a default argument.
- CachedTokens *DefaultArgTokens;
+ std::unique_ptr<CachedTokens> DefaultArgTokens;
- ParamInfo() {}
+ ParamInfo() = default;
ParamInfo(IdentifierInfo *ident, SourceLocation iloc,
Decl *param,
- CachedTokens *DefArgTokens = nullptr)
+ std::unique_ptr<CachedTokens> DefArgTokens = nullptr)
: Ident(ident), IdentLoc(iloc), Param(param),
- DefaultArgTokens(DefArgTokens) {}
+ DefaultArgTokens(std::move(DefArgTokens)) {}
};
struct TypeAndRange {
@@ -1246,9 +1248,10 @@ struct DeclaratorChunk {
/// declarator.
unsigned NumParams;
- /// NumExceptions - This is the number of types in the dynamic-exception-
- /// decl, if the function has one.
- unsigned NumExceptions;
+ /// NumExceptionsOrDecls - This is the number of types in the
+ /// dynamic-exception-decl, if the function has one. In C, this is the
+ /// number of declarations in the function prototype.
+ unsigned NumExceptionsOrDecls;
/// \brief The location of the ref-qualifier, if any.
///
@@ -1298,6 +1301,11 @@ struct DeclaratorChunk {
/// \brief Pointer to the cached tokens for an exception-specification
/// that has not yet been parsed.
CachedTokens *ExceptionSpecTokens;
+
+ /// Pointer to a new[]'d array of declarations that need to be available
+ /// for lookup inside the function body, if one exists. Does not exist in
+ /// C++.
+ NamedDecl **DeclsInPrototype;
};
/// \brief If HasTrailingReturnType is true, this is the trailing return
@@ -1308,10 +1316,8 @@ struct DeclaratorChunk {
///
/// This is used in various places for error recovery.
void freeParams() {
- for (unsigned I = 0; I < NumParams; ++I) {
- delete Params[I].DefaultArgTokens;
- Params[I].DefaultArgTokens = nullptr;
- }
+ for (unsigned I = 0; I < NumParams; ++I)
+ Params[I].DefaultArgTokens.reset();
if (DeleteParams) {
delete[] Params;
DeleteParams = false;
@@ -1322,10 +1328,20 @@ struct DeclaratorChunk {
void destroy() {
if (DeleteParams)
delete[] Params;
- if (getExceptionSpecType() == EST_Dynamic)
+ switch (getExceptionSpecType()) {
+ default:
+ break;
+ case EST_Dynamic:
delete[] Exceptions;
- else if (getExceptionSpecType() == EST_Unparsed)
+ break;
+ case EST_Unparsed:
delete ExceptionSpecTokens;
+ break;
+ case EST_None:
+ if (NumExceptionsOrDecls != 0)
+ delete[] DeclsInPrototype;
+ break;
+ }
}
/// isKNRPrototype - Return true if this is a K&R style identifier list,
@@ -1395,6 +1411,19 @@ struct DeclaratorChunk {
return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
}
+ /// \brief Get the number of dynamic exception specifications.
+ unsigned getNumExceptions() const {
+ assert(ExceptionSpecType != EST_None);
+ return NumExceptionsOrDecls;
+ }
+
+ /// \brief Get the non-parameter decls defined within this function
+ /// prototype. Typically these are tag declarations.
+ ArrayRef<NamedDecl *> getDeclsInPrototype() const {
+ assert(ExceptionSpecType == EST_None);
+ return llvm::makeArrayRef(DeclsInPrototype, NumExceptionsOrDecls);
+ }
+
/// \brief Determine whether this function declarator had a
/// trailing-return-type.
bool hasTrailingReturnType() const { return HasTrailingReturnType; }
@@ -1417,15 +1446,12 @@ struct DeclaratorChunk {
unsigned TypeQuals : 5;
// CXXScopeSpec has a constructor, so it can't be a direct member.
// So we need some pointer-aligned storage and a bit of trickery.
- union {
- void *Aligner;
- char Mem[sizeof(CXXScopeSpec)];
- } ScopeMem;
+ alignas(CXXScopeSpec) char ScopeMem[sizeof(CXXScopeSpec)];
CXXScopeSpec &Scope() {
- return *reinterpret_cast<CXXScopeSpec*>(ScopeMem.Mem);
+ return *reinterpret_cast<CXXScopeSpec *>(ScopeMem);
}
const CXXScopeSpec &Scope() const {
- return *reinterpret_cast<const CXXScopeSpec*>(ScopeMem.Mem);
+ return *reinterpret_cast<const CXXScopeSpec *>(ScopeMem);
}
void destroy() {
Scope().~CXXScopeSpec();
@@ -1543,6 +1569,7 @@ struct DeclaratorChunk {
unsigned NumExceptions,
Expr *NoexceptExpr,
CachedTokens *ExceptionSpecTokens,
+ ArrayRef<NamedDecl *> DeclsInPrototype,
SourceLocation LocalRangeBegin,
SourceLocation LocalRangeEnd,
Declarator &TheDeclarator,
@@ -1580,7 +1607,7 @@ struct DeclaratorChunk {
I.EndLoc = Loc;
I.Mem.TypeQuals = TypeQuals;
I.Mem.AttrList = nullptr;
- new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
+ new (I.Mem.ScopeMem) CXXScopeSpec(SS);
return I;
}
@@ -1600,6 +1627,58 @@ struct DeclaratorChunk {
}
};
+/// A parsed C++17 decomposition declarator of the form
+/// '[' identifier-list ']'
+class DecompositionDeclarator {
+public:
+ struct Binding {
+ IdentifierInfo *Name;
+ SourceLocation NameLoc;
+ };
+
+private:
+ /// The locations of the '[' and ']' tokens.
+ SourceLocation LSquareLoc, RSquareLoc;
+
+ /// The bindings.
+ Binding *Bindings;
+ unsigned NumBindings : 31;
+ unsigned DeleteBindings : 1;
+
+ friend class Declarator;
+
+public:
+ DecompositionDeclarator()
+ : Bindings(nullptr), NumBindings(0), DeleteBindings(false) {}
+ DecompositionDeclarator(const DecompositionDeclarator &G) = delete;
+ DecompositionDeclarator &operator=(const DecompositionDeclarator &G) = delete;
+ ~DecompositionDeclarator() {
+ if (DeleteBindings)
+ delete[] Bindings;
+ }
+
+ void clear() {
+ LSquareLoc = RSquareLoc = SourceLocation();
+ if (DeleteBindings)
+ delete[] Bindings;
+ Bindings = nullptr;
+ NumBindings = 0;
+ DeleteBindings = false;
+ }
+
+ ArrayRef<Binding> bindings() const {
+ return llvm::makeArrayRef(Bindings, NumBindings);
+ }
+
+ bool isSet() const { return LSquareLoc.isValid(); }
+
+ SourceLocation getLSquareLoc() const { return LSquareLoc; }
+ SourceLocation getRSquareLoc() const { return RSquareLoc; }
+ SourceRange getSourceRange() const {
+ return SourceRange(LSquareLoc, RSquareLoc);
+ }
+};
+
/// \brief Described the kind of function definition (if any) provided for
/// a function.
enum FunctionDefinitionKind {
@@ -1658,6 +1737,9 @@ private:
/// \brief Where we are parsing this declarator.
TheContext Context;
+ /// The C++17 structured binding, if any. This is an alternative to a Name.
+ DecompositionDeclarator BindingGroup;
+
/// DeclTypeInfo - This holds each type that the declarator includes as it is
/// parsed. This is pushed from the identifier out, which means that element
/// #0 will be the most closely bound to the identifier, and
@@ -1679,18 +1761,6 @@ private:
/// \brief Is this Declarator a redeclaration?
unsigned Redeclaration : 1;
- /// Attrs - Attributes.
- ParsedAttributes Attrs;
-
- /// \brief The asm label, if specified.
- Expr *AsmLabel;
-
- /// InlineParams - This is a local array used for the first function decl
- /// chunk to avoid going to the heap for the common case when we have one
- /// function chunk in the declarator.
- DeclaratorChunk::ParamInfo InlineParams[16];
- bool InlineParamsUsed;
-
/// \brief true if the declaration is preceded by \c __extension__.
unsigned Extension : 1;
@@ -1700,6 +1770,27 @@ private:
/// Indicates whether this is an Objective-C 'weak' property.
unsigned ObjCWeakProperty : 1;
+ /// Indicates whether the InlineParams / InlineBindings storage has been used.
+ unsigned InlineStorageUsed : 1;
+
+ /// Attrs - Attributes.
+ ParsedAttributes Attrs;
+
+ /// \brief The asm label, if specified.
+ Expr *AsmLabel;
+
+#ifndef _MSC_VER
+ union {
+#endif
+ /// InlineParams - This is a local array used for the first function decl
+ /// chunk to avoid going to the heap for the common case when we have one
+ /// function chunk in the declarator.
+ DeclaratorChunk::ParamInfo InlineParams[16];
+ DecompositionDeclarator::Binding InlineBindings[16];
+#ifndef _MSC_VER
+ };
+#endif
+
/// \brief If this is the second or subsequent declarator in this declaration,
/// the location of the comma before this declarator.
SourceLocation CommaLoc;
@@ -1712,14 +1803,12 @@ private:
public:
Declarator(const DeclSpec &ds, TheContext C)
- : DS(ds), Range(ds.getSourceRange()), Context(C),
- InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
- GroupingParens(false), FunctionDefinition(FDK_Declaration),
- Redeclaration(false),
- Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr),
- InlineParamsUsed(false), Extension(false), ObjCIvar(false),
- ObjCWeakProperty(false) {
- }
+ : DS(ds), Range(ds.getSourceRange()), Context(C),
+ InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
+ GroupingParens(false), FunctionDefinition(FDK_Declaration),
+ Redeclaration(false), Extension(false), ObjCIvar(false),
+ ObjCWeakProperty(false), InlineStorageUsed(false),
+ Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr) {}
~Declarator() {
clear();
@@ -1746,6 +1835,10 @@ public:
/// \brief Retrieve the name specified by this declarator.
UnqualifiedId &getName() { return Name; }
+
+ const DecompositionDeclarator &getDecompositionDeclarator() const {
+ return BindingGroup;
+ }
TheContext getContext() const { return Context; }
@@ -1789,13 +1882,14 @@ public:
SS.clear();
Name.clear();
Range = DS.getSourceRange();
-
+ BindingGroup.clear();
+
for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i)
DeclTypeInfo[i].destroy();
DeclTypeInfo.clear();
Attrs.clear();
AsmLabel = nullptr;
- InlineParamsUsed = false;
+ InlineStorageUsed = false;
ObjCIvar = false;
ObjCWeakProperty = false;
CommaLoc = SourceLocation();
@@ -1906,6 +2000,45 @@ public:
llvm_unreachable("unknown context kind!");
}
+ /// Return true if the context permits a C++17 decomposition declarator.
+ bool mayHaveDecompositionDeclarator() const {
+ switch (Context) {
+ case FileContext:
+ // FIXME: It's not clear that the proposal meant to allow file-scope
+ // structured bindings, but it does.
+ case BlockContext:
+ case ForContext:
+ case InitStmtContext:
+ return true;
+
+ case ConditionContext:
+ case MemberContext:
+ case PrototypeContext:
+ case TemplateParamContext:
+ // Maybe one day...
+ return false;
+
+ // These contexts don't allow any kind of non-abstract declarator.
+ case KNRTypeListContext:
+ case TypeNameContext:
+ case AliasDeclContext:
+ case AliasTemplateContext:
+ case LambdaExprParameterContext:
+ case ObjCParameterContext:
+ case ObjCResultContext:
+ case CXXNewContext:
+ case CXXCatchContext:
+ case ObjCCatchContext:
+ case BlockLiteralContext:
+ case LambdaExprContext:
+ case ConversionIdContext:
+ case TemplateTypeArgContext:
+ case TrailingReturnContext:
+ return false;
+ }
+ llvm_unreachable("unknown context kind!");
+ }
+
/// mayBeFollowedByCXXDirectInit - Return true if the declarator can be
/// followed by a C++ direct initializer, e.g. "int x(1);".
bool mayBeFollowedByCXXDirectInit() const {
@@ -1959,14 +2092,22 @@ public:
}
/// isPastIdentifier - Return true if we have parsed beyond the point where
- /// the
+ /// the name would appear. (This may happen even if we haven't actually parsed
+ /// a name, perhaps because this context doesn't require one.)
bool isPastIdentifier() const { return Name.isValid(); }
/// hasName - Whether this declarator has a name, which might be an
/// identifier (accessible via getIdentifier()) or some kind of
- /// special C++ name (constructor, destructor, etc.).
- bool hasName() const {
- return Name.getKind() != UnqualifiedId::IK_Identifier || Name.Identifier;
+ /// special C++ name (constructor, destructor, etc.), or a structured
+ /// binding (which is not exactly a name, but occupies the same position).
+ bool hasName() const {
+ return Name.getKind() != UnqualifiedId::IK_Identifier || Name.Identifier ||
+ isDecompositionDeclarator();
+ }
+
+ /// Return whether this declarator is a decomposition declarator.
+ bool isDecompositionDeclarator() const {
+ return BindingGroup.isSet();
}
IdentifierInfo *getIdentifier() const {
@@ -1981,7 +2122,13 @@ public:
void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc) {
Name.setIdentifier(Id, IdLoc);
}
-
+
+ /// Set the decomposition bindings for this declarator.
+ void
+ setDecompositionBindings(SourceLocation LSquareLoc,
+ ArrayRef<DecompositionDeclarator::Binding> Bindings,
+ SourceLocation RSquareLoc);
+
/// AddTypeInfo - Add a chunk to this declarator. Also extend the range to
/// EndLoc, which should be the last token of the chunk.
void AddTypeInfo(const DeclaratorChunk &TI,
@@ -2279,7 +2426,9 @@ public:
VS_None = 0,
VS_Override = 1,
VS_Final = 2,
- VS_Sealed = 4
+ VS_Sealed = 4,
+ // Represents the __final keyword, which is legal for gcc in pre-C++11 mode.
+ VS_GNU_Final = 8
};
VirtSpecifiers() : Specifiers(0), LastSpecifier(VS_None) { }
@@ -2292,7 +2441,7 @@ public:
bool isOverrideSpecified() const { return Specifiers & VS_Override; }
SourceLocation getOverrideLoc() const { return VS_overrideLoc; }
- bool isFinalSpecified() const { return Specifiers & (VS_Final | VS_Sealed); }
+ bool isFinalSpecified() const { return Specifiers & (VS_Final | VS_Sealed | VS_GNU_Final); }
bool isFinalSpelledSealed() const { return Specifiers & VS_Sealed; }
SourceLocation getFinalLoc() const { return VS_finalLoc; }
diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h
index 155b3aa72d70..b73ec0868f52 100644
--- a/include/clang/Sema/DelayedDiagnostic.h
+++ b/include/clang/Sema/DelayedDiagnostic.h
@@ -113,16 +113,16 @@ private:
/// the complete parsing of the current declaration.
class DelayedDiagnostic {
public:
- enum DDKind { Deprecation, Unavailable, Access, ForbiddenType };
+ enum DDKind : unsigned char { Availability, Access, ForbiddenType };
- unsigned char Kind; // actually a DDKind
+ DDKind Kind;
bool Triggered;
SourceLocation Loc;
void Destroy();
- static DelayedDiagnostic makeAvailability(Sema::AvailabilityDiagnostic AD,
+ static DelayedDiagnostic makeAvailability(AvailabilityResult AR,
SourceLocation Loc,
const NamedDecl *D,
const ObjCInterfaceDecl *UnknownObjCClass,
@@ -164,17 +164,19 @@ public:
return *reinterpret_cast<const AccessedEntity*>(AccessData);
}
- const NamedDecl *getDeprecationDecl() const {
- assert((Kind == Deprecation || Kind == Unavailable) &&
- "Not a deprecation diagnostic.");
- return DeprecationData.Decl;
+ const NamedDecl *getAvailabilityDecl() const {
+ assert(Kind == Availability && "Not an availability diagnostic.");
+ return AvailabilityData.Decl;
}
- StringRef getDeprecationMessage() const {
- assert((Kind == Deprecation || Kind == Unavailable) &&
- "Not a deprecation diagnostic.");
- return StringRef(DeprecationData.Message,
- DeprecationData.MessageLen);
+ StringRef getAvailabilityMessage() const {
+ assert(Kind == Availability && "Not an availability diagnostic.");
+ return StringRef(AvailabilityData.Message, AvailabilityData.MessageLen);
+ }
+
+ AvailabilityResult getAvailabilityResult() const {
+ assert(Kind == Availability && "Not an availability diagnostic.");
+ return AvailabilityData.AR;
}
/// The diagnostic ID to emit. Used like so:
@@ -195,27 +197,28 @@ public:
assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
return QualType::getFromOpaquePtr(ForbiddenTypeData.OperandType);
}
-
+
const ObjCInterfaceDecl *getUnknownObjCClass() const {
- return DeprecationData.UnknownObjCClass;
+ return AvailabilityData.UnknownObjCClass;
}
const ObjCPropertyDecl *getObjCProperty() const {
- return DeprecationData.ObjCProperty;
+ return AvailabilityData.ObjCProperty;
}
-
+
bool getObjCPropertyAccess() const {
- return DeprecationData.ObjCPropertyAccess;
+ return AvailabilityData.ObjCPropertyAccess;
}
-
+
private:
- struct DD {
+ struct AD {
const NamedDecl *Decl;
const ObjCInterfaceDecl *UnknownObjCClass;
const ObjCPropertyDecl *ObjCProperty;
const char *Message;
size_t MessageLen;
+ AvailabilityResult AR;
bool ObjCPropertyAccess;
};
@@ -226,8 +229,7 @@ private:
};
union {
- /// Deprecation
- struct DD DeprecationData;
+ struct AD AvailabilityData;
struct FTD ForbiddenTypeData;
/// Access control.
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h
index c2b13046d709..c5cb7b12b3f1 100644
--- a/include/clang/Sema/ExternalSemaSource.h
+++ b/include/clang/Sema/ExternalSemaSource.h
@@ -190,7 +190,8 @@ public:
/// external source should take care not to introduce the same map entries
/// repeatedly.
virtual void ReadLateParsedTemplates(
- llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {}
+ llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
+ &LPTMap) {}
/// \copydoc Sema::CorrectTypo
/// \note LookupKind must correspond to a valid Sema::LookupNameKind
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index a0bf78bf1688..a7b8cce32691 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -20,7 +20,6 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Overload.h"
#include "clang/Sema/Ownership.h"
-#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
@@ -85,7 +84,10 @@ public:
EK_RelatedResult,
/// \brief The entity being initialized is a function parameter; function
/// is member of group of audited CF APIs.
- EK_Parameter_CF_Audited
+ EK_Parameter_CF_Audited,
+ /// \brief The entity being initialized is a structured binding of a
+ /// decomposition declaration.
+ EK_Binding,
// Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this
// enum as an index for its first %select. When modifying this list,
@@ -118,6 +120,16 @@ private:
bool NRVO;
};
+ struct VD {
+ /// \brief The VarDecl, FieldDecl, or BindingDecl being initialized.
+ ValueDecl *VariableOrMember;
+
+ /// \brief When Kind == EK_Member, whether this is an implicit member
+ /// initialization in a copy or move constructor. These can perform array
+ /// copies.
+ bool IsImplicitFieldInit;
+ };
+
struct C {
/// \brief The name of the variable being captured by an EK_LambdaCapture.
IdentifierInfo *VarID;
@@ -127,9 +139,8 @@ private:
};
union {
- /// \brief When Kind == EK_Variable, or EK_Member, the VarDecl or
- /// FieldDecl, respectively.
- DeclaratorDecl *VariableOrMember;
+ /// \brief When Kind == EK_Variable, EK_Member or EK_Binding, the variable.
+ VD Variable;
/// \brief When Kind == EK_RelatedResult, the ObjectiveC method where
/// result type was implicitly changed to accommodate ARC semantics.
@@ -161,9 +172,9 @@ private:
InitializedEntity() : ManglingNumber(0) {}
/// \brief Create the initialization entity for a variable.
- InitializedEntity(VarDecl *Var)
- : Kind(EK_Variable), Parent(nullptr), Type(Var->getType()),
- ManglingNumber(0), VariableOrMember(Var) { }
+ InitializedEntity(VarDecl *Var, EntityKind EK = EK_Variable)
+ : Kind(EK), Parent(nullptr), Type(Var->getType()),
+ ManglingNumber(0), Variable{Var, false} { }
/// \brief Create the initialization entity for the result of a
/// function, throwing an object, performing an explicit cast, or
@@ -177,9 +188,11 @@ private:
}
/// \brief Create the initialization entity for a member subobject.
- InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent)
+ InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent,
+ bool Implicit)
: Kind(EK_Member), Parent(Parent), Type(Member->getType()),
- ManglingNumber(0), VariableOrMember(Member) { }
+ ManglingNumber(0), Variable{Member, Implicit} {
+ }
/// \brief Create the initialization entity for an array element.
InitializedEntity(ASTContext &Context, unsigned Index,
@@ -297,15 +310,17 @@ public:
/// \brief Create the initialization entity for a member subobject.
static InitializedEntity
InitializeMember(FieldDecl *Member,
- const InitializedEntity *Parent = nullptr) {
- return InitializedEntity(Member, Parent);
+ const InitializedEntity *Parent = nullptr,
+ bool Implicit = false) {
+ return InitializedEntity(Member, Parent, Implicit);
}
/// \brief Create the initialization entity for a member subobject.
static InitializedEntity
InitializeMember(IndirectFieldDecl *Member,
- const InitializedEntity *Parent = nullptr) {
- return InitializedEntity(Member->getAnonField(), Parent);
+ const InitializedEntity *Parent = nullptr,
+ bool Implicit = false) {
+ return InitializedEntity(Member->getAnonField(), Parent, Implicit);
}
/// \brief Create the initialization entity for an array element.
@@ -315,6 +330,11 @@ public:
return InitializedEntity(Context, Index, Parent);
}
+ /// \brief Create the initialization entity for a structured binding.
+ static InitializedEntity InitializeBinding(VarDecl *Binding) {
+ return InitializedEntity(Binding, EK_Binding);
+ }
+
/// \brief Create the initialization entity for a lambda capture.
static InitializedEntity InitializeLambdaCapture(IdentifierInfo *VarID,
QualType FieldType,
@@ -356,7 +376,7 @@ public:
/// \brief Retrieve the variable, parameter, or field being
/// initialized.
- DeclaratorDecl *getDecl() const;
+ ValueDecl *getDecl() const;
/// \brief Retrieve the ObjectiveC method being initialized.
ObjCMethodDecl *getMethodDecl() const { return MethodDecl; }
@@ -388,6 +408,18 @@ public:
return Base & 0x1;
}
+ /// \brief Determine whether this is an array new with an unknown bound.
+ bool isVariableLengthArrayNew() const {
+ return getKind() == EK_New && dyn_cast_or_null<IncompleteArrayType>(
+ getType()->getAsArrayTypeUnsafe());
+ }
+
+ /// \brief Is this the implicit initialization of a member of a class from
+ /// a defaulted constructor?
+ bool isImplicitMemberInitializer() const {
+ return getKind() == EK_Member && Variable.IsImplicitFieldInit;
+ }
+
/// \brief Determine the location of the 'return' keyword when initializing
/// the result of a function call.
SourceLocation getReturnLoc() const {
@@ -655,6 +687,9 @@ public:
/// temporary object, which is permitted (but not required) by
/// C++98/03 but not C++0x.
SK_ExtraneousCopyToTemporary,
+ /// \brief Direct-initialization from a reference-related object in the
+ /// final stage of class copy-initialization.
+ SK_FinalCopy,
/// \brief Perform a user-defined conversion, either via a conversion
/// function or via a constructor.
SK_UserConversion,
@@ -692,9 +727,14 @@ public:
/// \brief An initialization that "converts" an Objective-C object
/// (not a point to an object) to another Objective-C object type.
SK_ObjCObjectConversion,
+ /// \brief Array indexing for initialization by elementwise copy.
+ SK_ArrayLoopIndex,
+ /// \brief Array initialization by elementwise copy.
+ SK_ArrayLoopInit,
/// \brief Array initialization (from an array rvalue).
- /// This is a GNU C extension.
SK_ArrayInit,
+ /// \brief Array initialization (from an array rvalue) as a GNU extension.
+ SK_GNUArrayInit,
/// \brief Array initialization from a parenthesized initializer list.
/// This is a GNU C++ extension.
SK_ParenthesizedArrayInit,
@@ -711,6 +751,8 @@ public:
SK_StdInitializerListConstructorCall,
/// \brief Initialize an OpenCL sampler from an integer.
SK_OCLSamplerInit,
+ /// \brief Initialize queue_t from 0.
+ SK_OCLZeroQueue,
/// \brief Passing zero to a function where OpenCL event_t is expected.
SK_OCLZeroEvent
};
@@ -792,6 +834,10 @@ public:
FK_ReferenceInitOverloadFailed,
/// \brief Non-const lvalue reference binding to a temporary.
FK_NonConstLValueReferenceBindingToTemporary,
+ /// \brief Non-const lvalue reference binding to a bit-field.
+ FK_NonConstLValueReferenceBindingToBitfield,
+ /// \brief Non-const lvalue reference binding to a vector element.
+ FK_NonConstLValueReferenceBindingToVectorElement,
/// \brief Non-const lvalue reference binding to an lvalue of unrelated
/// type.
FK_NonConstLValueReferenceBindingToUnrelated,
@@ -1015,6 +1061,10 @@ public:
/// \param T The type of the temporary being created.
void AddExtraneousCopyToTemporary(QualType T);
+ /// \brief Add a new step that makes a copy of the input to an object of
+ /// the given type, as the final step in class copy-initialization.
+ void AddFinalCopy(QualType T);
+
/// \brief Add a new step invoking a conversion function, which is either
/// a constructor or a conversion function.
void AddUserConversionStep(FunctionDecl *Function,
@@ -1072,8 +1122,11 @@ public:
/// always a no-op.
void AddObjCObjectConversionStep(QualType T);
+ /// \brief Add an array initialization loop step.
+ void AddArrayInitLoopStep(QualType T, QualType EltTy);
+
/// \brief Add an array initialization step.
- void AddArrayInitStep(QualType T);
+ void AddArrayInitStep(QualType T, bool IsGNUExtension);
/// \brief Add a parenthesized array initialization step.
void AddParenthesizedArrayInitStep(QualType T);
@@ -1097,6 +1150,9 @@ public:
/// constant.
void AddOCLZeroEventStep(QualType T);
+ /// \brief Add a step to initialize an OpenCL queue_t from 0.
+ void AddOCLZeroQueueStep(QualType T);
+
/// \brief Add steps to unwrap a initializer list for a reference around a
/// single element and rewrap it at the end.
void RewrapReferenceInitList(QualType T, InitListExpr *Syntactic);
diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h
index 9bf8cd3d9252..37157204ea10 100644
--- a/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -322,8 +322,8 @@ public:
/// external source should take care not to introduce the same map entries
/// repeatedly.
void ReadLateParsedTemplates(
- llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap)
- override;
+ llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
+ &LPTMap) override;
/// \copydoc ExternalSemaSource::CorrectTypo
/// \note Returns the first nonempty correction.
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index d0f21cd71f8d..376db92d03bd 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -62,7 +62,7 @@ namespace clang {
ICK_Lvalue_To_Rvalue, ///< Lvalue-to-rvalue conversion (C++ 4.1)
ICK_Array_To_Pointer, ///< Array-to-pointer conversion (C++ 4.2)
ICK_Function_To_Pointer, ///< Function-to-pointer (C++ 4.3)
- ICK_NoReturn_Adjustment, ///< Removal of noreturn from a type (Clang)
+ ICK_Function_Conversion, ///< Function pointer conversion (C++17 4.13)
ICK_Qualification, ///< Qualification conversions (C++ 4.4)
ICK_Integral_Promotion, ///< Integral promotions (C++ 4.5)
ICK_Floating_Promotion, ///< Floating point promotions (C++ 4.6)
@@ -83,7 +83,10 @@ namespace clang {
ICK_TransparentUnionConversion, ///< Transparent Union Conversions
ICK_Writeback_Conversion, ///< Objective-C ARC writeback conversion
ICK_Zero_Event_Conversion, ///< Zero constant to event (OpenCL1.2 6.12.10)
+ ICK_Zero_Queue_Conversion, ///< Zero constant to queue
ICK_C_Only_Conversion, ///< Conversions allowed in C, but not C++
+ ICK_Incompatible_Pointer_Conversion, ///< C-only conversion between pointers
+ /// with incompatible types
ICK_Num_Conversion_Kinds, ///< The number of conversion kinds
};
@@ -97,8 +100,10 @@ namespace clang {
ICR_Conversion, ///< Conversion
ICR_Complex_Real_Conversion, ///< Complex <-> Real conversion
ICR_Writeback_Conversion, ///< ObjC ARC writeback conversion
- ICR_C_Conversion ///< Conversion only allowed in the C standard.
+ ICR_C_Conversion, ///< Conversion only allowed in the C standard.
/// (e.g. void* to char*)
+ ICR_C_Conversion_Extension ///< Conversion not allowed by the C standard,
+ /// but that we accept as an extension anyway.
};
ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind);
@@ -117,7 +122,11 @@ namespace clang {
/// A narrowing conversion, because a non-constant-expression variable might
/// have got narrowed.
- NK_Variable_Narrowing
+ NK_Variable_Narrowing,
+
+ /// Cannot tell whether this is a narrowing conversion because the
+ /// expression is value-dependent.
+ NK_Dependent_Narrowing,
};
/// StandardConversionSequence - represents a standard conversion
@@ -141,7 +150,8 @@ namespace clang {
/// pointer-to-member conversion, or boolean conversion.
ImplicitConversionKind Second : 8;
- /// Third - The third conversion can be a qualification conversion.
+ /// Third - The third conversion can be a qualification conversion
+ /// or a function conversion.
ImplicitConversionKind Third : 8;
/// \brief Whether this is the deprecated conversion of a
@@ -428,8 +438,9 @@ namespace clang {
};
ImplicitConversionSequence()
- : ConversionKind(Uninitialized), StdInitializerListElement(false)
- {}
+ : ConversionKind(Uninitialized), StdInitializerListElement(false) {
+ Standard.setAsIdentityConversion();
+ }
~ImplicitConversionSequence() {
destruct();
}
@@ -586,7 +597,10 @@ namespace clang {
ovl_fail_enable_if,
/// This candidate was not viable because its address could not be taken.
- ovl_fail_addr_not_available
+ ovl_fail_addr_not_available,
+
+ /// This candidate was not viable because its OpenCL extension is disabled.
+ ovl_fail_ext_disabled,
};
/// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
@@ -722,8 +736,9 @@ namespace clang {
CandidateSetKind Kind;
unsigned NumInlineSequences;
- llvm::AlignedCharArray<llvm::AlignOf<ImplicitConversionSequence>::Alignment,
- 16 * sizeof(ImplicitConversionSequence)> InlineSpace;
+ llvm::AlignedCharArray<alignof(ImplicitConversionSequence),
+ 16 * sizeof(ImplicitConversionSequence)>
+ InlineSpace;
OverloadCandidateSet(const OverloadCandidateSet &) = delete;
void operator=(const OverloadCandidateSet &) = delete;
@@ -790,7 +805,9 @@ namespace clang {
OverloadCandidateDisplayKind OCD,
ArrayRef<Expr *> Args,
StringRef Opc = "",
- SourceLocation Loc = SourceLocation());
+ SourceLocation Loc = SourceLocation(),
+ llvm::function_ref<bool(OverloadCandidate&)> Filter =
+ [](OverloadCandidate&) { return true; });
};
bool isBetterOverloadCandidate(Sema &S,
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
index 68d13f97e2e4..92ea5296c45b 100644
--- a/include/clang/Sema/Ownership.h
+++ b/include/clang/Sema/Ownership.h
@@ -17,7 +17,6 @@
#include "clang/AST/Expr.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/PointerIntPair.h"
//===----------------------------------------------------------------------===//
// OpaquePtr
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index ee724f7d728c..4b54807ab660 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -106,11 +106,15 @@ public:
bool HasDroppedStmt : 1;
/// \brief True if current scope is for OpenMP declare reduction combiner.
- bool HasOMPDeclareReductionCombiner;
+ bool HasOMPDeclareReductionCombiner : 1;
/// \brief Whether there is a fallthrough statement in this function.
bool HasFallthroughStmt : 1;
+ /// \brief Whether we make reference to a declaration that could be
+ /// unavailable.
+ bool HasPotentialAvailabilityViolations : 1;
+
/// A flag that is set when parsing a method that must call super's
/// implementation, such as \c -dealloc, \c -finalize, or any method marked
/// with \c __attribute__((objc_requires_super)).
@@ -381,6 +385,7 @@ public:
HasDroppedStmt(false),
HasOMPDeclareReductionCombiner(false),
HasFallthroughStmt(false),
+ HasPotentialAvailabilityViolations(false),
ObjCShouldCallSuper(false),
ObjCIsDesignatedInit(false),
ObjCWarnForNoDesignatedInitChain(false),
@@ -730,7 +735,16 @@ public:
/// to local variables that are usable as constant expressions and
/// do not involve an odr-use (they may still need to be captured
/// if the enclosing full-expression is instantiation dependent).
- llvm::SmallSet<Expr*, 8> NonODRUsedCapturingExprs;
+ llvm::SmallSet<Expr *, 8> NonODRUsedCapturingExprs;
+
+ /// Contains all of the variables defined in this lambda that shadow variables
+ /// that were defined in parent contexts. Used to avoid warnings when the
+ /// shadowed variables are uncaptured by this lambda.
+ struct ShadowedOuterDecl {
+ const VarDecl *VD;
+ const VarDecl *ShadowedDecl;
+ };
+ llvm::SmallVector<ShadowedOuterDecl, 4> ShadowingDecls;
SourceLocation PotentialThisCaptureLocation;
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 437a44a30711..82caaeb24ae7 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -74,6 +74,7 @@ namespace clang {
class ASTWriter;
class ArrayType;
class AttributeList;
+ class BindingDecl;
class BlockDecl;
class CapturedDecl;
class CXXBasePath;
@@ -454,9 +455,9 @@ public:
/// \brief Store a list of either DeclRefExprs or MemberExprs
/// that contain a reference to a variable (constant) that may or may not
/// be odr-used in this Expr, and we won't know until all lvalue-to-rvalue
- /// and discarded value conversions have been applied to all subexpressions
- /// of the enclosing full expression. This is cleared at the end of each
- /// full expression.
+ /// and discarded value conversions have been applied to all subexpressions
+ /// of the enclosing full expression. This is cleared at the end of each
+ /// full expression.
llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs;
/// \brief Stack containing information about each of the nested
@@ -550,7 +551,8 @@ public:
SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2>
DelayedDefaultedMemberExceptionSpecs;
- typedef llvm::MapVector<const FunctionDecl *, LateParsedTemplate *>
+ typedef llvm::MapVector<const FunctionDecl *,
+ std::unique_ptr<LateParsedTemplate>>
LateParsedTemplateMapT;
LateParsedTemplateMapT LateParsedTemplateMap;
@@ -669,15 +671,15 @@ public:
class SynthesizedFunctionScope {
Sema &S;
Sema::ContextRAII SavedContext;
-
+
public:
SynthesizedFunctionScope(Sema &S, DeclContext *DC)
- : S(S), SavedContext(S, DC)
+ : S(S), SavedContext(S, DC)
{
S.PushFunctionScope();
S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
}
-
+
~SynthesizedFunctionScope() {
S.PopExpressionEvaluationContext();
S.PopFunctionScopeInfo();
@@ -720,6 +722,14 @@ public:
/// standard library.
LazyDeclPtr StdBadAlloc;
+ /// \brief The C++ "std::align_val_t" enum class, which is defined by the C++
+ /// standard library.
+ LazyDeclPtr StdAlignValT;
+
+ /// \brief The C++ "std::experimental" namespace, where the experimental parts
+ /// of the standard library resides.
+ NamespaceDecl *StdExperimentalNamespaceCache;
+
/// \brief The C++ "std::initializer_list" template, which is defined in
/// \<initializer_list>.
ClassTemplateDecl *StdInitializerList;
@@ -778,15 +788,12 @@ 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;
/// A flag to indicate that we're in a context that permits abstract
- /// references to fields. This is really a
+ /// references to fields. This is really a
bool AllowAbstractFieldReference;
/// \brief Describes how the expressions currently being parsed are
@@ -866,7 +873,7 @@ public:
///
/// This mangling information is allocated lazily, since most contexts
/// do not have lambda expressions or block literals.
- IntrusiveRefCntPtr<MangleNumberingContext> MangleNumbering;
+ std::unique_ptr<MangleNumberingContext> MangleNumbering;
/// \brief If we are processing a decltype type, a set of call expressions
/// for which we have deferred checking the completeness of the return type.
@@ -1177,7 +1184,7 @@ public:
/// is during Parsing. Currently it is used to pass on the depth
/// when parsing generic lambda 'auto' parameters.
void RecordParsingTemplateParameterDepth(unsigned Depth);
-
+
void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD,
RecordDecl *RD,
CapturedRegionKind K);
@@ -1189,11 +1196,11 @@ public:
sema::FunctionScopeInfo *getCurFunction() const {
return FunctionScopes.back();
}
-
+
sema::FunctionScopeInfo *getEnclosingFunction() const {
if (FunctionScopes.empty())
return nullptr;
-
+
for (int e = FunctionScopes.size()-1; e >= 0; --e) {
if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
continue;
@@ -1201,13 +1208,13 @@ public:
}
return nullptr;
}
-
+
template <typename ExprT>
void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) {
if (!isUnevaluatedContext())
getCurFunction()->recordUseOfWeak(E, IsRead);
}
-
+
void PushCompoundScope();
void PopCompoundScope();
@@ -1293,7 +1300,9 @@ public:
SourceLocation Loc, DeclarationName Entity);
QualType BuildParenType(QualType T);
QualType BuildAtomicType(QualType T, SourceLocation Loc);
- QualType BuildPipeType(QualType T,
+ QualType BuildReadPipeType(QualType T,
+ SourceLocation Loc);
+ QualType BuildWritePipeType(QualType T,
SourceLocation Loc);
TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S);
@@ -1321,18 +1330,20 @@ public:
bool CheckEquivalentExceptionSpec(
const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
const FunctionProtoType *Old, SourceLocation OldLoc,
- const FunctionProtoType *New, SourceLocation NewLoc,
- bool *MissingExceptionSpecification = nullptr,
- bool *MissingEmptyExceptionSpecification = nullptr,
- bool AllowNoexceptAllMatchWithNoSpec = false,
- bool IsOperatorNew = false);
- bool CheckExceptionSpecSubset(
- const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
- const FunctionProtoType *Superset, SourceLocation SuperLoc,
- const FunctionProtoType *Subset, SourceLocation SubLoc);
- bool CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
- const FunctionProtoType *Target, SourceLocation TargetLoc,
- const FunctionProtoType *Source, SourceLocation SourceLoc);
+ const FunctionProtoType *New, SourceLocation NewLoc);
+ bool CheckExceptionSpecSubset(const PartialDiagnostic &DiagID,
+ const PartialDiagnostic &NestedDiagID,
+ const PartialDiagnostic &NoteID,
+ const FunctionProtoType *Superset,
+ SourceLocation SuperLoc,
+ const FunctionProtoType *Subset,
+ SourceLocation SubLoc);
+ bool CheckParamExceptionSpec(const PartialDiagnostic &NestedDiagID,
+ const PartialDiagnostic &NoteID,
+ const FunctionProtoType *Target,
+ SourceLocation TargetLoc,
+ const FunctionProtoType *Source,
+ SourceLocation SourceLoc);
TypeResult ActOnTypeName(Scope *S, Declarator &D);
@@ -1393,8 +1404,14 @@ private:
bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
TypeDiagnoser *Diagnoser);
+ struct ModuleScope {
+ clang::Module *Module;
+ VisibleModuleSet OuterVisibleModules;
+ };
+ /// The modules we're currently parsing.
+ llvm::SmallVector<ModuleScope, 16> ModuleScopes;
+
VisibleModuleSet VisibleModules;
- llvm::SmallVector<VisibleModuleSet, 16> VisibleModulesStack;
Module *CachedFakeTopLevelModule;
@@ -1510,12 +1527,6 @@ public:
NamedDecl *Previous;
};
- /// List of decls defined in a function prototype. This contains EnumConstants
- /// that incorrectly end up in translation unit scope because there is no
- /// function to pin them on. ActOnFunctionDeclarator reads this list and patches
- /// them into the FunctionDecl.
- std::vector<NamedDecl*> DeclsInPrototypeScope;
-
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr);
void DiagnoseUseOfUnimplementedSelectors();
@@ -1696,6 +1707,8 @@ public:
/// to a shadowing declaration.
void CheckShadowingDeclModification(Expr *E, SourceLocation Loc);
+ void DiagnoseShadowingLambdaDecls(const sema::LambdaScopeInfo *LSI);
+
private:
/// Map of current shadowing declarations to shadowed declarations. Warn if
/// it looks like the user is trying to modify the shadowing declaration.
@@ -1716,11 +1729,16 @@ public:
TypeSourceInfo *TInfo,
LookupResult &Previous,
MultiTemplateParamsArg TemplateParamLists,
- bool &AddToScope);
+ bool &AddToScope,
+ ArrayRef<BindingDecl *> Bindings = None);
+ NamedDecl *
+ ActOnDecompositionDeclarator(Scope *S, Declarator &D,
+ MultiTemplateParamsArg TemplateParamLists);
// Returns true if the variable declaration is a redeclaration
bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
void CheckVariableDeclarationType(VarDecl *NewVD);
- void CheckCompleteVariableDeclaration(VarDecl *var);
+ void CheckCompleteVariableDeclaration(VarDecl *VD);
+ void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD);
void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
@@ -1742,6 +1760,7 @@ public:
bool CheckFunctionDeclaration(Scope *S,
FunctionDecl *NewFD, LookupResult &Previous,
bool IsExplicitSpecialization);
+ bool shouldLinkDependentDeclWithPrevious(Decl *D, Decl *OldDecl);
void CheckMain(FunctionDecl *FD, const DeclSpec &D);
void CheckMSVCRTEntryPoint(FunctionDecl *FD);
Decl *ActOnParamDeclarator(Scope *S, Declarator &D);
@@ -1766,6 +1785,8 @@ public:
bool TypeMayContainAuto);
void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto);
void ActOnInitializerError(Decl *Dcl);
+ bool canInitializeWithParenthesizedList(QualType TargetType);
+
void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc);
void ActOnCXXForRangeDecl(Decl *D);
StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
@@ -1850,6 +1871,17 @@ public:
AttributeList *AttrList,
SourceLocation SemiLoc);
+ enum class ModuleDeclKind {
+ Module, ///< 'module X;'
+ Partition, ///< 'module partition X;'
+ Implementation, ///< 'module implementation X;'
+ };
+
+ /// The parser has processed a module-declaration that begins the definition
+ /// of a module interface or implementation.
+ DeclGroupPtrTy ActOnModuleDecl(SourceLocation ModuleLoc, ModuleDeclKind MDK,
+ ModuleIdPath Path);
+
/// \brief The parser has processed a module import declaration.
///
/// \param AtLoc The location of the '@' symbol, if any.
@@ -1863,16 +1895,13 @@ public:
/// \brief The parser has processed a module import translated from a
/// #include or similar preprocessing directive.
void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
+ void BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
/// \brief The parsed has entered a submodule.
void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod);
/// \brief The parser has left a submodule.
void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod);
- /// \brief Check if module import may be found in the current context,
- /// emit error if not.
- void diagnoseMisplacedModuleImport(Module *M, SourceLocation ImportLoc);
-
/// \brief Create an implicit import of the given module at the given
/// source location, for error recovery, if possible.
///
@@ -1900,6 +1929,11 @@ public:
SourceLocation DeclLoc, ArrayRef<Module *> Modules,
MissingImportKind MIK, bool Recover);
+ Decl *ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc,
+ SourceLocation LBraceLoc);
+ Decl *ActOnFinishExportDecl(Scope *S, Decl *ExportDecl,
+ SourceLocation RBraceLoc);
+
/// \brief We've found a use of a templated declaration that would trigger an
/// implicit instantiation. Check that any relevant explicit specializations
/// and partial specializations are visible, and diagnose if not.
@@ -1939,6 +1973,24 @@ public:
Decl *BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
RecordDecl *Record);
+ /// Common ways to introduce type names without a tag for use in diagnostics.
+ /// Keep in sync with err_tag_reference_non_tag.
+ enum NonTagKind {
+ NTK_NonStruct,
+ NTK_NonClass,
+ NTK_NonUnion,
+ NTK_NonEnum,
+ NTK_Typedef,
+ NTK_TypeAlias,
+ NTK_Template,
+ NTK_TypeAliasTemplate,
+ NTK_TemplateTemplateArgument,
+ };
+
+ /// Given a non-tag type declaration, returns an enum useful for indicating
+ /// what kind of non-tag type this is.
+ NonTagKind getNonTagTypeDeclKind(const Decl *D, TagTypeKind TTK);
+
bool isAcceptableTagRedeclaration(const TagDecl *Previous,
TagTypeKind NewTag, bool isDefinition,
SourceLocation NewTagLoc,
@@ -2181,6 +2233,8 @@ public:
VisibilityAttr *mergeVisibilityAttr(Decl *D, SourceRange Range,
VisibilityAttr::VisibilityType Vis,
unsigned AttrSpellingListIndex);
+ UuidAttr *mergeUuidAttr(Decl *D, SourceRange Range,
+ unsigned AttrSpellingListIndex, StringRef Uuid);
DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range,
unsigned AttrSpellingListIndex);
DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range,
@@ -2219,6 +2273,7 @@ public:
void MergeVarDecl(VarDecl *New, LookupResult &Previous);
void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld);
void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
+ bool checkVarDeclRedefinition(VarDecl *OldDefn, VarDecl *NewDefn);
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S);
// AssignmentAction - This is used by all the assignment diagnostic functions
@@ -2305,7 +2360,7 @@ public:
bool IgnoreBaseAccess);
bool IsQualificationConversion(QualType FromType, QualType ToType,
bool CStyle, bool &ObjCLifetimeConversion);
- bool IsNoReturnConversion(QualType FromType, QualType ToType,
+ bool IsFunctionConversion(QualType FromType, QualType ToType,
QualType &ResultTy);
bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
bool isSameOrCompatibleFunctionType(CanQualType Param, CanQualType Arg);
@@ -2519,7 +2574,7 @@ public:
OverloadCandidateSet& CandidateSet,
SourceRange OpRange = SourceRange());
void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
- ArrayRef<Expr *> Args,
+ ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
bool IsAssignmentOperator = false,
unsigned NumContextualBoolArguments = 0);
@@ -2799,8 +2854,8 @@ private:
TypoDiagnosticGenerator DiagHandler;
TypoRecoveryCallback RecoveryHandler;
TypoExprState();
- TypoExprState(TypoExprState&& other) LLVM_NOEXCEPT;
- TypoExprState& operator=(TypoExprState&& other) LLVM_NOEXCEPT;
+ TypoExprState(TypoExprState &&other) noexcept;
+ TypoExprState &operator=(TypoExprState &&other) noexcept;
};
/// \brief The set of unhandled TypoExprs and their associated state.
@@ -3015,7 +3070,7 @@ public:
bool isValidPointerAttrType(QualType T, bool RefOkay = false);
bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
- bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
+ bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
const FunctionDecl *FD = nullptr);
bool CheckNoReturnAttr(const AttributeList &attr);
bool checkStringLiteralArgumentAttr(const AttributeList &Attr,
@@ -3059,10 +3114,14 @@ public:
/// method) or an Objective-C property attribute, rather than as an
/// underscored type specifier.
///
+ /// \param allowArrayTypes Whether to accept nullability specifiers on an
+ /// array type (e.g., because it will decay to a pointer).
+ ///
/// \returns true if nullability cannot be applied, false otherwise.
bool checkNullabilityTypeSpecifier(QualType &type, NullabilityKind nullability,
SourceLocation nullabilityLoc,
- bool isContextSensitive);
+ bool isContextSensitive,
+ bool allowArrayTypes);
/// \brief Stmt attributes - this routine is the top level dispatcher.
StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs,
@@ -3117,18 +3176,18 @@ public:
/// declared in class 'IFace'.
bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace,
ObjCMethodDecl *Method, ObjCIvarDecl *IV);
-
+
/// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which
/// backs the property is not used in the property's accessor.
void DiagnoseUnusedBackingIvarInAccessor(Scope *S,
const ObjCImplementationDecl *ImplD);
-
+
/// GetIvarBackingPropertyAccessor - If method is a property setter/getter and
/// it property has a backing ivar, returns this ivar; otherwise, returns NULL.
/// It also returns ivar's property on success.
ObjCIvarDecl *GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method,
const ObjCPropertyDecl *&PDecl) const;
-
+
/// Called by ActOnProperty to handle \@property declarations in
/// class extensions.
ObjCPropertyDecl *HandlePropertyInClassExtension(Scope *S,
@@ -3228,12 +3287,12 @@ public:
SmallVectorImpl<ObjCMethodDecl*>& Methods,
bool InstanceFirst, bool CheckTheOther,
const ObjCObjectType *TypeBound = nullptr);
-
+
bool
AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod,
SourceRange R, bool receiverIdOrClass,
SmallVectorImpl<ObjCMethodDecl*>& Methods);
-
+
void
DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods,
Selector Sel, SourceRange R,
@@ -3245,7 +3304,7 @@ private:
ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args,
bool IsInstance,
SmallVectorImpl<ObjCMethodDecl*>& Methods);
-
+
/// \brief Record the typo correction failure and return an empty correction.
TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc,
@@ -3621,18 +3680,18 @@ public:
void redelayDiagnostics(sema::DelayedDiagnosticPool &pool);
- enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable, AD_Partial };
-
- void EmitAvailabilityWarning(AvailabilityDiagnostic AD,
- NamedDecl *D, StringRef Message,
- SourceLocation Loc,
+ void EmitAvailabilityWarning(AvailabilityResult AR, NamedDecl *D,
+ StringRef Message, SourceLocation Loc,
const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty,
+ const ObjCPropertyDecl *ObjCProperty,
bool ObjCPropertyAccess);
bool makeUnavailableInSystemHeader(SourceLocation loc,
UnavailableAttr::ImplicitReason reason);
+ /// \brief Issue any -Wunguarded-availability warnings in \c FD
+ void DiagnoseUnguardedAvailabilityViolations(Decl *FD);
+
//===--------------------------------------------------------------------===//
// Expression Parsing Callbacks: SemaExpr.cpp.
@@ -3718,16 +3777,16 @@ public:
///
/// \param FunctionScopeIndexToStopAt If non-null, it points to the index
/// of the FunctionScopeInfo stack beyond which we do not attempt to capture.
- /// This is useful when enclosing lambdas must speculatively capture
+ /// This is useful when enclosing lambdas must speculatively capture
/// variables that may or may not be used in certain specializations of
/// a nested generic lambda.
- ///
+ ///
/// \returns true if an error occurred (i.e., the variable cannot be
/// captured) and false if the capture succeeded.
bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind,
SourceLocation EllipsisLoc, bool BuildAndDiagnose,
QualType &CaptureType,
- QualType &DeclRefType,
+ QualType &DeclRefType,
const unsigned *const FunctionScopeIndexToStopAt);
/// \brief Try to capture the given variable.
@@ -3965,6 +4024,12 @@ public:
bool SuppressQualifierCheck = false,
ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
+ ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
+ SourceLocation OpLoc,
+ const CXXScopeSpec &SS, FieldDecl *Field,
+ DeclAccessPair FoundDecl,
+ const DeclarationNameInfo &MemberNameInfo);
+
ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow);
bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType,
@@ -4201,7 +4266,10 @@ public:
NamespaceDecl *getStdNamespace() const;
NamespaceDecl *getOrCreateStdNamespace();
+ NamespaceDecl *lookupStdExperimentalNamespace();
+
CXXRecordDecl *getStdBadAlloc() const;
+ EnumDecl *getStdAlignValT() const;
/// \brief Tests whether Ty is an instance of std::initializer_list and, if
/// it is and Element is not NULL, assigns the element type to Element.
@@ -4249,18 +4317,22 @@ public:
SourceLocation NameLoc,
const LookupResult &Previous);
bool CheckUsingDeclQualifier(SourceLocation UsingLoc,
+ bool HasTypename,
const CXXScopeSpec &SS,
const DeclarationNameInfo &NameInfo,
SourceLocation NameLoc);
NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
SourceLocation UsingLoc,
+ bool HasTypenameKeyword,
+ SourceLocation TypenameLoc,
CXXScopeSpec &SS,
DeclarationNameInfo NameInfo,
+ SourceLocation EllipsisLoc,
AttributeList *AttrList,
- bool IsInstantiation,
- bool HasTypenameKeyword,
- SourceLocation TypenameLoc);
+ bool IsInstantiation);
+ NamedDecl *BuildUsingPackDecl(NamedDecl *InstantiatedFrom,
+ ArrayRef<NamedDecl *> Expansions);
bool CheckInheritingConstructorUsingDecl(UsingDecl *UD);
@@ -4273,13 +4345,12 @@ public:
Decl *ActOnUsingDeclaration(Scope *CurScope,
AccessSpecifier AS,
- bool HasUsingKeyword,
SourceLocation UsingLoc,
+ SourceLocation TypenameLoc,
CXXScopeSpec &SS,
UnqualifiedId &Name,
- AttributeList *AttrList,
- bool HasTypenameKeyword,
- SourceLocation TypenameLoc);
+ SourceLocation EllipsisLoc,
+ AttributeList *AttrList);
Decl *ActOnAliasDeclaration(Scope *CurScope,
AccessSpecifier AS,
MultiTemplateParamsArg TemplateParams,
@@ -4326,6 +4397,12 @@ public:
ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field);
+
+ /// Instantiate or parse a C++ default argument expression as necessary.
+ /// Return true on error.
+ bool CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
+ ParmVarDecl *Param);
+
/// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
/// the default expr if needed.
ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
@@ -4721,12 +4798,12 @@ public:
///
/// \param FunctionScopeIndexToStopAt If non-null, it points to the index
/// of the FunctionScopeInfo stack beyond which we do not attempt to capture.
- /// This is useful when enclosing lambdas must speculatively capture
+ /// This is useful when enclosing lambdas must speculatively capture
/// 'this' that may or may not be used in certain specializations of
- /// a nested generic lambda (depending on whether the name resolves to
+ /// a nested generic lambda (depending on whether the name resolves to
/// a non-static member function or a static function).
/// \return returns 'true' if failed, 'false' if success.
- bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false,
+ bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false,
bool BuildAndDiagnose = true,
const unsigned *const FunctionScopeIndexToStopAt = nullptr,
bool ByCopy = false);
@@ -4793,25 +4870,22 @@ public:
SourceRange R);
bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
bool UseGlobal, QualType AllocType, bool IsArray,
- MultiExprArg PlaceArgs,
+ bool &PassAlignment, MultiExprArg PlaceArgs,
FunctionDecl *&OperatorNew,
FunctionDecl *&OperatorDelete);
- bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
- DeclarationName Name, MultiExprArg Args,
- DeclContext *Ctx,
- bool AllowMissing, FunctionDecl *&Operator,
- bool Diagnose = true);
void DeclareGlobalNewDelete();
void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
- QualType Param1,
- QualType Param2 = QualType());
+ ArrayRef<QualType> Params);
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
DeclarationName Name, FunctionDecl* &Operator,
bool Diagnose = true);
FunctionDecl *FindUsualDeallocationFunction(SourceLocation StartLoc,
bool CanProvideSize,
+ bool Overaligned,
DeclarationName Name);
+ FunctionDecl *FindDeallocationFunctionForDestructor(SourceLocation StartLoc,
+ CXXRecordDecl *RD);
/// ActOnCXXDelete - Parsed a C++ 'delete' expression
ExprResult ActOnCXXDelete(SourceLocation StartLoc,
@@ -4949,16 +5023,41 @@ public:
bool *CanCorrect = nullptr);
NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
+ /// \brief Keeps information about an identifier in a nested-name-spec.
+ ///
+ struct NestedNameSpecInfo {
+ /// \brief The type of the object, if we're parsing nested-name-specifier in
+ /// a member access expression.
+ ParsedType ObjectType;
+
+ /// \brief The identifier preceding the '::'.
+ IdentifierInfo *Identifier;
+
+ /// \brief The location of the identifier.
+ SourceLocation IdentifierLoc;
+
+ /// \brief The location of the '::'.
+ SourceLocation CCLoc;
+
+ /// \brief Creates info object for the most typical case.
+ NestedNameSpecInfo(IdentifierInfo *II, SourceLocation IdLoc,
+ SourceLocation ColonColonLoc, ParsedType ObjectType = ParsedType())
+ : ObjectType(ObjectType), Identifier(II), IdentifierLoc(IdLoc),
+ CCLoc(ColonColonLoc) {
+ }
+
+ NestedNameSpecInfo(IdentifierInfo *II, SourceLocation IdLoc,
+ SourceLocation ColonColonLoc, QualType ObjectType)
+ : ObjectType(ParsedType::make(ObjectType)), Identifier(II),
+ IdentifierLoc(IdLoc), CCLoc(ColonColonLoc) {
+ }
+ };
+
bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
- SourceLocation IdLoc,
- IdentifierInfo &II,
- ParsedType ObjectType);
+ NestedNameSpecInfo &IdInfo);
bool BuildCXXNestedNameSpecifier(Scope *S,
- IdentifierInfo &Identifier,
- SourceLocation IdentifierLoc,
- SourceLocation CCLoc,
- QualType ObjectType,
+ NestedNameSpecInfo &IdInfo,
bool EnteringContext,
CXXScopeSpec &SS,
NamedDecl *ScopeLookupResult,
@@ -4969,14 +5068,8 @@ public:
///
/// \param S The scope in which this nested-name-specifier occurs.
///
- /// \param Identifier The identifier preceding the '::'.
- ///
- /// \param IdentifierLoc The location of the identifier.
- ///
- /// \param CCLoc The location of the '::'.
- ///
- /// \param ObjectType The type of the object, if we're parsing
- /// nested-name-specifier in a member access expression.
+ /// \param IdInfo Parser information about an identifier in the
+ /// nested-name-spec.
///
/// \param EnteringContext Whether we're entering the context nominated by
/// this nested-name-specifier.
@@ -4995,10 +5088,7 @@ public:
///
/// \returns true if an error occurred, false otherwise.
bool ActOnCXXNestedNameSpecifier(Scope *S,
- IdentifierInfo &Identifier,
- SourceLocation IdentifierLoc,
- SourceLocation CCLoc,
- ParsedType ObjectType,
+ NestedNameSpecInfo &IdInfo,
bool EnteringContext,
CXXScopeSpec &SS,
bool ErrorRecoveryLookup = false,
@@ -5011,10 +5101,7 @@ public:
SourceLocation ColonColonLoc);
bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
- IdentifierInfo &Identifier,
- SourceLocation IdentifierLoc,
- SourceLocation ColonLoc,
- ParsedType ObjectType,
+ NestedNameSpecInfo &IdInfo,
bool EnteringContext);
/// \brief The parser has parsed a nested-name-specifier
@@ -5106,7 +5193,7 @@ public:
/// \brief Create a new lambda closure type.
CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange,
TypeSourceInfo *Info,
- bool KnownDependent,
+ bool KnownDependent,
LambdaCaptureDefault CaptureDefault);
/// \brief Start the definition of a lambda expression.
@@ -5114,10 +5201,11 @@ public:
SourceRange IntroducerRange,
TypeSourceInfo *MethodType,
SourceLocation EndLoc,
- ArrayRef<ParmVarDecl *> Params);
+ ArrayRef<ParmVarDecl *> Params,
+ bool IsConstexprSpecified);
/// \brief Endow the lambda scope info with the relevant properties.
- void buildLambdaScope(sema::LambdaScopeInfo *LSI,
+ void buildLambdaScope(sema::LambdaScopeInfo *LSI,
CXXMethodDecl *CallOperator,
SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
@@ -5141,7 +5229,7 @@ public:
/// \brief Create a dummy variable within the declcontext of the lambda's
/// call operator, for name lookup purposes for a lambda init capture.
- ///
+ ///
/// CodeGen handles emission of lambda captures, ignoring these dummy
/// variables appropriately.
VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc,
@@ -5540,7 +5628,7 @@ 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);
@@ -5682,6 +5770,14 @@ public:
TemplateTy &SuggestedTemplate,
TemplateNameKind &SuggestedKind);
+ bool DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
+ NamedDecl *Instantiation,
+ bool InstantiatedFromMember,
+ const NamedDecl *Pattern,
+ const NamedDecl *PatternDef,
+ TemplateSpecializationKind TSK,
+ bool Complain = true);
+
void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
TemplateDecl *AdjustDeclIfTemplate(Decl *&Decl);
@@ -5694,7 +5790,10 @@ public:
SourceLocation EqualLoc,
ParsedType DefaultArg);
+ QualType CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI,
+ SourceLocation Loc);
QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc);
+
Decl *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
unsigned Depth,
unsigned Position,
@@ -5753,6 +5852,10 @@ public:
TemplateParameterList **OuterTemplateParamLists,
SkipBodyInfo *SkipBody = nullptr);
+ TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg,
+ QualType NTTPType,
+ SourceLocation Loc);
+
void translateTemplateArguments(const ASTTemplateArgsPtr &In,
TemplateArgumentListInfo &Out);
@@ -5827,6 +5930,15 @@ public:
MultiTemplateParamsArg TemplateParameterLists,
SkipBodyInfo *SkipBody = nullptr);
+ bool CheckTemplatePartialSpecializationArgs(SourceLocation Loc,
+ TemplateDecl *PrimaryTemplate,
+ unsigned NumExplicitArgs,
+ ArrayRef<TemplateArgument> Args);
+ void CheckTemplatePartialSpecialization(
+ ClassTemplatePartialSpecializationDecl *Partial);
+ void CheckTemplatePartialSpecialization(
+ VarTemplatePartialSpecializationDecl *Partial);
+
Decl *ActOnTemplateDeclarator(Scope *S,
MultiTemplateParamsArg TemplateParameterLists,
Declarator &D);
@@ -6253,9 +6365,9 @@ public:
/// \brief Collect the set of unexpanded parameter packs within the given
/// nested-name-specifier.
///
- /// \param SS The nested-name-specifier that will be traversed to find
+ /// \param NNS The nested-name-specifier that will be traversed to find
/// unexpanded parameter packs.
- void collectUnexpandedParameterPacks(CXXScopeSpec &SS,
+ void collectUnexpandedParameterPacks(NestedNameSpecifierLoc NNS,
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
/// \brief Collect the set of unexpanded parameter packs within the given
@@ -6399,11 +6511,24 @@ public:
SourceLocation &Ellipsis,
Optional<unsigned> &NumExpansions) const;
+ /// Given a template argument that contains an unexpanded parameter pack, but
+ /// which has already been substituted, attempt to determine the number of
+ /// elements that will be produced once this argument is fully-expanded.
+ ///
+ /// This is intended for use when transforming 'sizeof...(Arg)' in order to
+ /// avoid actually expanding the pack where possible.
+ Optional<unsigned> getFullyPackExpandedSize(TemplateArgument Arg);
+
//===--------------------------------------------------------------------===//
// C++ Template Argument Deduction (C++ [temp.deduct])
//===--------------------------------------------------------------------===//
- QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType);
+ /// Adjust the type \p ArgFunctionType to match the calling convention,
+ /// noreturn, and optionally the exception specification of \p FunctionType.
+ /// Deduction often wants to ignore these properties when matching function
+ /// types.
+ QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType,
+ bool AdjustExceptionSpec = false);
/// \brief Describes the result of template argument deduction.
///
@@ -6455,7 +6580,9 @@ public:
/// not be resolved to a suitable function.
TDK_FailedOverloadResolution,
/// \brief Deduction failed; that's all we know.
- TDK_MiscellaneousDeductionFailure
+ TDK_MiscellaneousDeductionFailure,
+ /// \brief CUDA Target attributes do not match.
+ TDK_CUDATargetMismatch
};
TemplateDeductionResult
@@ -6512,7 +6639,7 @@ public:
QualType ArgFunctionType,
FunctionDecl *&Specialization,
sema::TemplateDeductionInfo &Info,
- bool InOverloadResolution = false);
+ bool IsAddressOfFunction = false);
TemplateDeductionResult
DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
@@ -6525,12 +6652,12 @@ public:
TemplateArgumentListInfo *ExplicitTemplateArgs,
FunctionDecl *&Specialization,
sema::TemplateDeductionInfo &Info,
- bool InOverloadResolution = false);
+ bool IsAddressOfFunction = false);
/// \brief Substitute Replacement for \p auto in \p TypeWithAuto
QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement);
/// \brief Substitute Replacement for auto in TypeWithAuto
- TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
+ TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
QualType Replacement);
/// \brief Result type of DeduceAutoType.
@@ -6540,10 +6667,12 @@ public:
DAR_FailedAlreadyDiagnosed
};
- DeduceAutoResult DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer,
- QualType &Result);
- DeduceAutoResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer,
- QualType &Result);
+ DeduceAutoResult
+ DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, QualType &Result,
+ Optional<unsigned> DependentDeductionDepth = None);
+ DeduceAutoResult
+ DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result,
+ Optional<unsigned> DependentDeductionDepth = None);
void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init);
bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
bool Diagnose = true);
@@ -6580,10 +6709,19 @@ public:
ClassTemplatePartialSpecializationDecl *PS2,
SourceLocation Loc);
+ bool isMoreSpecializedThanPrimary(ClassTemplatePartialSpecializationDecl *T,
+ sema::TemplateDeductionInfo &Info);
+
VarTemplatePartialSpecializationDecl *getMoreSpecializedPartialSpecialization(
VarTemplatePartialSpecializationDecl *PS1,
VarTemplatePartialSpecializationDecl *PS2, SourceLocation Loc);
+ bool isMoreSpecializedThanPrimary(VarTemplatePartialSpecializationDecl *T,
+ sema::TemplateDeductionInfo &Info);
+
+ bool isTemplateTemplateParameterAtLeastAsSpecializedAs(
+ TemplateParameterList *P, TemplateDecl *AArg, SourceLocation Loc);
+
void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
bool OnlyDeduced,
unsigned Depth,
@@ -6634,8 +6772,8 @@ public:
/// We are substituting template argument determined as part of
/// template argument deduction for either a class template
/// partial specialization or a function template. The
- /// Entity is either a ClassTemplatePartialSpecializationDecl or
- /// a FunctionTemplateDecl.
+ /// Entity is either a {Class|Var}TemplatePartialSpecializationDecl or
+ /// a TemplateDecl.
DeducedTemplateArgumentSubstitution,
/// We are substituting prior template arguments into a new
@@ -6857,6 +6995,14 @@ public:
SourceRange InstantiationRange = SourceRange());
/// \brief Note that we are instantiating as part of template
+ /// argument deduction for a class template declaration.
+ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+ TemplateDecl *Template,
+ ArrayRef<TemplateArgument> TemplateArgs,
+ sema::TemplateDeductionInfo &DeductionInfo,
+ SourceRange InstantiationRange = SourceRange());
+
+ /// \brief Note that we are instantiating as part of template
/// argument deduction for a class template partial
/// specialization.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
@@ -7118,7 +7264,7 @@ public:
public:
/// Set the ExtParameterInfo for the parameter at the given index,
- ///
+ ///
void set(unsigned index, FunctionProtoType::ExtParameterInfo info) {
assert(Infos.size() <= index);
Infos.resize(index);
@@ -7357,7 +7503,7 @@ public:
const SourceLocation *ProtoLocs,
SourceLocation EndProtoLoc,
AttributeList *AttrList);
-
+
void ActOnSuperClassOfClassInterface(Scope *S,
SourceLocation AtInterfaceLoc,
ObjCInterfaceDecl *IDecl,
@@ -7367,8 +7513,9 @@ public:
SourceLocation SuperLoc,
ArrayRef<ParsedType> SuperTypeArgs,
SourceRange SuperTypeArgsRange);
-
+
void ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs,
+ SmallVectorImpl<SourceLocation> &ProtocolLocs,
IdentifierInfo *SuperName,
SourceLocation SuperLoc);
@@ -7475,6 +7622,14 @@ public:
ArrayRef<SourceLocation> ProtocolLocs,
SourceLocation ProtocolRAngleLoc);
+ /// Build an Objective-C type parameter type.
+ QualType BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
+ SourceLocation ProtocolLAngleLoc,
+ ArrayRef<ObjCProtocolDecl *> Protocols,
+ ArrayRef<SourceLocation> ProtocolLocs,
+ SourceLocation ProtocolRAngleLoc,
+ bool FailOnError = false);
+
/// Build an Objective-C object pointer type.
QualType BuildObjCObjectType(QualType BaseType,
SourceLocation Loc,
@@ -7685,14 +7840,14 @@ public:
ParsedType Type,
SourceLocation RParenLoc,
Expr *SubExpr);
-
+
void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr);
-
+
void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr);
-
+
bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,
CastKind &Kind);
-
+
bool checkObjCBridgeRelatedComponents(SourceLocation Loc,
QualType DestType, QualType SrcType,
ObjCInterfaceDecl *&RelatedClass,
@@ -7932,6 +8087,58 @@ public:
void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body);
//===--------------------------------------------------------------------===//
+ // OpenCL extensions.
+ //
+private:
+ std::string CurrOpenCLExtension;
+ /// Extensions required by an OpenCL type.
+ llvm::DenseMap<const Type*, std::set<std::string>> OpenCLTypeExtMap;
+ /// Extensions required by an OpenCL declaration.
+ llvm::DenseMap<const Decl*, std::set<std::string>> OpenCLDeclExtMap;
+public:
+ llvm::StringRef getCurrentOpenCLExtension() const {
+ return CurrOpenCLExtension;
+ }
+ void setCurrentOpenCLExtension(llvm::StringRef Ext) {
+ CurrOpenCLExtension = Ext;
+ }
+
+ /// \brief Set OpenCL extensions for a type which can only be used when these
+ /// OpenCL extensions are enabled. If \p Exts is empty, do nothing.
+ /// \param Exts A space separated list of OpenCL extensions.
+ void setOpenCLExtensionForType(QualType T, llvm::StringRef Exts);
+
+ /// \brief Set OpenCL extensions for a declaration which can only be
+ /// used when these OpenCL extensions are enabled. If \p Exts is empty, do
+ /// nothing.
+ /// \param Exts A space separated list of OpenCL extensions.
+ void setOpenCLExtensionForDecl(Decl *FD, llvm::StringRef Exts);
+
+ /// \brief Set current OpenCL extensions for a type which can only be used
+ /// when these OpenCL extensions are enabled. If current OpenCL extension is
+ /// empty, do nothing.
+ void setCurrentOpenCLExtensionForType(QualType T);
+
+ /// \brief Set current OpenCL extensions for a declaration which
+ /// can only be used when these OpenCL extensions are enabled. If current
+ /// OpenCL extension is empty, do nothing.
+ void setCurrentOpenCLExtensionForDecl(Decl *FD);
+
+ bool isOpenCLDisabledDecl(Decl *FD);
+
+ /// \brief Check if type \p T corresponding to declaration specifier \p DS
+ /// is disabled due to required OpenCL extensions being disabled. If so,
+ /// emit diagnostics.
+ /// \return true if type is disabled.
+ bool checkOpenCLDisabledTypeDeclSpec(const DeclSpec &DS, QualType T);
+
+ /// \brief Check if declaration \p D used by expression \p E
+ /// is disabled due to required OpenCL extensions being disabled. If so,
+ /// emit diagnostics.
+ /// \return true if type is disabled.
+ bool checkOpenCLDisabledDecl(const Decl &D, const Expr &E);
+
+ //===--------------------------------------------------------------------===//
// OpenMP directives and clauses.
//
private:
@@ -7947,6 +8154,21 @@ private:
/// Returns OpenMP nesting level for current directive.
unsigned getOpenMPNestingLevel() const;
+ /// Checks if a type or a declaration is disabled due to the owning extension
+ /// being disabled, and emits diagnostic messages if it is disabled.
+ /// \param D type or declaration to be checked.
+ /// \param DiagLoc source location for the diagnostic message.
+ /// \param DiagInfo information to be emitted for the diagnostic message.
+ /// \param SrcRange source range of the declaration.
+ /// \param Map maps type or declaration to the extensions.
+ /// \param Selector selects diagnostic message: 0 for type and 1 for
+ /// declaration.
+ /// \return true if the type or declaration is disabled.
+ template <typename T, typename DiagLocT, typename DiagInfoT, typename MapT>
+ bool checkOpenCLDisabledTypeOrDecl(T D, DiagLocT DiagLoc, DiagInfoT DiagInfo,
+ MapT &Map, unsigned Selector = 0,
+ SourceRange SrcRange = SourceRange());
+
public:
/// \brief Return true if the provided declaration \a VD should be captured by
/// reference.
@@ -8244,6 +8466,54 @@ public:
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc,
llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ /// \brief Called on well-formed '\#pragma omp target simd' after parsing of
+ /// the associated statement.
+ StmtResult ActOnOpenMPTargetSimdDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp teams distribute' after parsing of
+ /// the associated statement.
+ StmtResult ActOnOpenMPTeamsDistributeDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp teams distribute simd' after parsing
+ /// of the associated statement.
+ StmtResult ActOnOpenMPTeamsDistributeSimdDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp teams distribute parallel for simd'
+ /// after parsing of the associated statement.
+ StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp teams distribute parallel for'
+ /// after parsing of the associated statement.
+ StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp target teams' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// Called on well-formed '\#pragma omp target teams distribute' after parsing
+ /// of the associated statement.
+ StmtResult ActOnOpenMPTargetTeamsDistributeDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp target teams distribute parallel for'
+ /// after parsing of the associated statement.
+ StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
/// Checks correctness of linear modifiers.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
@@ -8565,6 +8835,11 @@ public:
// argument, and arguments that have type float are promoted to double.
ExprResult DefaultArgumentPromotion(Expr *E);
+ /// If \p E is a prvalue denoting an unmaterialized temporary, materialize
+ /// it as an xvalue. In C++98, the result will still be a prvalue, because
+ /// we don't have xvalues there.
+ ExprResult TemporaryMaterializationConversion(Expr *E);
+
// Used for emitting the right warning by DefaultVariadicArgumentPromotion
enum VariadicCallType {
VariadicFunction,
@@ -8646,8 +8921,8 @@ public:
/// are not compatible, but we accept them as an extension.
IncompatiblePointer,
- /// IncompatiblePointer - The assignment is between two pointers types which
- /// point to integers which have a different sign, but are otherwise
+ /// IncompatiblePointerSign - The assignment is between two pointers types
+ /// which point to integers which have a different sign, but are otherwise
/// identical. This is a subset of the above, but broken out because it's by
/// far the most common case of incompatible pointers.
IncompatiblePointerSign,
@@ -8728,15 +9003,23 @@ public:
CastKind &Kind,
bool ConvertRHS = true);
- // CheckSingleAssignmentConstraints - Currently used by
- // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking,
- // this routine performs the default function/array converions, if ConvertRHS
- // is true.
- AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType,
- ExprResult &RHS,
- bool Diagnose = true,
- bool DiagnoseCFAudited = false,
- bool ConvertRHS = true);
+ /// Check assignment constraints for an assignment of RHS to LHSType.
+ ///
+ /// \param LHSType The destination type for the assignment.
+ /// \param RHS The source expression for the assignment.
+ /// \param Diagnose If \c true, diagnostics may be produced when checking
+ /// for assignability. If a diagnostic is produced, \p RHS will be
+ /// set to ExprError(). Note that this function may still return
+ /// without producing a diagnostic, even for an invalid assignment.
+ /// \param DiagnoseCFAudited If \c true, the target is a function parameter
+ /// in an audited Core Foundation API and does not need to be checked
+ /// for ARC retain issues.
+ /// \param ConvertRHS If \c true, \p RHS will be updated to model the
+ /// conversions necessary to perform the assignment. If \c false,
+ /// \p Diagnose must also be \c false.
+ AssignConvertType CheckSingleAssignmentConstraints(
+ QualType LHSType, ExprResult &RHS, bool Diagnose = true,
+ bool DiagnoseCFAudited = false, bool ConvertRHS = true);
// \brief If the lhs type is a transparent union, check whether we
// can initialize the transparent union with the given expression.
@@ -8792,8 +9075,8 @@ public:
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
BinaryOperatorKind Opc, bool isRelational);
QualType CheckBitwiseOperands( // C99 6.5.[10...12]
- ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
- bool IsCompAssign = false);
+ ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
+ BinaryOperatorKind Opc);
QualType CheckLogicalOperands( // C99 6.5.[13,14]
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
BinaryOperatorKind Opc);
@@ -8818,13 +9101,13 @@ public:
ExprResult &cond, ExprResult &lhs, ExprResult &rhs,
ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc);
QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
- bool *NonStandardCompositeType = nullptr);
+ bool ConvertArgs = true);
QualType FindCompositePointerType(SourceLocation Loc,
ExprResult &E1, ExprResult &E2,
- bool *NonStandardCompositeType = nullptr) {
+ bool ConvertArgs = true) {
Expr *E1Tmp = E1.get(), *E2Tmp = E2.get();
- QualType Composite = FindCompositePointerType(Loc, E1Tmp, E2Tmp,
- NonStandardCompositeType);
+ QualType Composite =
+ FindCompositePointerType(Loc, E1Tmp, E2Tmp, ConvertArgs);
E1 = E1Tmp;
E2 = E2Tmp;
return Composite;
@@ -8869,13 +9152,7 @@ public:
/// that their unqualified forms (T1 and T2) are either the same
/// or T1 is a base class of T2.
Ref_Related,
- /// Ref_Compatible_With_Added_Qualification - The two types are
- /// reference-compatible with added qualification, meaning that
- /// they are reference-compatible and the qualifiers on T1 (cv1)
- /// are greater than the qualifiers on T2 (cv2).
- Ref_Compatible_With_Added_Qualification,
- /// Ref_Compatible - The two types are reference-compatible and
- /// have equivalent qualifiers (cv1 == cv2).
+ /// Ref_Compatible - The two types are reference-compatible.
Ref_Compatible
};
@@ -9104,6 +9381,154 @@ public:
QualType FieldTy, bool IsMsStruct,
Expr *BitWidth, bool *ZeroWidth = nullptr);
+private:
+ unsigned ForceCUDAHostDeviceDepth = 0;
+
+public:
+ /// Increments our count of the number of times we've seen a pragma forcing
+ /// functions to be __host__ __device__. So long as this count is greater
+ /// than zero, all functions encountered will be __host__ __device__.
+ void PushForceCUDAHostDevice();
+
+ /// Decrements our count of the number of times we've seen a pragma forcing
+ /// functions to be __host__ __device__. Returns false if the count is 0
+ /// before incrementing, so you can emit an error.
+ bool PopForceCUDAHostDevice();
+
+ /// Diagnostics that are emitted only if we discover that the given function
+ /// must be codegen'ed. Because handling these correctly adds overhead to
+ /// compilation, this is currently only enabled for CUDA compilations.
+ llvm::DenseMap<CanonicalDeclPtr<FunctionDecl>,
+ std::vector<PartialDiagnosticAt>>
+ CUDADeferredDiags;
+
+ /// A pair of a canonical FunctionDecl and a SourceLocation. When used as the
+ /// key in a hashtable, both the FD and location are hashed.
+ struct FunctionDeclAndLoc {
+ CanonicalDeclPtr<FunctionDecl> FD;
+ SourceLocation Loc;
+ };
+
+ /// FunctionDecls and SourceLocations for which CheckCUDACall has emitted a
+ /// (maybe deferred) "bad call" diagnostic. We use this to avoid emitting the
+ /// same deferred diag twice.
+ llvm::DenseSet<FunctionDeclAndLoc> LocsWithCUDACallDiags;
+
+ /// An inverse call graph, mapping known-emitted functions to one of their
+ /// known-emitted callers (plus the location of the call).
+ ///
+ /// Functions that we can tell a priori must be emitted aren't added to this
+ /// map.
+ llvm::DenseMap</* Callee = */ CanonicalDeclPtr<FunctionDecl>,
+ /* Caller = */ FunctionDeclAndLoc>
+ CUDAKnownEmittedFns;
+
+ /// A partial call graph maintained during CUDA compilation to support
+ /// deferred diagnostics.
+ ///
+ /// Functions are only added here if, at the time they're considered, they are
+ /// not known-emitted. As soon as we discover that a function is
+ /// known-emitted, we remove it and everything it transitively calls from this
+ /// set and add those functions to CUDAKnownEmittedFns.
+ llvm::DenseMap</* Caller = */ CanonicalDeclPtr<FunctionDecl>,
+ /* Callees = */ llvm::MapVector<CanonicalDeclPtr<FunctionDecl>,
+ SourceLocation>>
+ CUDACallGraph;
+
+ /// Diagnostic builder for CUDA errors which may or may not be deferred.
+ ///
+ /// In CUDA, there exist constructs (e.g. variable-length arrays, try/catch)
+ /// which are not allowed to appear inside __device__ functions and are
+ /// allowed to appear in __host__ __device__ functions only if the host+device
+ /// function is never codegen'ed.
+ ///
+ /// To handle this, we use the notion of "deferred diagnostics", where we
+ /// attach a diagnostic to a FunctionDecl that's emitted iff it's codegen'ed.
+ ///
+ /// This class lets you emit either a regular diagnostic, a deferred
+ /// diagnostic, or no diagnostic at all, according to an argument you pass to
+ /// its constructor, thus simplifying the process of creating these "maybe
+ /// deferred" diagnostics.
+ class CUDADiagBuilder {
+ public:
+ enum Kind {
+ /// Emit no diagnostics.
+ K_Nop,
+ /// Emit the diagnostic immediately (i.e., behave like Sema::Diag()).
+ K_Immediate,
+ /// Emit the diagnostic immediately, and, if it's a warning or error, also
+ /// emit a call stack showing how this function can be reached by an a
+ /// priori known-emitted function.
+ K_ImmediateWithCallStack,
+ /// Create a deferred diagnostic, which is emitted only if the function
+ /// it's attached to is codegen'ed. Also emit a call stack as with
+ /// K_ImmediateWithCallStack.
+ K_Deferred
+ };
+
+ CUDADiagBuilder(Kind K, SourceLocation Loc, unsigned DiagID,
+ FunctionDecl *Fn, Sema &S);
+ ~CUDADiagBuilder();
+
+ /// Convertible to bool: True if we immediately emitted an error, false if
+ /// we didn't emit an error or we created a deferred error.
+ ///
+ /// Example usage:
+ ///
+ /// if (CUDADiagBuilder(...) << foo << bar)
+ /// return ExprError();
+ ///
+ /// But see CUDADiagIfDeviceCode() and CUDADiagIfHostCode() -- you probably
+ /// want to use these instead of creating a CUDADiagBuilder yourself.
+ operator bool() const { return ImmediateDiag.hasValue(); }
+
+ template <typename T>
+ friend const CUDADiagBuilder &operator<<(const CUDADiagBuilder &Diag,
+ const T &Value) {
+ if (Diag.ImmediateDiag.hasValue())
+ *Diag.ImmediateDiag << Value;
+ else if (Diag.PartialDiag.hasValue())
+ *Diag.PartialDiag << Value;
+ return Diag;
+ }
+
+ private:
+ Sema &S;
+ SourceLocation Loc;
+ unsigned DiagID;
+ FunctionDecl *Fn;
+ bool ShowCallStack;
+
+ // Invariant: At most one of these Optionals has a value.
+ // FIXME: Switch these to a Variant once that exists.
+ llvm::Optional<SemaDiagnosticBuilder> ImmediateDiag;
+ llvm::Optional<PartialDiagnostic> PartialDiag;
+ };
+
+ /// Creates a CUDADiagBuilder that emits the diagnostic if the current context
+ /// is "used as device code".
+ ///
+ /// - If CurContext is a __host__ function, does not emit any diagnostics.
+ /// - If CurContext is a __device__ or __global__ function, emits the
+ /// diagnostics immediately.
+ /// - If CurContext is a __host__ __device__ function and we are compiling for
+ /// the device, creates a diagnostic which is emitted if and when we realize
+ /// that the function will be codegen'ed.
+ ///
+ /// Example usage:
+ ///
+ /// // Variable-length arrays are not allowed in CUDA device code.
+ /// if (CUDADiagIfDeviceCode(Loc, diag::err_cuda_vla) << CurrentCUDATarget())
+ /// return ExprError();
+ /// // Otherwise, continue parsing as normal.
+ CUDADiagBuilder CUDADiagIfDeviceCode(SourceLocation Loc, unsigned DiagID);
+
+ /// Creates a CUDADiagBuilder that emits the diagnostic if the current context
+ /// is "used as host code".
+ ///
+ /// Same as CUDADiagIfDeviceCode, with "host" and "device" switched.
+ CUDADiagBuilder CUDADiagIfHostCode(SourceLocation Loc, unsigned DiagID);
+
enum CUDAFunctionTarget {
CFT_Device,
CFT_Global,
@@ -9112,7 +9537,19 @@ public:
CFT_InvalidTarget
};
- CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D);
+ /// Determines whether the given function is a CUDA device/host/kernel/etc.
+ /// function.
+ ///
+ /// Use this rather than examining the function's attributes yourself -- you
+ /// will get it wrong. Returns CFT_Host if D is null.
+ CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D,
+ bool IgnoreImplicitHDAttr = false);
+ CUDAFunctionTarget IdentifyCUDATarget(const AttributeList *Attr);
+
+ /// Gets the CUDA target for the current context.
+ CUDAFunctionTarget CurrentCUDATarget() {
+ return IdentifyCUDATarget(dyn_cast<FunctionDecl>(CurContext));
+ }
// CUDA function call preference. Must be ordered numerically from
// worst to best.
@@ -9120,8 +9557,7 @@ public:
CFP_Never, // Invalid caller/callee combination.
CFP_WrongSide, // Calls from host-device to host or device
// function that do not match current compilation
- // mode. Only in effect if
- // LangOpts.CUDADisableTargetCallChecks is true.
+ // mode.
CFP_HostDevice, // Any calls to host/device functions.
CFP_SameSide, // Calls from host-device to host or device
// function matching current compilation mode.
@@ -9139,23 +9575,48 @@ public:
const FunctionDecl *Callee);
/// Determines whether Caller may invoke Callee, based on their CUDA
- /// host/device attributes. Returns true if the call is not allowed.
- bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee) {
- return IdentifyCUDAPreference(Caller, Callee) == CFP_Never;
+ /// host/device attributes. Returns false if the call is not allowed.
+ ///
+ /// Note: Will return true for CFP_WrongSide calls. These may appear in
+ /// semantically correct CUDA programs, but only if they're never codegen'ed.
+ bool IsAllowedCUDACall(const FunctionDecl *Caller,
+ const FunctionDecl *Callee) {
+ return IdentifyCUDAPreference(Caller, Callee) != CFP_Never;
}
/// May add implicit CUDAHostAttr and CUDADeviceAttr attributes to FD,
/// depending on FD and the current compilation settings.
- void maybeAddCUDAHostDeviceAttrs(Scope *S, FunctionDecl *FD,
+ void maybeAddCUDAHostDeviceAttrs(FunctionDecl *FD,
const LookupResult &Previous);
+public:
+ /// Check whether we're allowed to call Callee from the current context.
+ ///
+ /// - If the call is never allowed in a semantically-correct program
+ /// (CFP_Never), emits an error and returns false.
+ ///
+ /// - If the call is allowed in semantically-correct programs, but only if
+ /// it's never codegen'ed (CFP_WrongSide), creates a deferred diagnostic to
+ /// be emitted if and when the caller is codegen'ed, and returns true.
+ ///
+ /// Will only create deferred diagnostics for a given SourceLocation once,
+ /// so you can safely call this multiple times without generating duplicate
+ /// deferred errors.
+ ///
+ /// - Otherwise, returns true without emitting any diagnostics.
+ bool CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee);
+
+ /// Set __device__ or __host__ __device__ attributes on the given lambda
+ /// operator() method.
+ ///
+ /// CUDA lambdas declared inside __device__ or __global__ functions inherit
+ /// the __device__ attribute. Similarly, lambdas inside __host__ __device__
+ /// functions become __host__ __device__ themselves.
+ void CUDASetLambdaAttrs(CXXMethodDecl *Method);
+
/// Finds a function in \p Matches with highest calling priority
/// from \p Caller context and erases all functions with lower
/// calling priority.
- void EraseUnwantedCUDAMatches(const FunctionDecl *Caller,
- SmallVectorImpl<FunctionDecl *> &Matches);
- void EraseUnwantedCUDAMatches(const FunctionDecl *Caller,
- SmallVectorImpl<DeclAccessPair> &Matches);
void EraseUnwantedCUDAMatches(
const FunctionDecl *Caller,
SmallVectorImpl<std::pair<DeclAccessPair, FunctionDecl *>> &Matches);
@@ -9182,6 +9643,13 @@ public:
bool isEmptyCudaConstructor(SourceLocation Loc, CXXConstructorDecl *CD);
bool isEmptyCudaDestructor(SourceLocation Loc, CXXDestructorDecl *CD);
+ /// Check whether NewFD is a valid overload for CUDA. Emits
+ /// diagnostics and invalidates NewFD if not.
+ void checkCUDATargetOverload(FunctionDecl *NewFD,
+ const LookupResult &Previous);
+ /// Copies target attributes from the template TD to the function FD.
+ void inheritCUDATargetAttrs(FunctionDecl *FD, const FunctionTemplateDecl &TD);
+
/// \name Code completion
//@{
/// \brief Describes the context in which code completion occurs.
@@ -9241,8 +9709,8 @@ public:
void CodeCompleteExpression(Scope *S,
const CodeCompleteExpressionData &Data);
void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
- SourceLocation OpLoc,
- bool IsArrow);
+ SourceLocation OpLoc, bool IsArrow,
+ bool IsBaseExprStatement);
void CodeCompletePostfixExpression(Scope *S, ExprResult LHS);
void CodeCompleteTag(Scope *S, unsigned TagSpec);
void CodeCompleteTypeQualifiers(DeclSpec &DS);
@@ -9320,6 +9788,9 @@ public:
bool AtParameterName,
ParsedType ReturnType,
ArrayRef<IdentifierInfo *> SelIdents);
+ void CodeCompleteObjCClassPropertyRefExpr(Scope *S, IdentifierInfo &ClassName,
+ SourceLocation ClassNameLoc,
+ bool IsBaseExprStatement);
void CodeCompletePreprocessorDirective(bool InConditional);
void CodeCompleteInPreprocessorConditionalExclusion(Scope *S);
void CodeCompletePreprocessorMacroName(bool IsDefinition);
@@ -9369,11 +9840,12 @@ private:
SourceLocation Loc);
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
- ArrayRef<const Expr *> Args, bool IsMemberFunction,
- SourceLocation Loc, SourceRange Range,
+ ArrayRef<const Expr *> Args, bool IsMemberFunction,
+ SourceLocation Loc, SourceRange Range,
VariadicCallType CallType);
bool CheckObjCString(Expr *Arg);
+ ExprResult CheckOSLogFormatStringArg(Expr *Arg);
ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl,
unsigned BuiltinID, CallExpr *TheCall);
@@ -9386,6 +9858,7 @@ private:
bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+ bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall);
bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
@@ -9395,6 +9868,7 @@ private:
bool SemaBuiltinVAStartARM(CallExpr *Call);
bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
+ bool SemaBuiltinOSLogFormat(CallExpr *TheCall);
public:
// Used by C++ template instantiation.
@@ -9405,6 +9879,7 @@ public:
private:
bool SemaBuiltinPrefetch(CallExpr *TheCall);
+ bool SemaBuiltinAllocaWithAlign(CallExpr *TheCall);
bool SemaBuiltinAssume(CallExpr *TheCall);
bool SemaBuiltinAssumeAligned(CallExpr *TheCall);
bool SemaBuiltinLongjmp(CallExpr *TheCall);
@@ -9432,12 +9907,13 @@ public:
FST_Kprintf,
FST_FreeBSDKPrintf,
FST_OSTrace,
+ FST_OSLog,
FST_Unknown
};
static FormatStringType GetFormatStringType(const FormatAttr *Format);
bool FormatStringHasSArg(const StringLiteral *FExpr);
-
+
static bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx);
private:
@@ -9455,8 +9931,9 @@ private:
llvm::SmallBitVector &CheckedVarArgs);
void CheckAbsoluteValueFunction(const CallExpr *Call,
- const FunctionDecl *FDecl,
- IdentifierInfo *FnInfo);
+ const FunctionDecl *FDecl);
+
+ void CheckMaxUnsignedZero(const CallExpr *Call, const FunctionDecl *FDecl);
void CheckMemaccessArguments(const CallExpr *Call,
unsigned BId,
@@ -9535,6 +10012,10 @@ private:
void CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr,
const Expr * const *ExprArgs);
+ /// \brief Check if we are taking the address of a packed field
+ /// as this may be a problem if the pointer value is dereferenced.
+ void CheckAddressOfPackedMember(Expr *rhs);
+
/// \brief The parser's current scope.
///
/// The parser maintains this state here.
@@ -9590,8 +10071,17 @@ public:
return OriginalLexicalContext ? OriginalLexicalContext : CurContext;
}
- AvailabilityResult getCurContextAvailability() const;
-
+ /// \brief The diagnostic we should emit for \c D, or \c AR_Available.
+ ///
+ /// \param D The declaration to check. Note that this may be altered to point
+ /// to another declaration that \c D gets it's availability from. i.e., we
+ /// walk the list of typedefs to find an availability attribute.
+ ///
+ /// \param Message If non-null, this will be populated with the message from
+ /// the availability attribute that is selected.
+ AvailabilityResult ShouldDiagnoseAvailabilityOfDecl(NamedDecl *&D,
+ std::string *Message);
+
const DeclContext *getCurObjCLexicalContext() const {
const DeclContext *DC = getCurLexicalContext();
// A category implicitly has the attribute of the interface.
@@ -9613,6 +10103,53 @@ public:
// Emitting members of dllexported classes is delayed until the class
// (including field initializers) is fully parsed.
SmallVector<CXXRecordDecl*, 4> DelayedDllExportClasses;
+
+private:
+ /// \brief Helper class that collects misaligned member designations and
+ /// their location info for delayed diagnostics.
+ struct MisalignedMember {
+ Expr *E;
+ RecordDecl *RD;
+ ValueDecl *MD;
+ CharUnits Alignment;
+
+ MisalignedMember() : E(), RD(), MD(), Alignment() {}
+ MisalignedMember(Expr *E, RecordDecl *RD, ValueDecl *MD,
+ CharUnits Alignment)
+ : E(E), RD(RD), MD(MD), Alignment(Alignment) {}
+ explicit MisalignedMember(Expr *E)
+ : MisalignedMember(E, nullptr, nullptr, CharUnits()) {}
+
+ bool operator==(const MisalignedMember &m) { return this->E == m.E; }
+ };
+ /// \brief Small set of gathered accesses to potentially misaligned members
+ /// due to the packed attribute.
+ SmallVector<MisalignedMember, 4> MisalignedMembers;
+
+ /// \brief Adds an expression to the set of gathered misaligned members.
+ void AddPotentialMisalignedMembers(Expr *E, RecordDecl *RD, ValueDecl *MD,
+ CharUnits Alignment);
+
+public:
+ /// \brief Diagnoses the current set of gathered accesses. This typically
+ /// happens at full expression level. The set is cleared after emitting the
+ /// diagnostics.
+ void DiagnoseMisalignedMembers();
+
+ /// \brief This function checks if the expression is in the sef of potentially
+ /// misaligned members and it is converted to some pointer type T with lower
+ /// or equal alignment requirements. If so it removes it. This is used when
+ /// we do not want to diagnose such misaligned access (e.g. in conversions to
+ /// void*).
+ void DiscardMisalignedMemberAddress(const Type *T, Expr *E);
+
+ /// \brief This function calls Action when it determines that E designates a
+ /// misaligned member due to the packed attribute. This is used to emit
+ /// local diagnostics like in reference binding.
+ void RefersToMemberWithReducedAlignment(
+ Expr *E,
+ llvm::function_ref<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)>
+ Action);
};
/// \brief RAII object that enters a new expression evaluation context.
@@ -9636,7 +10173,7 @@ public:
Sema::ReuseLambdaContextDecl_t,
bool IsDecltype = false)
: Actions(Actions) {
- Actions.PushExpressionEvaluationContext(NewContext,
+ Actions.PushExpressionEvaluationContext(NewContext,
Sema::ReuseLambdaContextDecl,
IsDecltype);
}
@@ -9661,4 +10198,31 @@ struct LateParsedTemplate {
} // end namespace clang
+namespace llvm {
+// Hash a FunctionDeclAndLoc by looking at both its FunctionDecl and its
+// SourceLocation.
+template <> struct DenseMapInfo<clang::Sema::FunctionDeclAndLoc> {
+ using FunctionDeclAndLoc = clang::Sema::FunctionDeclAndLoc;
+ using FDBaseInfo = DenseMapInfo<clang::CanonicalDeclPtr<clang::FunctionDecl>>;
+
+ static FunctionDeclAndLoc getEmptyKey() {
+ return {FDBaseInfo::getEmptyKey(), clang::SourceLocation()};
+ }
+
+ static FunctionDeclAndLoc getTombstoneKey() {
+ return {FDBaseInfo::getTombstoneKey(), clang::SourceLocation()};
+ }
+
+ static unsigned getHashValue(const FunctionDeclAndLoc &FDL) {
+ return hash_combine(FDBaseInfo::getHashValue(FDL.FD),
+ FDL.Loc.getRawEncoding());
+ }
+
+ static bool isEqual(const FunctionDeclAndLoc &LHS,
+ const FunctionDeclAndLoc &RHS) {
+ return LHS.FD == RHS.FD && LHS.Loc == RHS.Loc;
+ }
+};
+} // namespace llvm
+
#endif
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
index 76567f3b77f4..a01e8d639f60 100644
--- a/include/clang/Sema/SemaInternal.h
+++ b/include/clang/Sema/SemaInternal.h
@@ -333,12 +333,12 @@ private:
inline Sema::TypoExprState::TypoExprState() {}
-inline Sema::TypoExprState::TypoExprState(TypoExprState &&other) LLVM_NOEXCEPT {
+inline Sema::TypoExprState::TypoExprState(TypoExprState &&other) noexcept {
*this = std::move(other);
}
-inline Sema::TypoExprState &Sema::TypoExprState::operator=(
- Sema::TypoExprState &&other) LLVM_NOEXCEPT {
+inline Sema::TypoExprState &Sema::TypoExprState::
+operator=(Sema::TypoExprState &&other) noexcept {
Consumer = std::move(other.Consumer);
DiagHandler = std::move(other.DiagHandler);
RecoveryHandler = std::move(other.RecoveryHandler);
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
index c0926304cf43..401bbbf1e566 100644
--- a/include/clang/Sema/Template.h
+++ b/include/clang/Sema/Template.h
@@ -410,6 +410,7 @@ namespace clang {
#define OBJCCONTAINER(DERIVED, BASE)
#define FILESCOPEASM(DERIVED, BASE)
#define IMPORT(DERIVED, BASE)
+#define EXPORT(DERIVED, BASE)
#define LINKAGESPEC(DERIVED, BASE)
#define OBJCCOMPATIBLEALIAS(DERIVED, BASE)
#define OBJCMETHOD(DERIVED, BASE)
@@ -433,7 +434,8 @@ namespace clang {
Decl *VisitFunctionDecl(FunctionDecl *D,
TemplateParameterList *TemplateParams);
Decl *VisitDecl(Decl *D);
- Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate);
+ Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate,
+ ArrayRef<BindingDecl *> *Bindings = nullptr);
// Enable late instantiation of attributes. Late instantiated attributes
// will be stored in LA.
@@ -513,6 +515,11 @@ namespace clang {
VarTemplateDecl *VarTemplate,
VarTemplatePartialSpecializationDecl *PartialSpec);
void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern);
+
+ private:
+ template<typename T>
+ Decl *instantiateUnresolvedUsingDecl(T *D,
+ bool InstantiatingPackElement = false);
};
}
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
index ed1e768832cc..f4a706ecb9ab 100644
--- a/include/clang/Sema/TemplateDeduction.h
+++ b/include/clang/Sema/TemplateDeduction.h
@@ -40,6 +40,9 @@ class TemplateDeductionInfo {
/// \brief Have we suppressed an error during deduction?
bool HasSFINAEDiagnostic;
+ /// \brief The template parameter depth for which we're performing deduction.
+ unsigned DeducedDepth;
+
/// \brief Warnings (and follow-on notes) that were suppressed due to
/// SFINAE while performing template argument deduction.
SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
@@ -48,9 +51,9 @@ class TemplateDeductionInfo {
void operator=(const TemplateDeductionInfo &) = delete;
public:
- TemplateDeductionInfo(SourceLocation Loc)
+ TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0)
: Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
- Expression(nullptr) {}
+ DeducedDepth(DeducedDepth), Expression(nullptr) {}
/// \brief Returns the location at which template argument is
/// occurring.
@@ -58,6 +61,12 @@ public:
return Loc;
}
+ /// \brief The depth of template parameters for which deduction is being
+ /// performed.
+ unsigned getDeducedDepth() const {
+ return DeducedDepth;
+ }
+
/// \brief Take ownership of the deduced template argument list.
TemplateArgumentList *take() {
TemplateArgumentList *Result = Deduced;
@@ -70,6 +79,11 @@ public:
assert(HasSFINAEDiagnostic);
PD.first = SuppressedDiagnostics.front().first;
PD.second.swap(SuppressedDiagnostics.front().second);
+ clearSFINAEDiagnostic();
+ }
+
+ /// \brief Discard any SFINAE diagnostics.
+ void clearSFINAEDiagnostic() {
SuppressedDiagnostics.clear();
HasSFINAEDiagnostic = false;
}
@@ -199,10 +213,7 @@ struct DeductionFailureInfo {
void *Data;
/// \brief A diagnostic indicating why deduction failed.
- union {
- void *Align;
- char Diagnostic[sizeof(PartialDiagnosticAt)];
- };
+ alignas(PartialDiagnosticAt) char Diagnostic[sizeof(PartialDiagnosticAt)];
/// \brief Retrieve the diagnostic which caused this deduction failure,
/// if any.
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
index 3b0385ef2a9d..5bebe52325c6 100644
--- a/include/clang/Sema/TypoCorrection.h
+++ b/include/clang/Sema/TypoCorrection.h
@@ -230,6 +230,15 @@ public:
bool requiresImport() const { return RequiresImport; }
void setRequiresImport(bool Req) { RequiresImport = Req; }
+ /// Extra diagnostics are printed after the first diagnostic for the typo.
+ /// This can be used to attach external notes to the diag.
+ void addExtraDiagnostic(PartialDiagnostic PD) {
+ ExtraDiagnostics.push_back(std::move(PD));
+ }
+ ArrayRef<PartialDiagnostic> getExtraDiagnostics() const {
+ return ExtraDiagnostics;
+ }
+
private:
bool hasCorrectionDecl() const {
return (!isKeyword() && !CorrectionDecls.empty());
@@ -245,6 +254,8 @@ private:
SourceRange CorrectionRange;
bool ForceSpecifierReplacement;
bool RequiresImport;
+
+ std::vector<PartialDiagnostic> ExtraDiagnostics;
};
/// @brief Base class for callback objects used by Sema::CorrectTypo to check
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 79c6a0622257..861fe64096af 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -344,7 +344,7 @@ namespace clang {
///
/// The TYPE_OFFSET constant describes the record that occurs
/// within the AST block. The record itself is an array of offsets that
- /// point into the declarations and types block (identified by
+ /// point into the declarations and types block (identified by
/// DECLTYPES_BLOCK_ID). The index into the array is based on the ID
/// of a type. For a given type ID @c T, the lower three bits of
/// @c T are its qualifiers (const, volatile, restrict), as in
@@ -446,10 +446,10 @@ namespace clang {
/// \brief Record code for the set of ext_vector type names.
EXT_VECTOR_DECLS = 16,
-
+
/// \brief Record code for the array of unused file scoped decls.
UNUSED_FILESCOPED_DECLS = 17,
-
+
/// \brief Record code for the table of offsets to entries in the
/// preprocessing record.
PPD_ENTITIES_OFFSETS = 18,
@@ -465,7 +465,7 @@ namespace clang {
/// \brief Record code for an update to the TU's lexically contained
/// declarations.
TU_UPDATE_LEXICAL = 22,
-
+
// ID 23 used to be for a list of local redeclarations.
/// \brief Record code for declarations that Sema keeps references of.
@@ -490,7 +490,7 @@ namespace clang {
// ID 30 used to be a decl update record. These are now in the DECLTYPES
// block.
-
+
// ID 31 used to be a list of offsets to DECL_CXX_BASE_SPECIFIERS records.
/// \brief Record code for \#pragma diagnostic mappings.
@@ -498,7 +498,7 @@ namespace clang {
/// \brief Record code for special CUDA declarations.
CUDA_SPECIAL_DECL_REFS = 33,
-
+
/// \brief Record code for header search information.
HEADER_SEARCH_TABLE = 34,
@@ -516,7 +516,7 @@ namespace clang {
KNOWN_NAMESPACES = 38,
/// \brief Record code for the remapping information used to relate
- /// loaded modules to the various offsets and IDs(e.g., source location
+ /// loaded modules to the various offsets and IDs(e.g., source location
/// offests, declaration and type IDs) that are used in that module to
/// refer to other modules.
MODULE_OFFSET_MAP = 39,
@@ -525,20 +525,20 @@ namespace clang {
/// which stores information about \#line directives.
SOURCE_MANAGER_LINE_TABLE = 40,
- /// \brief Record code for map of Objective-C class definition IDs to the
+ /// \brief Record code for map of Objective-C class definition IDs to the
/// ObjC categories in a module that are attached to that class.
OBJC_CATEGORIES_MAP = 41,
/// \brief Record code for a file sorted array of DeclIDs in a module.
FILE_SORTED_DECLS = 42,
-
+
/// \brief Record code for an array of all of the (sub)modules that were
/// imported by the AST file.
IMPORTED_MODULES = 43,
-
+
// ID 44 used to be a table of merged canonical declarations.
// ID 45 used to be a list of declaration IDs of local redeclarations.
-
+
/// \brief Record code for the array of Objective-C categories (including
/// extensions).
///
@@ -580,7 +580,17 @@ namespace clang {
MSSTRUCT_PRAGMA_OPTIONS = 55,
/// \brief Record code for \#pragma ms_struct options.
- POINTERS_TO_MEMBERS_PRAGMA_OPTIONS = 56
+ POINTERS_TO_MEMBERS_PRAGMA_OPTIONS = 56,
+
+ /// \brief Number of unmatched #pragma clang cuda_force_host_device begin
+ /// directives we've seen.
+ CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH = 57,
+
+ /// \brief Record code for types associated with OpenCL extensions.
+ OPENCL_EXTENSION_TYPES = 58,
+
+ /// \brief Record code for declarations associated with OpenCL extensions.
+ OPENCL_EXTENSION_DECLS = 59,
};
/// \brief Record types used within a source manager block.
@@ -684,6 +694,9 @@ namespace clang {
/// \brief Specifies a header that is private to this submodule but
/// must be textually included.
SUBMODULE_PRIVATE_TEXTUAL_HEADER = 15,
+ /// \brief Specifies some declarations with initializers that must be
+ /// emitted to initialize the module.
+ SUBMODULE_INITIALIZERS = 16,
};
/// \brief Record types used within a comments block.
@@ -899,7 +912,9 @@ namespace clang {
/// \brief An AdjustedType record.
TYPE_ADJUSTED = 42,
/// \brief A PipeType record.
- TYPE_PIPE = 43
+ TYPE_PIPE = 43,
+ /// \brief An ObjCTypeParamType record.
+ TYPE_OBJC_TYPE_PARAM = 44
};
/// \brief The type IDs for special types constructed by semantic
@@ -1053,6 +1068,10 @@ namespace clang {
DECL_IMPLICIT_PARAM,
/// \brief A ParmVarDecl record.
DECL_PARM_VAR,
+ /// \brief A DecompositionDecl record.
+ DECL_DECOMPOSITION,
+ /// \brief A BindingDecl record.
+ DECL_BINDING,
/// \brief A FileScopeAsmDecl record.
DECL_FILE_SCOPE_ASM,
/// \brief A BlockDecl record.
@@ -1084,6 +1103,8 @@ namespace clang {
DECL_NAMESPACE_ALIAS,
/// \brief A UsingDecl record.
DECL_USING,
+ /// \brief A UsingPackDecl record.
+ DECL_USING_PACK,
/// \brief A UsingShadowDecl record.
DECL_USING_SHADOW,
/// \brief A ConstructorUsingShadowDecl record.
@@ -1096,6 +1117,8 @@ namespace clang {
DECL_UNRESOLVED_USING_TYPENAME,
/// \brief A LinkageSpecDecl record.
DECL_LINKAGE_SPEC,
+ /// \brief An ExportDecl record.
+ DECL_EXPORT,
/// \brief A CXXRecordDecl record.
DECL_CXX_RECORD,
/// \brief A CXXMethodDecl record.
@@ -1277,10 +1300,14 @@ namespace clang {
EXPR_DESIGNATED_INIT,
/// \brief A DesignatedInitUpdateExpr record.
EXPR_DESIGNATED_INIT_UPDATE,
- /// \brief An ImplicitValueInitExpr record.
- EXPR_IMPLICIT_VALUE_INIT,
/// \brief An NoInitExpr record.
EXPR_NO_INIT,
+ /// \brief An ArrayInitLoopExpr record.
+ EXPR_ARRAY_INIT_LOOP,
+ /// \brief An ArrayInitIndexExpr record.
+ EXPR_ARRAY_INIT_INDEX,
+ /// \brief An ImplicitValueInitExpr record.
+ EXPR_IMPLICIT_VALUE_INIT,
/// \brief A VAArgExpr record.
EXPR_VA_ARG,
/// \brief An AddrLabelExpr record.
@@ -1481,6 +1508,14 @@ namespace clang {
STMT_OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE,
STMT_OMP_DISTRIBUTE_SIMD_DIRECTIVE,
STMT_OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE,
+ STMT_OMP_TARGET_SIMD_DIRECTIVE,
+ STMT_OMP_TEAMS_DISTRIBUTE_DIRECTIVE,
+ STMT_OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE,
+ STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE,
+ STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE,
+ STMT_OMP_TARGET_TEAMS_DIRECTIVE,
+ STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE,
+ STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE,
EXPR_OMP_ARRAY_SECTION,
// ARC
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 18e23870a765..5230e2ae0013 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -18,10 +18,8 @@
#include "clang/AST/DeclarationName.h"
#include "clang/AST/TemplateBase.h"
#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Version.h"
#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/HeaderSearch.h"
@@ -33,9 +31,6 @@
#include "clang/Serialization/Module.h"
#include "clang/Serialization/ModuleFileExtension.h"
#include "clang/Serialization/ModuleManager.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
@@ -43,22 +38,27 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Timer.h"
#include <deque>
-#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
namespace llvm {
+ class BitstreamCursor;
class MemoryBuffer;
+ class APInt;
+ class APSInt;
+ class APFloat;
}
namespace clang {
+class SourceManager;
+class HeaderSearchOptions;
+class FileManager;
class AddrLabelExpr;
class ASTConsumer;
class ASTContext;
@@ -89,6 +89,7 @@ class ASTWriter;
class ASTReader;
class ASTDeclReader;
class ASTStmtReader;
+class ASTRecordReader;
class TypeLocReader;
struct HeaderFileInfo;
class VersionTuple;
@@ -285,6 +286,21 @@ private:
void Error(const char *Msg);
};
+/// \brief ASTReaderListenter implementation to set SuggestedPredefines of
+/// ASTReader which is required to use a pch file. This is the replacement
+/// of PCHValidator or SimplePCHValidator when using a pch file without
+/// validating it.
+class SimpleASTReaderListener : public ASTReaderListener {
+ Preprocessor &PP;
+
+public:
+ SimpleASTReaderListener(Preprocessor &PP)
+ : PP(PP) {}
+
+ bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
+ std::string &SuggestedPredefines) override;
+};
+
namespace serialization {
class ReadMethodPoolVisitor;
@@ -342,7 +358,7 @@ public:
/// \brief The AST file has errors.
HadErrors
};
-
+
/// \brief Types of AST files.
friend class PCHValidator;
friend class ASTDeclReader;
@@ -350,6 +366,7 @@ public:
friend class ASTIdentifierIterator;
friend class serialization::reader::ASTIdentifierLookupTrait;
friend class TypeLocReader;
+ friend class ASTRecordReader;
friend class ASTWriter;
friend class ASTUnit; // ASTUnit needs to remap source locations.
friend class serialization::ReadMethodPoolVisitor;
@@ -758,6 +775,10 @@ private:
/// Sema tracks these to emit warnings.
SmallVector<uint64_t, 16> UnusedLocalTypedefNameCandidates;
+ /// \brief Our current depth in #pragma cuda force_host_device begin/end
+ /// macros.
+ unsigned ForceCUDAHostDeviceDepth = 0;
+
/// \brief The IDs of the declarations Sema stores directly.
///
/// Sema tracks a few important decls, such as namespace std, directly.
@@ -788,7 +809,13 @@ private:
SourceLocation PointersToMembersPragmaLocation;
/// \brief The OpenCL extension settings.
- SmallVector<uint64_t, 1> OpenCLExtensions;
+ OpenCLOptions OpenCLExtensions;
+
+ /// \brief Extensions required by an OpenCL type.
+ llvm::DenseMap<const Type *, std::set<std::string>> OpenCLTypeExtMap;
+
+ /// \brief Extensions required by an OpenCL declaration.
+ llvm::DenseMap<const Decl *, std::set<std::string>> OpenCLDeclExtMap;
/// \brief A list of the namespaces we've seen.
SmallVector<uint64_t, 4> KnownNamespaces;
@@ -803,6 +830,7 @@ private:
// \brief A list of late parsed template function data.
SmallVector<uint64_t, 1> LateParsedTemplates;
+public:
struct ImportedSubmodule {
serialization::SubmoduleID ID;
SourceLocation ImportLoc;
@@ -811,6 +839,7 @@ private:
: ID(ID), ImportLoc(ImportLoc) {}
};
+private:
/// \brief A list of modules that were imported by precompiled headers or
/// any other non-module AST file.
SmallVector<ImportedSubmodule, 2> ImportedModules;
@@ -1154,7 +1183,7 @@ private:
static ASTReadResult ReadOptionsBlock(
llvm::BitstreamCursor &Stream, unsigned ClientLoadCapabilities,
bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener,
- std::string &SuggestedPredefines);
+ std::string &SuggestedPredefines, bool ValidateDiagnosticOptions);
ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
ASTReadResult ReadExtensionBlock(ModuleFile &F);
bool ParseLineTable(ModuleFile &F, const RecordData &Record);
@@ -1386,9 +1415,13 @@ public:
/// \param ClientLoadCapabilities The set of client load-failure
/// capabilities, represented as a bitset of the enumerators of
/// LoadFailureCapabilities.
+ ///
+ /// \param Imported optional out-parameter to append the list of modules
+ /// that were imported by precompiled headers or any other non-module AST file
ASTReadResult ReadAST(StringRef FileName, ModuleKind Type,
SourceLocation ImportLoc,
- unsigned ClientLoadCapabilities);
+ unsigned ClientLoadCapabilities,
+ SmallVectorImpl<ImportedSubmodule> *Imported = nullptr);
/// \brief Make the entities in the given module and any of its (non-explicit)
/// submodules visible to name lookup.
@@ -1406,6 +1439,10 @@ public:
/// \brief Make the names within this set of hidden names visible.
void makeNamesVisible(const HiddenNames &Names, Module *Owner);
+ /// \brief Note that MergedDef is a redefinition of the canonical definition
+ /// Def, so Def should be visible whenever MergedDef is.
+ void mergeDefinitionVisibility(NamedDecl *Def, NamedDecl *MergedDef);
+
/// \brief Take the AST callbacks listener.
std::unique_ptr<ASTReaderListener> takeListener() {
return std::move(Listener);
@@ -1517,7 +1554,8 @@ public:
readASTFileControlBlock(StringRef Filename, FileManager &FileMgr,
const PCHContainerReader &PCHContainerRdr,
bool FindModuleFileExtensions,
- ASTReaderListener &Listener);
+ ASTReaderListener &Listener,
+ bool ValidateDiagnosticOptions);
/// \brief Determine whether the given AST file is acceptable to load into a
/// translation unit with the given language and target options.
@@ -1854,8 +1892,8 @@ public:
SourceLocation> > &Pending) override;
void ReadLateParsedTemplates(
- llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap)
- override;
+ llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
+ &LPTMap) override;
/// \brief Load a selector from disk, registering its ID if it exists.
void LoadSelector(Selector Sel);
@@ -1910,7 +1948,7 @@ public:
/// number.
serialization::SubmoduleID
getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID);
-
+
/// \brief Retrieve the submodule that corresponds to a global submodule ID.
///
Module *getSubmodule(serialization::SubmoduleID GlobalID);
@@ -2154,6 +2192,287 @@ public:
bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
};
+/// \brief An object for streaming information from a record.
+class ASTRecordReader {
+ typedef serialization::ModuleFile ModuleFile;
+
+ ASTReader *Reader;
+ ModuleFile *F;
+ unsigned Idx = 0;
+ ASTReader::RecordData Record;
+
+ typedef ASTReader::RecordData RecordData;
+ typedef ASTReader::RecordDataImpl RecordDataImpl;
+
+public:
+ /// Construct an ASTRecordReader that uses the default encoding scheme.
+ ASTRecordReader(ASTReader &Reader, ModuleFile &F)
+ : Reader(&Reader), F(&F) {}
+
+ /// \brief Reads a record with id AbbrevID from Cursor, resetting the
+ /// internal state.
+ unsigned readRecord(llvm::BitstreamCursor &Cursor, unsigned AbbrevID);
+
+ /// \brief Is this a module file for a module (rather than a PCH or similar).
+ bool isModule() const { return F->isModule(); }
+
+ /// \brief Retrieve the AST context that this AST reader supplements.
+ ASTContext &getContext() { return Reader->getContext(); }
+
+ /// \brief The current position in this record.
+ unsigned getIdx() const { return Idx; }
+ /// \brief The length of this record.
+ size_t size() const { return Record.size(); }
+
+ /// \brief An arbitrary index in this record.
+ const uint64_t &operator[](size_t N) { return Record[N]; }
+ /// \brief The last element in this record.
+ const uint64_t &back() const { return Record.back(); }
+
+ /// \brief Returns the current value in this record, and advances to the
+ /// next value.
+ const uint64_t &readInt() { return Record[Idx++]; }
+ /// \brief Returns the current value in this record, without advancing.
+ const uint64_t &peekInt() { return Record[Idx]; }
+
+ /// \brief Skips the specified number of values.
+ void skipInts(unsigned N) { Idx += N; }
+
+ /// \brief Retrieve the global submodule ID its local ID number.
+ serialization::SubmoduleID
+ getGlobalSubmoduleID(unsigned LocalID) {
+ return Reader->getGlobalSubmoduleID(*F, LocalID);
+ }
+
+ /// \brief Retrieve the submodule that corresponds to a global submodule ID.
+ Module *getSubmodule(serialization::SubmoduleID GlobalID) {
+ return Reader->getSubmodule(GlobalID);
+ }
+
+ /// \brief Read the record that describes the lexical contents of a DC.
+ bool readLexicalDeclContextStorage(uint64_t Offset, DeclContext *DC) {
+ return Reader->ReadLexicalDeclContextStorage(*F, F->DeclsCursor, Offset,
+ DC);
+ }
+
+ /// \brief Read the record that describes the visible contents of a DC.
+ bool readVisibleDeclContextStorage(uint64_t Offset,
+ serialization::DeclID ID) {
+ return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset,
+ ID);
+ }
+
+ void readExceptionSpec(SmallVectorImpl<QualType> &ExceptionStorage,
+ FunctionProtoType::ExceptionSpecInfo &ESI) {
+ return Reader->readExceptionSpec(*F, ExceptionStorage, ESI, Record, Idx);
+ }
+
+ /// \brief Get the global offset corresponding to a local offset.
+ uint64_t getGlobalBitOffset(uint32_t LocalOffset) {
+ return Reader->getGlobalBitOffset(*F, LocalOffset);
+ }
+
+ /// \brief Reads a statement.
+ Stmt *readStmt() { return Reader->ReadStmt(*F); }
+
+ /// \brief Reads an expression.
+ Expr *readExpr() { return Reader->ReadExpr(*F); }
+
+ /// \brief Reads a sub-statement operand during statement reading.
+ Stmt *readSubStmt() { return Reader->ReadSubStmt(); }
+
+ /// \brief Reads a sub-expression operand during statement reading.
+ Expr *readSubExpr() { return Reader->ReadSubExpr(); }
+
+ /// \brief Reads a TemplateArgumentLocInfo appropriate for the
+ /// given TemplateArgument kind, advancing Idx.
+ TemplateArgumentLocInfo
+ getTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind) {
+ return Reader->GetTemplateArgumentLocInfo(*F, Kind, Record, Idx);
+ }
+
+ /// \brief Reads a TemplateArgumentLoc, advancing Idx.
+ TemplateArgumentLoc
+ readTemplateArgumentLoc() {
+ return Reader->ReadTemplateArgumentLoc(*F, Record, Idx);
+ }
+
+ const ASTTemplateArgumentListInfo*
+ readASTTemplateArgumentListInfo() {
+ return Reader->ReadASTTemplateArgumentListInfo(*F, Record, Idx);
+ }
+
+ /// \brief Reads a declarator info from the given record, advancing Idx.
+ TypeSourceInfo *getTypeSourceInfo() {
+ return Reader->GetTypeSourceInfo(*F, Record, Idx);
+ }
+
+ /// \brief Map a local type ID within a given AST file to a global type ID.
+ serialization::TypeID getGlobalTypeID(unsigned LocalID) const {
+ return Reader->getGlobalTypeID(*F, LocalID);
+ }
+
+ /// \brief Read a type from the current position in the record.
+ QualType readType() {
+ return Reader->readType(*F, Record, Idx);
+ }
+
+ /// \brief Reads a declaration ID from the given position in this record.
+ ///
+ /// \returns The declaration ID read from the record, adjusted to a global ID.
+ serialization::DeclID readDeclID() {
+ return Reader->ReadDeclID(*F, Record, Idx);
+ }
+
+ /// \brief Reads a declaration from the given position in a record in the
+ /// given module, advancing Idx.
+ Decl *readDecl() {
+ return Reader->ReadDecl(*F, Record, Idx);
+ }
+
+ /// \brief Reads a declaration from the given position in the record,
+ /// advancing Idx.
+ ///
+ /// \returns The declaration read from this location, casted to the given
+ /// result type.
+ template<typename T>
+ T *readDeclAs() {
+ return Reader->ReadDeclAs<T>(*F, Record, Idx);
+ }
+
+ IdentifierInfo *getIdentifierInfo() {
+ return Reader->GetIdentifierInfo(*F, Record, Idx);
+ }
+
+ /// \brief Read a selector from the Record, advancing Idx.
+ Selector readSelector() {
+ return Reader->ReadSelector(*F, Record, Idx);
+ }
+
+ /// \brief Read a declaration name, advancing Idx.
+ DeclarationName readDeclarationName() {
+ return Reader->ReadDeclarationName(*F, Record, Idx);
+ }
+ void readDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name) {
+ return Reader->ReadDeclarationNameLoc(*F, DNLoc, Name, Record, Idx);
+ }
+ void readDeclarationNameInfo(DeclarationNameInfo &NameInfo) {
+ return Reader->ReadDeclarationNameInfo(*F, NameInfo, Record, Idx);
+ }
+
+ void readQualifierInfo(QualifierInfo &Info) {
+ return Reader->ReadQualifierInfo(*F, Info, Record, Idx);
+ }
+
+ NestedNameSpecifier *readNestedNameSpecifier() {
+ return Reader->ReadNestedNameSpecifier(*F, Record, Idx);
+ }
+
+ NestedNameSpecifierLoc readNestedNameSpecifierLoc() {
+ return Reader->ReadNestedNameSpecifierLoc(*F, Record, Idx);
+ }
+
+ /// \brief Read a template name, advancing Idx.
+ TemplateName readTemplateName() {
+ return Reader->ReadTemplateName(*F, Record, Idx);
+ }
+
+ /// \brief Read a template argument, advancing Idx.
+ TemplateArgument readTemplateArgument(bool Canonicalize = false) {
+ return Reader->ReadTemplateArgument(*F, Record, Idx, Canonicalize);
+ }
+
+ /// \brief Read a template parameter list, advancing Idx.
+ TemplateParameterList *readTemplateParameterList() {
+ return Reader->ReadTemplateParameterList(*F, Record, Idx);
+ }
+
+ /// \brief Read a template argument array, advancing Idx.
+ void readTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
+ bool Canonicalize = false) {
+ return Reader->ReadTemplateArgumentList(TemplArgs, *F, Record, Idx,
+ Canonicalize);
+ }
+
+ /// \brief Read a UnresolvedSet structure, advancing Idx.
+ void readUnresolvedSet(LazyASTUnresolvedSet &Set) {
+ return Reader->ReadUnresolvedSet(*F, Set, Record, Idx);
+ }
+
+ /// \brief Read a C++ base specifier, advancing Idx.
+ CXXBaseSpecifier readCXXBaseSpecifier() {
+ return Reader->ReadCXXBaseSpecifier(*F, Record, Idx);
+ }
+
+ /// \brief Read a CXXCtorInitializer array, advancing Idx.
+ CXXCtorInitializer **readCXXCtorInitializers() {
+ return Reader->ReadCXXCtorInitializers(*F, Record, Idx);
+ }
+
+ CXXTemporary *readCXXTemporary() {
+ return Reader->ReadCXXTemporary(*F, Record, Idx);
+ }
+
+ /// \brief Read a source location, advancing Idx.
+ SourceLocation readSourceLocation() {
+ return Reader->ReadSourceLocation(*F, Record, Idx);
+ }
+
+ /// \brief Read a source range, advancing Idx.
+ SourceRange readSourceRange() {
+ return Reader->ReadSourceRange(*F, Record, Idx);
+ }
+
+ /// \brief Read an integral value, advancing Idx.
+ llvm::APInt readAPInt() {
+ return Reader->ReadAPInt(Record, Idx);
+ }
+
+ /// \brief Read a signed integral value, advancing Idx.
+ llvm::APSInt readAPSInt() {
+ return Reader->ReadAPSInt(Record, Idx);
+ }
+
+ /// \brief Read a floating-point value, advancing Idx.
+ llvm::APFloat readAPFloat(const llvm::fltSemantics &Sem) {
+ return Reader->ReadAPFloat(Record, Sem,Idx);
+ }
+
+ /// \brief Read a string, advancing Idx.
+ std::string readString() {
+ return Reader->ReadString(Record, Idx);
+ }
+
+ /// \brief Read a path, advancing Idx.
+ std::string readPath() {
+ return Reader->ReadPath(*F, Record, Idx);
+ }
+
+ /// \brief Read a version tuple, advancing Idx.
+ VersionTuple readVersionTuple() {
+ return ASTReader::ReadVersionTuple(Record, Idx);
+ }
+
+ /// \brief Reads attributes from the current stream position, advancing Idx.
+ void readAttributes(AttrVec &Attrs) {
+ return Reader->ReadAttributes(*F, Attrs, Record, Idx);
+ }
+
+ /// \brief Reads a token out of a record, advancing Idx.
+ Token readToken() {
+ return Reader->ReadToken(*F, Record, Idx);
+ }
+
+ void recordSwitchCaseID(SwitchCase *SC, unsigned ID) {
+ Reader->RecordSwitchCaseID(SC, ID);
+ }
+
+ /// \brief Retrieve the switch-case statement with the given ID.
+ SwitchCase *getSwitchCaseWithID(unsigned ID) {
+ return Reader->getSwitchCaseWithID(ID);
+ }
+};
+
/// \brief Helper class that saves the current stream position and
/// then restores it when destroyed.
struct SavedStreamPosition {
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index bfdb9f2262b5..1469555ec21e 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -16,9 +16,8 @@
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/AST/TemplateBase.h"
+#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ASTDeserializationListener.h"
@@ -26,21 +25,19 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Bitcode/BitstreamWriter.h"
-#include <map>
#include <queue>
#include <vector>
namespace llvm {
class APFloat;
class APInt;
- class BitstreamWriter;
}
namespace clang {
+class DeclarationName;
class ASTContext;
class Attr;
class NestedNameSpecifier;
@@ -376,9 +373,10 @@ private:
/// it.
llvm::SmallSetVector<const DeclContext *, 16> UpdatedDeclContexts;
- /// \brief Keeps track of visible decls that were added in DeclContexts
- /// coming from another AST file.
- SmallVector<const Decl *, 16> UpdatingVisibleDecls;
+ /// \brief Keeps track of declarations that we must emit, even though we're
+ /// not guaranteed to be able to find them by walking the AST starting at the
+ /// translation unit.
+ SmallVector<const Decl *, 16> DeclsToEmitEvenIfUnreferenced;
/// \brief The set of Objective-C class that have categories we
/// should serialize.
@@ -461,6 +459,9 @@ private:
void WriteDeclContextVisibleUpdate(const DeclContext *DC);
void WriteFPPragmaOptions(const FPOptions &Opts);
void WriteOpenCLExtensions(Sema &SemaRef);
+ void WriteOpenCLExtensionTypes(Sema &SemaRef);
+ void WriteOpenCLExtensionDecls(Sema &SemaRef);
+ void WriteCUDAPragmas(Sema &SemaRef);
void WriteObjCCategories();
void WriteLateParsedTemplates(Sema &SemaRef);
void WriteOptimizePragmaOptions(Sema &SemaRef);
@@ -670,6 +671,14 @@ private:
void CompletedTagDefinition(const TagDecl *D) override;
void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override;
void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override;
+ void AddedCXXTemplateSpecialization(
+ const ClassTemplateDecl *TD,
+ const ClassTemplateSpecializationDecl *D) override;
+ void AddedCXXTemplateSpecialization(
+ const VarTemplateDecl *TD,
+ const VarTemplateSpecializationDecl *D) override;
+ void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
+ const FunctionDecl *D) override;
void ResolvedExceptionSpec(const FunctionDecl *FD) override;
void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override;
void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
@@ -677,6 +686,7 @@ private:
void CompletedImplicitDefinition(const FunctionDecl *D) override;
void StaticDataMemberInstantiated(const VarDecl *D) override;
void DefaultArgumentInstantiated(const ParmVarDecl *D) override;
+ void DefaultMemberInitializerInstantiated(const FieldDecl *D) override;
void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) override;
@@ -911,7 +921,6 @@ public:
class PCHGenerator : public SemaConsumer {
const Preprocessor &PP;
std::string OutputFile;
- clang::Module *Module;
std::string isysroot;
Sema *SemaPtr;
std::shared_ptr<PCHBuffer> Buffer;
@@ -927,7 +936,7 @@ protected:
public:
PCHGenerator(
const Preprocessor &PP, StringRef OutputFile,
- clang::Module *Module, StringRef isysroot,
+ StringRef isysroot,
std::shared_ptr<PCHBuffer> Buffer,
ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors = false,
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index aa0392f0ecfb..58b3149d407e 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -48,7 +48,8 @@ enum ModuleKind {
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.
+ MK_MainFile, ///< File is a PCH file treated as the actual main file.
+ MK_PrebuiltModule ///< File is from a prebuilt module path.
};
/// \brief The input file that has been loaded from this AST file, along with
@@ -172,8 +173,8 @@ public:
/// \brief The global bit offset (or base) of this module
uint64_t GlobalBitOffset;
- /// \brief The bitstream reader from which we'll read the AST file.
- llvm::BitstreamReader StreamFile;
+ /// \brief The serialized bitstream data for this file.
+ StringRef Data;
/// \brief The main bitstream cursor for the main block.
llvm::BitstreamCursor Stream;
@@ -447,7 +448,8 @@ public:
/// \brief Is this a module file for a module (rather than a PCH or similar).
bool isModule() const {
- return Kind == MK_ImplicitModule || Kind == MK_ExplicitModule;
+ return Kind == MK_ImplicitModule || Kind == MK_ExplicitModule ||
+ Kind == MK_PrebuiltModule;
}
/// \brief Dump debugging output for this module.
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index 08e7d4049e55..1c4d88e979e3 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -175,7 +175,7 @@ public:
OutOfDate
};
- typedef ASTFileSignature(*ASTFileSignatureReader)(llvm::BitstreamReader &);
+ typedef ASTFileSignature(*ASTFileSignatureReader)(StringRef);
/// \brief Attempts to create a new module and add it to the list of known
/// modules.
diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 785e064e72a9..2e58debf80fc 100644
--- a/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -42,6 +42,10 @@ def Nullability : Package<"nullability">;
def Cplusplus : Package<"cplusplus">;
def CplusplusAlpha : Package<"cplusplus">, InPackage<Alpha>, Hidden;
+def CplusplusOptIn : Package<"cplusplus">, InPackage<OptIn>;
+
+def Valist : Package<"valist">;
+def ValistAlpha : Package<"valist">, InPackage<Alpha>, Hidden;
def DeadCode : Package<"deadcode">;
def DeadCodeAlpha : Package<"deadcode">, InPackage<Alpha>, Hidden;
@@ -75,8 +79,17 @@ def LocalizabilityOptIn : Package<"localizability">, InPackage<CocoaOptIn>;
def MPI : Package<"mpi">, InPackage<OptIn>;
def LLVM : Package<"llvm">;
+
+// The APIModeling package is for checkers that model APIs and don't perform
+// any diagnostics. These checkers are always turned on; this package is
+// intended for API modeling that is not controlled by the the target triple.
+def APIModeling : Package<"apiModeling">, Hidden;
+def GoogleAPIModeling : Package<"google">, InPackage<APIModeling>;
+
def Debug : Package<"debug">;
+def CloneDetectionAlpha : Package<"clone">, InPackage<Alpha>, Hidden;
+
//===----------------------------------------------------------------------===//
// Core Checkers.
//===----------------------------------------------------------------------===//
@@ -131,6 +144,10 @@ def CastToStructChecker : Checker<"CastToStruct">,
HelpText<"Check for cast from non-struct pointer to struct pointer">,
DescFile<"CastToStructChecker.cpp">;
+def ConversionChecker : Checker<"Conversion">,
+ HelpText<"Loss of sign/precision in implicit conversions">,
+ DescFile<"ConversionChecker.cpp">;
+
def IdenticalExprChecker : Checker<"IdenticalExpr">,
HelpText<"Warn about unintended use of identical expressions in operators">,
DescFile<"IdenticalExprChecker.cpp">;
@@ -183,7 +200,7 @@ def NullablePassedToNonnullChecker : Checker<"NullablePassedToNonnull">,
HelpText<"Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.">,
DescFile<"NullabilityChecker.cpp">;
-def NullableReturnedFromNonnullChecker : Checker<"NullablePassedToNonnull">,
+def NullableReturnedFromNonnullChecker : Checker<"NullableReturnedFromNonnull">,
HelpText<"Warns when a nullable pointer is returned from a function that has _Nonnull return type.">,
DescFile<"NullabilityChecker.cpp">;
@@ -247,15 +264,40 @@ def NewDeleteLeaksChecker : Checker<"NewDeleteLeaks">,
HelpText<"Check for memory leaks. Traces memory managed by new/delete.">,
DescFile<"MallocChecker.cpp">;
+def CXXSelfAssignmentChecker : Checker<"SelfAssignment">,
+ HelpText<"Checks C++ copy and move assignment operators for self assignment">,
+ DescFile<"CXXSelfAssignmentChecker.cpp">;
+
} // end: "cplusplus"
-let ParentPackage = CplusplusAlpha in {
+let ParentPackage = CplusplusOptIn in {
def VirtualCallChecker : Checker<"VirtualCall">,
HelpText<"Check virtual function calls during construction or destruction">,
DescFile<"VirtualCallChecker.cpp">;
-} // end: "alpha.cplusplus"
+} // end: "optin.cplusplus"
+
+
+//===----------------------------------------------------------------------===//
+// Valist checkers.
+//===----------------------------------------------------------------------===//
+
+let ParentPackage = ValistAlpha in {
+
+def UninitializedChecker : Checker<"Uninitialized">,
+ HelpText<"Check for usages of uninitialized (or already released) va_lists.">,
+ DescFile<"ValistChecker.cpp">;
+
+def UnterminatedChecker : Checker<"Unterminated">,
+ HelpText<"Check for va_lists which are not released by a va_end call.">,
+ DescFile<"ValistChecker.cpp">;
+
+def CopyToSelfChecker : Checker<"CopyToSelf">,
+ HelpText<"Check for va_lists which are copied onto itself.">,
+ DescFile<"ValistChecker.cpp">;
+
+} // end : "alpha.valist"
//===----------------------------------------------------------------------===//
// Deadcode checkers.
@@ -382,6 +424,10 @@ def VforkChecker : Checker<"Vfork">,
HelpText<"Check for proper usage of vfork">,
DescFile<"VforkChecker.cpp">;
+def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
+ HelpText<"Improve modeling of the C standard library functions">,
+ DescFile<"StdLibraryFunctionsChecker.cpp">;
+
} // end "unix"
let ParentPackage = UnixAlpha in {
@@ -402,6 +448,10 @@ def SimpleStreamChecker : Checker<"SimpleStream">,
HelpText<"Check for misuses of stream APIs">,
DescFile<"SimpleStreamChecker.cpp">;
+def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
+ HelpText<"Check for calls to blocking functions inside a critical section">,
+ DescFile<"BlockInCriticalSectionChecker.cpp">;
+
} // end "alpha.unix"
let ParentPackage = CString in {
@@ -436,16 +486,22 @@ def CStringNotNullTerm : Checker<"NotNullTerminated">,
let ParentPackage = OSX in {
+def NumberObjectConversionChecker : Checker<"NumberObjectConversion">,
+ HelpText<"Check for erroneous conversions of objects representing numbers into numbers">,
+ DescFile<"NumberObjectConversionChecker.cpp">;
+
def MacOSXAPIChecker : Checker<"API">,
- InPackage<OSX>,
HelpText<"Check for proper uses of various Apple APIs">,
DescFile<"MacOSXAPIChecker.cpp">;
def MacOSKeychainAPIChecker : Checker<"SecKeychainAPI">,
- InPackage<OSX>,
HelpText<"Check for proper uses of Secure Keychain APIs">,
DescFile<"MacOSKeychainAPIChecker.cpp">;
+def ObjCPropertyChecker : Checker<"ObjCProperty">,
+ HelpText<"Check for proper uses of Objective-C properties">,
+ DescFile<"ObjCPropertyChecker.cpp">;
+
} // end "osx"
let ParentPackage = Cocoa in {
@@ -539,8 +595,8 @@ def DirectIvarAssignmentForAnnotatedFunctions : Checker<"DirectIvarAssignmentFor
let ParentPackage = CoreFoundation in {
-def CFNumberCreateChecker : Checker<"CFNumber">,
- HelpText<"Check for proper uses of CFNumberCreate">,
+def CFNumberChecker : Checker<"CFNumber">,
+ HelpText<"Check for proper uses of CFNumber APIs">,
DescFile<"BasicObjCFoundationChecks.cpp">;
def CFRetainReleaseChecker : Checker<"CFRetainRelease">,
@@ -594,12 +650,27 @@ def LLVMConventionsChecker : Checker<"Conventions">,
HelpText<"Check code for LLVM codebase conventions">,
DescFile<"LLVMConventionsChecker.cpp">;
+
+
+//===----------------------------------------------------------------------===//
+// Checkers modeling Google APIs.
+//===----------------------------------------------------------------------===//
+
+def GTestChecker : Checker<"GTest">,
+ InPackage<GoogleAPIModeling>,
+ HelpText<"Model gtest assertion APIs">,
+ DescFile<"GTestChecker.cpp">;
+
//===----------------------------------------------------------------------===//
// Debugging checkers (for analyzer development).
//===----------------------------------------------------------------------===//
let ParentPackage = Debug in {
+def AnalysisOrderChecker : Checker<"AnalysisOrder">,
+ HelpText<"Print callbacks that are called during analysis in order">,
+ DescFile<"AnalysisOrder.cpp">;
+
def DominatorsTreeDumper : Checker<"DumpDominators">,
HelpText<"Print the dominance tree for a given CFG">,
DescFile<"DebugCheckers.cpp">;
@@ -657,3 +728,17 @@ def BugHashDumper : Checker<"DumpBugHash">,
DescFile<"DebugCheckers.cpp">;
} // end "debug"
+
+
+//===----------------------------------------------------------------------===//
+// Clone Detection
+//===----------------------------------------------------------------------===//
+
+let ParentPackage = CloneDetectionAlpha in {
+
+def CloneChecker : Checker<"CloneChecker">,
+ HelpText<"Reports similar pieces of code.">,
+ DescFile<"CloneChecker.cpp">;
+
+} // end "clone"
+
diff --git a/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h b/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h
new file mode 100644
index 000000000000..65e908912c54
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h
@@ -0,0 +1,97 @@
+//===-- MPIFunctionClassifier.h - classifies MPI functions ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines functionality to identify and classify MPI functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPIFUNCTIONCLASSIFIER_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPIFUNCTIONCLASSIFIER_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+
+namespace clang {
+namespace ento {
+namespace mpi {
+
+class MPIFunctionClassifier {
+public:
+ MPIFunctionClassifier(ASTContext &ASTCtx) { identifierInit(ASTCtx); }
+
+ // general identifiers
+ bool isMPIType(const IdentifierInfo *const IdentInfo) const;
+ bool isNonBlockingType(const IdentifierInfo *const IdentInfo) const;
+
+ // point-to-point identifiers
+ bool isPointToPointType(const IdentifierInfo *const IdentInfo) const;
+
+ // collective identifiers
+ bool isCollectiveType(const IdentifierInfo *const IdentInfo) const;
+ bool isCollToColl(const IdentifierInfo *const IdentInfo) const;
+ bool isScatterType(const IdentifierInfo *const IdentInfo) const;
+ bool isGatherType(const IdentifierInfo *const IdentInfo) const;
+ bool isAllgatherType(const IdentifierInfo *const IdentInfo) const;
+ bool isAlltoallType(const IdentifierInfo *const IdentInfo) const;
+ bool isReduceType(const IdentifierInfo *const IdentInfo) const;
+ bool isBcastType(const IdentifierInfo *const IdentInfo) const;
+
+ // additional identifiers
+ bool isMPI_Wait(const IdentifierInfo *const IdentInfo) const;
+ bool isMPI_Waitall(const IdentifierInfo *const IdentInfo) const;
+ bool isWaitType(const IdentifierInfo *const IdentInfo) const;
+
+private:
+ // Initializes function identifiers, to recognize them during analysis.
+ void identifierInit(ASTContext &ASTCtx);
+ void initPointToPointIdentifiers(ASTContext &ASTCtx);
+ void initCollectiveIdentifiers(ASTContext &ASTCtx);
+ void initAdditionalIdentifiers(ASTContext &ASTCtx);
+
+ // The containers are used, to enable classification of MPI-functions during
+ // analysis.
+ llvm::SmallVector<IdentifierInfo *, 12> MPINonBlockingTypes;
+
+ llvm::SmallVector<IdentifierInfo *, 10> MPIPointToPointTypes;
+ llvm::SmallVector<IdentifierInfo *, 16> MPICollectiveTypes;
+
+ llvm::SmallVector<IdentifierInfo *, 4> MPIPointToCollTypes;
+ llvm::SmallVector<IdentifierInfo *, 4> MPICollToPointTypes;
+ llvm::SmallVector<IdentifierInfo *, 6> MPICollToCollTypes;
+
+ llvm::SmallVector<IdentifierInfo *, 32> MPIType;
+
+ // point-to-point functions
+ IdentifierInfo *IdentInfo_MPI_Send = nullptr, *IdentInfo_MPI_Isend = nullptr,
+ *IdentInfo_MPI_Ssend = nullptr, *IdentInfo_MPI_Issend = nullptr,
+ *IdentInfo_MPI_Bsend = nullptr, *IdentInfo_MPI_Ibsend = nullptr,
+ *IdentInfo_MPI_Rsend = nullptr, *IdentInfo_MPI_Irsend = nullptr,
+ *IdentInfo_MPI_Recv = nullptr, *IdentInfo_MPI_Irecv = nullptr;
+
+ // collective functions
+ IdentifierInfo *IdentInfo_MPI_Scatter = nullptr,
+ *IdentInfo_MPI_Iscatter = nullptr, *IdentInfo_MPI_Gather = nullptr,
+ *IdentInfo_MPI_Igather = nullptr, *IdentInfo_MPI_Allgather = nullptr,
+ *IdentInfo_MPI_Iallgather = nullptr, *IdentInfo_MPI_Bcast = nullptr,
+ *IdentInfo_MPI_Ibcast = nullptr, *IdentInfo_MPI_Reduce = nullptr,
+ *IdentInfo_MPI_Ireduce = nullptr, *IdentInfo_MPI_Allreduce = nullptr,
+ *IdentInfo_MPI_Iallreduce = nullptr, *IdentInfo_MPI_Alltoall = nullptr,
+ *IdentInfo_MPI_Ialltoall = nullptr, *IdentInfo_MPI_Barrier = nullptr;
+
+ // additional functions
+ IdentifierInfo *IdentInfo_MPI_Comm_rank = nullptr,
+ *IdentInfo_MPI_Comm_size = nullptr, *IdentInfo_MPI_Wait = nullptr,
+ *IdentInfo_MPI_Waitall = nullptr;
+};
+
+} // end of namespace: mpi
+} // end of namespace: ento
+} // end of namespace: clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
index 5850656916e3..25886545e2f7 100644
--- a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
+++ b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
@@ -120,9 +120,6 @@ public:
NoRet,
/// Indicates that the returned value is an owned (+1) symbol.
OwnedSymbol,
- /// Indicates that the returned value is an owned (+1) symbol and
- /// that it should be treated as freshly allocated.
- OwnedAllocatedSymbol,
/// Indicates that the returned value is an object with retain count
/// semantics but that it is not owned (+0). This is the default
/// for getters, etc.
@@ -163,8 +160,7 @@ public:
ObjKind getObjKind() const { return O; }
bool isOwned() const {
- return K == OwnedSymbol || K == OwnedAllocatedSymbol ||
- K == OwnedWhenTrackedReceiver;
+ return K == OwnedSymbol || K == OwnedWhenTrackedReceiver;
}
bool notOwned() const {
@@ -179,8 +175,8 @@ public:
return RetEffect(OwnedWhenTrackedReceiver, ObjC);
}
- static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) {
- return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o);
+ static RetEffect MakeOwned(ObjKind o) {
+ return RetEffect(OwnedSymbol, o);
}
static RetEffect MakeNotOwned(ObjKind o) {
return RetEffect(NotOwnedSymbol, o);
diff --git a/include/clang/StaticAnalyzer/Checkers/SValExplainer.h b/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
index 28cfbef91038..62bb0f666d44 100644
--- a/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
+++ b/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
@@ -142,6 +142,14 @@ public:
// TODO: Explain CXXThisRegion itself, find a way to test it.
if (isThisObject(R))
return "'this' object";
+ // Objective-C objects are not normal symbolic regions. At least,
+ // they're always on the heap.
+ if (R->getSymbol()->getType()
+ .getCanonicalType()->getAs<ObjCObjectPointerType>())
+ return "object at " + Visit(R->getSymbol());
+ // Other heap-based symbolic regions are also special.
+ if (isa<HeapSpaceRegion>(R->getMemorySpace()))
+ return "heap segment that starts at " + Visit(R->getSymbol());
return "pointee of " + Visit(R->getSymbol());
}
@@ -176,6 +184,8 @@ public:
std::string Name = VD->getQualifiedNameAsString();
if (isa<ParmVarDecl>(VD))
return "parameter '" + Name + "'";
+ else if (VD->hasAttr<BlocksAttr>())
+ return "block variable '" + Name + "'";
else if (VD->hasLocalStorage())
return "local variable '" + Name + "'";
else if (VD->isStaticLocal())
@@ -186,6 +196,11 @@ public:
llvm_unreachable("A variable is either local or global");
}
+ std::string VisitObjCIvarRegion(const ObjCIvarRegion *R) {
+ return "instance variable '" + R->getDecl()->getNameAsString() + "' of " +
+ Visit(R->getSuperRegion());
+ }
+
std::string VisitFieldRegion(const FieldRegion *R) {
return "field '" + R->getDecl()->getNameAsString() + "' of " +
Visit(R->getSuperRegion());
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 3959de24d431..4fb50deb0f6b 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -125,6 +125,9 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
public:
typedef llvm::StringMap<std::string> ConfigTable;
+ static std::vector<StringRef>
+ getRegisteredCheckers(bool IncludeExperimental = false);
+
/// \brief Pair of checker name and enable/disable.
std::vector<std::pair<std::string, bool> > CheckersControlList;
@@ -149,6 +152,7 @@ public:
unsigned DisableAllChecks : 1;
unsigned ShowCheckerHelp : 1;
+ unsigned ShowEnabledCheckerList : 1;
unsigned AnalyzeAll : 1;
unsigned AnalyzerDisplayProgress : 1;
unsigned AnalyzeNestedBlocks : 1;
@@ -265,6 +269,9 @@ private:
/// \sa shouldWidenLoops
Optional<bool> WidenLoops;
+ /// \sa shouldDisplayNotesAsEvents
+ Optional<bool> DisplayNotesAsEvents;
+
/// A helper function that retrieves option for a given full-qualified
/// checker name.
/// Options for checkers can be specified via 'analyzer-config' command-line
@@ -533,6 +540,14 @@ public:
/// This is controlled by the 'widen-loops' config option.
bool shouldWidenLoops();
+ /// Returns true if the bug reporter should transparently treat extra note
+ /// diagnostic pieces as event diagnostic pieces. Useful when the diagnostic
+ /// consumer doesn't support the extra note pieces.
+ ///
+ /// This is controlled by the 'extra-notes-as-events' option, which defaults
+ /// to false when unset.
+ bool shouldDisplayNotesAsEvents();
+
public:
AnalyzerOptions() :
AnalysisStoreOpt(RegionStoreModel),
@@ -541,6 +556,7 @@ public:
AnalysisPurgeOpt(PurgeStmt),
DisableAllChecks(0),
ShowCheckerHelp(0),
+ ShowEnabledCheckerList(0),
AnalyzeAll(0),
AnalyzerDisplayProgress(0),
AnalyzeNestedBlocks(0),
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 57c73fd6eca1..73f4dd5a3e91 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -66,6 +66,8 @@ public:
typedef SmallVector<std::unique_ptr<BugReporterVisitor>, 8> VisitorList;
typedef VisitorList::iterator visitor_iterator;
typedef SmallVector<StringRef, 2> ExtraTextList;
+ typedef SmallVector<llvm::IntrusiveRefCntPtr<PathDiagnosticNotePiece>, 4>
+ NoteList;
protected:
friend class BugReporter;
@@ -82,7 +84,8 @@ protected:
const ExplodedNode *ErrorNode;
SmallVector<SourceRange, 4> Ranges;
ExtraTextList ExtraText;
-
+ NoteList Notes;
+
typedef llvm::DenseSet<SymbolRef> Symbols;
typedef llvm::DenseSet<const MemRegion *> Regions;
@@ -177,6 +180,18 @@ public:
const BugType& getBugType() const { return BT; }
BugType& getBugType() { return BT; }
+ /// \brief True when the report has an execution path associated with it.
+ ///
+ /// A report is said to be path-sensitive if it was thrown against a
+ /// particular exploded node in the path-sensitive analysis graph.
+ /// Path-sensitive reports have their intermediate path diagnostics
+ /// auto-generated, perhaps with the help of checker-defined visitors,
+ /// and may contain extra notes.
+ /// Path-insensitive reports consist only of a single warning message
+ /// in a specific location, and perhaps extra notes.
+ /// Path-sensitive checkers are allowed to throw path-insensitive reports.
+ bool isPathSensitive() const { return ErrorNode != nullptr; }
+
const ExplodedNode *getErrorNode() const { return ErrorNode; }
StringRef getDescription() const { return Description; }
@@ -245,7 +260,33 @@ public:
void setDeclWithIssue(const Decl *declWithIssue) {
DeclWithIssue = declWithIssue;
}
-
+
+ /// Add new item to the list of additional notes that need to be attached to
+ /// this path-insensitive report. If you want to add extra notes to a
+ /// path-sensitive report, you need to use a BugReporterVisitor because it
+ /// allows you to specify where exactly in the auto-generated path diagnostic
+ /// the extra note should appear.
+ void addNote(StringRef Msg, const PathDiagnosticLocation &Pos,
+ ArrayRef<SourceRange> Ranges) {
+ PathDiagnosticNotePiece *P = new PathDiagnosticNotePiece(Pos, Msg);
+
+ for (const auto &R : Ranges)
+ P->addRange(R);
+
+ Notes.push_back(P);
+ }
+
+ // FIXME: Instead of making an override, we could have default-initialized
+ // Ranges with {}, however it crashes the MSVC 2013 compiler.
+ void addNote(StringRef Msg, const PathDiagnosticLocation &Pos) {
+ std::vector<SourceRange> Ranges;
+ addNote(Msg, Pos, Ranges);
+ }
+
+ virtual const NoteList &getNotes() {
+ return Notes;
+ }
+
/// \brief This allows for addition of meta data to the diagnostic.
///
/// Currently, only the HTMLDiagnosticClient knows how to display it.
@@ -311,31 +352,6 @@ public:
virtual void Profile(llvm::FoldingSetNodeID& hash) const;
};
-} // end ento namespace
-} // end clang namespace
-
-namespace llvm {
- template<> struct ilist_traits<clang::ento::BugReport>
- : public ilist_default_traits<clang::ento::BugReport> {
- clang::ento::BugReport *createSentinel() const {
- return static_cast<clang::ento::BugReport *>(&Sentinel);
- }
- void destroySentinel(clang::ento::BugReport *) const {}
-
- clang::ento::BugReport *provideInitialHead() const {
- return createSentinel();
- }
- clang::ento::BugReport *ensureHead(clang::ento::BugReport *) const {
- return createSentinel();
- }
- private:
- mutable ilist_half_node<clang::ento::BugReport> Sentinel;
- };
-}
-
-namespace clang {
-namespace ento {
-
//===----------------------------------------------------------------------===//
// BugTypes (collections of related reports).
//===----------------------------------------------------------------------===//
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
index c954bbfad8cb..8c3a1d0d4b40 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
@@ -185,6 +185,11 @@ public:
/// Visitor that tries to report interesting diagnostics from conditions.
class ConditionBRVisitor final
: public BugReporterVisitorImpl<ConditionBRVisitor> {
+
+ // FIXME: constexpr initialization isn't supported by MSVC2013.
+ static const char *const GenericTrueMessage;
+ static const char *const GenericFalseMessage;
+
public:
void Profile(llvm::FoldingSetNodeID &ID) const override {
static int x = 0;
@@ -240,11 +245,14 @@ public:
const ExplodedNode *N);
bool patternMatch(const Expr *Ex,
+ const Expr *ParentEx,
raw_ostream &Out,
BugReporterContext &BRC,
BugReport &R,
const ExplodedNode *N,
Optional<bool> &prunable);
+
+ static bool isPieceMessageGeneric(const PathDiagnosticPiece *Piece);
};
/// \brief Suppress reports that might lead to known false positives.
@@ -331,6 +339,22 @@ public:
BugReport &BR) override;
};
+class CXXSelfAssignmentBRVisitor final
+ : public BugReporterVisitorImpl<CXXSelfAssignmentBRVisitor> {
+
+ bool Satisfied;
+
+public:
+ CXXSelfAssignmentBRVisitor() : Satisfied(false) {}
+
+ void Profile(llvm::FoldingSetNodeID &ID) const override {}
+
+ PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
+};
+
namespace bugreporter {
/// Attempts to add visitors to trace a null or undefined value back to its
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
index 16226e94df48..18fa85c9657f 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -17,7 +17,6 @@
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
-#include "llvm/ADT/FoldingSet.h"
#include <string>
namespace clang {
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index c34b14cbf9e2..efe809fb1981 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -334,9 +334,9 @@ public:
// Path "pieces" for path-sensitive diagnostics.
//===----------------------------------------------------------------------===//
-class PathDiagnosticPiece : public RefCountedBaseVPTR {
+class PathDiagnosticPiece : public RefCountedBase<PathDiagnosticPiece> {
public:
- enum Kind { ControlFlow, Event, Macro, Call };
+ enum Kind { ControlFlow, Event, Macro, Call, Note };
enum DisplayHint { Above, Below };
private:
@@ -366,7 +366,7 @@ protected:
PathDiagnosticPiece(Kind k, DisplayHint hint = Below);
public:
- ~PathDiagnosticPiece() override;
+ virtual ~PathDiagnosticPiece();
StringRef getString() const { return str; }
@@ -452,7 +452,8 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const override;
static bool classof(const PathDiagnosticPiece *P) {
- return P->getKind() == Event || P->getKind() == Macro;
+ return P->getKind() == Event || P->getKind() == Macro ||
+ P->getKind() == Note;
}
};
@@ -710,6 +711,23 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const override;
};
+class PathDiagnosticNotePiece: public PathDiagnosticSpotPiece {
+public:
+ PathDiagnosticNotePiece(const PathDiagnosticLocation &Pos, StringRef S,
+ bool AddPosRange = true)
+ : PathDiagnosticSpotPiece(Pos, S, Note, AddPosRange) {}
+
+ ~PathDiagnosticNotePiece() override;
+
+ static inline bool classof(const PathDiagnosticPiece *P) {
+ return P->getKind() == Note;
+ }
+
+ void dump() const override;
+
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
+};
+
/// PathDiagnostic - PathDiagnostic objects represent a single path-sensitive
/// diagnostic. It represents an ordered-collection of PathDiagnosticPieces,
/// each which represent the pieces of the path.
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index 137f238cced9..dd7a6c863be0 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -325,20 +325,13 @@ class RegionChanges {
return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
Explicits, Regions, Call);
}
- template <typename CHECKER>
- static bool _wantsRegionChangeUpdate(void *checker,
- ProgramStateRef state) {
- return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
- }
public:
template <typename CHECKER>
static void _register(CHECKER *checker, CheckerManager &mgr) {
mgr._registerForRegionChanges(
CheckerManager::CheckRegionChangesFunc(checker,
- _checkRegionChanges<CHECKER>),
- CheckerManager::WantsRegionChangeUpdateFunc(checker,
- _wantsRegionChangeUpdate<CHECKER>));
+ _checkRegionChanges<CHECKER>));
}
};
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index b06b74d326de..5af717d90268 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -322,9 +322,6 @@ public:
ExprEngine &Eng,
ProgramPoint::Kind K);
- /// \brief True if at least one checker wants to check region changes.
- bool wantsRegionChangeUpdate(ProgramStateRef state);
-
/// \brief Run checkers for region changes.
///
/// This corresponds to the check::RegionChanges callback.
@@ -452,8 +449,6 @@ public:
const CallEvent *Call)>
CheckRegionChangesFunc;
- typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
-
typedef CheckerFn<ProgramStateRef (ProgramStateRef,
const InvalidatedSymbols &Escaped,
const CallEvent *Call,
@@ -501,8 +496,7 @@ public:
void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
- void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
- WantsRegionChangeUpdateFunc wantUpdateFn);
+ void _registerForRegionChanges(CheckRegionChangesFunc checkfn);
void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
@@ -611,11 +605,7 @@ private:
std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
- struct RegionChangesCheckerInfo {
- CheckRegionChangesFunc CheckFn;
- WantsRegionChangeUpdateFunc WantUpdateFn;
- };
- std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
+ std::vector<CheckRegionChangesFunc> RegionChangesCheckers;
std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
index c9724c08da2d..3b26ed3e1a09 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
@@ -127,7 +127,9 @@ public:
/// Prints the name and description of all checkers in this registry.
/// This output is not intended to be machine-parseable.
- void printHelp(raw_ostream &out, size_t maxNameChars = 30) const ;
+ void printHelp(raw_ostream &out, size_t maxNameChars = 30) const;
+ void printList(raw_ostream &out,
+ SmallVectorImpl<CheckerOptInfo> &opts) const;
private:
mutable CheckerInfoList Checkers;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index 5b007f1531df..0d1a120c9dd4 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -59,6 +59,29 @@ public:
void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); }
};
+class PointerToMemberData: public llvm::FoldingSetNode {
+ const DeclaratorDecl *D;
+ llvm::ImmutableList<const CXXBaseSpecifier *> L;
+
+public:
+ PointerToMemberData(const DeclaratorDecl *D,
+ llvm::ImmutableList<const CXXBaseSpecifier *> L)
+ : D(D), L(L) {}
+
+ typedef llvm::ImmutableList<const CXXBaseSpecifier *>::iterator iterator;
+ iterator begin() const { return L.begin(); }
+ iterator end() const { return L.end(); }
+
+ static void Profile(llvm::FoldingSetNodeID& ID, const DeclaratorDecl *D,
+ llvm::ImmutableList<const CXXBaseSpecifier *> L);
+
+ void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, D, L); }
+ const DeclaratorDecl *getDeclaratorDecl() const {return D;}
+ llvm::ImmutableList<const CXXBaseSpecifier *> getCXXBaseList() const {
+ return L;
+ }
+};
+
class BasicValueFactory {
typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
APSIntSetTy;
@@ -71,8 +94,10 @@ class BasicValueFactory {
void * PersistentSValPairs;
llvm::ImmutableList<SVal>::Factory SValListFactory;
+ llvm::ImmutableList<const CXXBaseSpecifier*>::Factory CXXBaseListFactory;
llvm::FoldingSet<CompoundValData> CompoundValDataSet;
llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet;
+ llvm::FoldingSet<PointerToMemberData> PointerToMemberDataSet;
// This is private because external clients should use the factory
// method that takes a QualType.
@@ -81,7 +106,8 @@ class BasicValueFactory {
public:
BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator &Alloc)
: Ctx(ctx), BPAlloc(Alloc), PersistentSVals(nullptr),
- PersistentSValPairs(nullptr), SValListFactory(Alloc) {}
+ PersistentSValPairs(nullptr), SValListFactory(Alloc),
+ CXXBaseListFactory(Alloc) {}
~BasicValueFactory();
@@ -172,14 +198,32 @@ public:
const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store,
const TypedValueRegion *region);
+ const PointerToMemberData *getPointerToMemberData(
+ const DeclaratorDecl *DD,
+ llvm::ImmutableList<const CXXBaseSpecifier *> L);
+
llvm::ImmutableList<SVal> getEmptySValList() {
return SValListFactory.getEmptyList();
}
- llvm::ImmutableList<SVal> consVals(SVal X, llvm::ImmutableList<SVal> L) {
+ llvm::ImmutableList<SVal> prependSVal(SVal X, llvm::ImmutableList<SVal> L) {
return SValListFactory.add(X, L);
}
+ llvm::ImmutableList<const CXXBaseSpecifier *> getEmptyCXXBaseList() {
+ return CXXBaseListFactory.getEmptyList();
+ }
+
+ llvm::ImmutableList<const CXXBaseSpecifier *> prependCXXBase(
+ const CXXBaseSpecifier *CBS,
+ llvm::ImmutableList<const CXXBaseSpecifier *> L) {
+ return CXXBaseListFactory.add(CBS, L);
+ }
+
+ const clang::ento::PointerToMemberData *accumCXXBase(
+ llvm::iterator_range<CastExpr::path_const_iterator> PathRange,
+ const nonloc::PointerToMember &PTM);
+
const llvm::APSInt* evalAPSInt(BinaryOperator::Opcode Op,
const llvm::APSInt& V1,
const llvm::APSInt& V2);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
index 9a858c2cfb01..6651382d9e95 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -36,7 +36,7 @@ public:
/// Construct a ConstraintVal indicating the constraint is underconstrained.
ConditionTruthVal() {}
-
+
/// Return true if the constraint is perfectly constrained to 'true'.
bool isConstrainedTrue() const {
return Val.hasValue() && Val.getValue();
@@ -58,11 +58,11 @@ public:
return !Val.hasValue();
}
};
-
+
class ConstraintManager {
public:
ConstraintManager() : NotifyAssumeClients(true) {}
-
+
virtual ~ConstraintManager();
virtual ProgramStateRef assume(ProgramStateRef state,
DefinedSVal Cond,
@@ -99,25 +99,26 @@ public:
return ProgramStatePair(StTrue, StFalse);
}
- virtual ProgramStateRef assumeWithinInclusiveRange(ProgramStateRef State,
- NonLoc Value,
- const llvm::APSInt &From,
- const llvm::APSInt &To,
- bool InBound) = 0;
+ virtual ProgramStateRef assumeInclusiveRange(ProgramStateRef State,
+ NonLoc Value,
+ const llvm::APSInt &From,
+ const llvm::APSInt &To,
+ bool InBound) = 0;
- virtual ProgramStatePair assumeWithinInclusiveRangeDual(
- ProgramStateRef State, NonLoc Value, const llvm::APSInt &From,
- const llvm::APSInt &To) {
- ProgramStateRef StInRange = assumeWithinInclusiveRange(State, Value, From,
- To, true);
+ virtual ProgramStatePair assumeInclusiveRangeDual(ProgramStateRef State,
+ NonLoc Value,
+ const llvm::APSInt &From,
+ const llvm::APSInt &To) {
+ ProgramStateRef StInRange =
+ assumeInclusiveRange(State, Value, From, To, true);
// If StTrue is infeasible, asserting the falseness of Cond is unnecessary
// because the existing constraints already establish this.
if (!StInRange)
return ProgramStatePair((ProgramStateRef)nullptr, State);
- ProgramStateRef StOutOfRange = assumeWithinInclusiveRange(State, Value,
- From, To, false);
+ ProgramStateRef StOutOfRange =
+ assumeInclusiveRange(State, Value, From, To, false);
if (!StOutOfRange) {
// We are careful to return the original state, /not/ StTrue,
// because we want to avoid having callers generate a new node
@@ -147,7 +148,7 @@ public:
const char *sep) = 0;
virtual void EndPath(ProgramStateRef state) {}
-
+
/// Convenience method to query the state to see if a symbol is null or
/// not null, or if neither assumption can be made.
ConditionTruthVal isNull(ProgramStateRef State, SymbolRef Sym) {
@@ -173,7 +174,7 @@ protected:
virtual bool canReasonAbout(SVal X) const = 0;
/// Returns whether or not a symbol is known to be null ("true"), known to be
- /// non-null ("false"), or may be either ("underconstrained").
+ /// non-null ("false"), or may be either ("underconstrained").
virtual ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym);
};
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 0fa736d76c99..12ec5b6c64a4 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -109,7 +109,8 @@ private:
CoreEngine(const CoreEngine &) = delete;
void operator=(const CoreEngine &) = delete;
- ExplodedNode *generateCallExitBeginNode(ExplodedNode *N);
+ ExplodedNode *generateCallExitBeginNode(ExplodedNode *N,
+ const ReturnStmt *RS);
public:
/// Construct a CoreEngine object to analyze the provided CFG.
@@ -172,7 +173,7 @@ public:
/// \brief enqueue the nodes corresponding to the end of function onto the
/// end of path / work list.
- void enqueueEndOfFunction(ExplodedNodeSet &Set);
+ void enqueueEndOfFunction(ExplodedNodeSet &Set, const ReturnStmt *RS);
/// \brief Enqueue a single node created as a result of statement processing.
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index 549db1a6a1e8..a710ae68be60 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -28,7 +28,6 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include <memory>
@@ -451,57 +450,35 @@ public:
namespace llvm {
template<> struct GraphTraits<clang::ento::ExplodedNode*> {
- typedef clang::ento::ExplodedNode NodeType;
typedef clang::ento::ExplodedNode *NodeRef;
- typedef NodeType::succ_iterator ChildIteratorType;
- typedef llvm::df_iterator<NodeType*> nodes_iterator;
+ typedef clang::ento::ExplodedNode::succ_iterator ChildIteratorType;
+ typedef llvm::df_iterator<NodeRef> nodes_iterator;
- static inline NodeType* getEntryNode(NodeType* N) {
- return N;
- }
+ static NodeRef getEntryNode(NodeRef N) { return N; }
- static inline ChildIteratorType child_begin(NodeType* N) {
- return N->succ_begin();
- }
+ static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
- static inline ChildIteratorType child_end(NodeType* N) {
- return N->succ_end();
- }
+ static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
- static inline nodes_iterator nodes_begin(NodeType* N) {
- return df_begin(N);
- }
+ static nodes_iterator nodes_begin(NodeRef N) { return df_begin(N); }
- static inline nodes_iterator nodes_end(NodeType* N) {
- return df_end(N);
- }
+ static nodes_iterator nodes_end(NodeRef N) { return df_end(N); }
};
template<> struct GraphTraits<const clang::ento::ExplodedNode*> {
- typedef const clang::ento::ExplodedNode NodeType;
typedef const clang::ento::ExplodedNode *NodeRef;
- typedef NodeType::const_succ_iterator ChildIteratorType;
- typedef llvm::df_iterator<NodeType*> nodes_iterator;
+ typedef clang::ento::ExplodedNode::const_succ_iterator ChildIteratorType;
+ typedef llvm::df_iterator<NodeRef> nodes_iterator;
- static inline NodeType* getEntryNode(NodeType* N) {
- return N;
- }
+ static NodeRef getEntryNode(NodeRef N) { return N; }
- static inline ChildIteratorType child_begin(NodeType* N) {
- return N->succ_begin();
- }
+ static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
- static inline ChildIteratorType child_end(NodeType* N) {
- return N->succ_end();
- }
+ static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
- static inline nodes_iterator nodes_begin(NodeType* N) {
- return df_begin(N);
- }
+ static nodes_iterator nodes_begin(NodeRef N) { return df_begin(N); }
- static inline nodes_iterator nodes_end(NodeType* N) {
- return df_end(N);
- }
+ static nodes_iterator nodes_end(NodeRef N) { return df_end(N); }
};
} // end llvm namespace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 50d85057041d..591b112d60ac 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -262,7 +262,8 @@ public:
/// Called by CoreEngine. Used to notify checkers that processing a
/// function has ended. Called for both inlined and and top-level functions.
void processEndOfFunction(NodeBuilderContext& BC,
- ExplodedNode *Pred) override;
+ ExplodedNode *Pred,
+ const ReturnStmt *RS = nullptr) override;
/// Remove dead bindings/symbols before exiting a function.
void removeDeadOnEndOfFunction(NodeBuilderContext& BC,
@@ -285,10 +286,6 @@ public:
ProgramStateRef processAssume(ProgramStateRef state, SVal cond,
bool assumption) override;
- /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
- /// region change should trigger a processRegionChanges update.
- bool wantsRegionChangeUpdate(ProgramStateRef state) override;
-
/// processRegionChanges - Called by ProgramStateManager whenever a change is made
/// to the store. Used to update checkers that track region values.
ProgramStateRef
@@ -482,6 +479,22 @@ public:
return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X;
}
+ ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex,
+ const LocationContext *LCtx, QualType T,
+ QualType ExTy, const CastExpr *CastE,
+ StmtNodeBuilder &Bldr,
+ ExplodedNode *Pred);
+
+ ProgramStateRef handleLVectorSplat(ProgramStateRef state,
+ const LocationContext *LCtx,
+ const CastExpr *CastE,
+ StmtNodeBuilder &Bldr,
+ ExplodedNode *Pred);
+
+ void handleUOExtension(ExplodedNodeSet::iterator I,
+ const UnaryOperator* U,
+ StmtNodeBuilder &Bldr);
+
public:
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 40cd4e4b3c4e..da4b964424c3 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -1277,15 +1277,9 @@ public:
private:
template <typename RegionTy, typename A1>
- RegionTy* getRegion(const A1 a1);
-
- template <typename RegionTy, typename A1>
RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
template <typename RegionTy, typename A1, typename A2>
- RegionTy* getRegion(const A1 a1, const A2 a2);
-
- template <typename RegionTy, typename A1, typename A2>
RegionTy* getSubRegion(const A1 a1, const A2 a2,
const MemRegion* superRegion);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index f89747ee1756..463b375fda30 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -24,7 +24,6 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Allocator.h"
#include <utility>
@@ -99,18 +98,18 @@ public:
/// This ctor is used when creating the first ProgramState object.
ProgramState(ProgramStateManager *mgr, const Environment& env,
StoreRef st, GenericDataMap gdm);
-
+
/// Copy ctor - We must explicitly define this or else the "Next" ptr
/// in FoldingSetNode will also get copied.
ProgramState(const ProgramState &RHS);
-
+
~ProgramState();
/// Return the ProgramStateManager associated with this state.
ProgramStateManager &getStateManager() const {
return *stateMgr;
}
-
+
/// Return the ConstraintManager.
ConstraintManager &getConstraintManager() const;
@@ -122,7 +121,7 @@ public:
/// is a mapping from locations to values.
Store getStore() const { return store; }
-
+
/// getGDM - Return the generic data map associated with this state.
GenericDataMap getGDM() const { return GDM; }
@@ -198,10 +197,10 @@ public:
///
/// This returns a new state with the added constraint on \p cond.
/// If no new state is feasible, NULL is returned.
- ProgramStateRef assumeWithinInclusiveRange(DefinedOrUnknownSVal Val,
- const llvm::APSInt &From,
- const llvm::APSInt &To,
- bool assumption) const;
+ ProgramStateRef assumeInclusiveRange(DefinedOrUnknownSVal Val,
+ const llvm::APSInt &From,
+ const llvm::APSInt &To,
+ bool assumption) const;
/// Assumes given range both "true" and "false" for \p Val, and returns both
/// corresponding states (respectively).
@@ -209,14 +208,13 @@ public:
/// This is more efficient than calling assume() twice. Note that one (but not
/// both) of the returned states may be NULL.
std::pair<ProgramStateRef, ProgramStateRef>
- assumeWithinInclusiveRange(DefinedOrUnknownSVal Val, const llvm::APSInt &From,
- const llvm::APSInt &To) const;
+ assumeInclusiveRange(DefinedOrUnknownSVal Val, const llvm::APSInt &From,
+ const llvm::APSInt &To) const;
-
/// \brief Check if the given SVal is constrained to zero or is a zero
/// constant.
ConditionTruthVal isNull(SVal V) const;
-
+
/// Utility method for getting regions.
const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
@@ -255,7 +253,7 @@ public:
/// \param IS the set of invalidated symbols.
/// \param Call if non-null, the invalidated regions represent parameters to
/// the call and should be considered directly invalidated.
- /// \param ITraits information about special handling for a particular
+ /// \param ITraits information about special handling for a particular
/// region/symbol.
ProgramStateRef
invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E,
@@ -279,7 +277,7 @@ public:
/// Get the lvalue for a variable reference.
Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
- Loc getLValue(const CompoundLiteralExpr *literal,
+ Loc getLValue(const CompoundLiteralExpr *literal,
const LocationContext *LC) const;
/// Get the lvalue for an ivar reference.
@@ -296,7 +294,7 @@ public:
/// Returns the SVal bound to the statement 'S' in the state's environment.
SVal getSVal(const Stmt *S, const LocationContext *LCtx) const;
-
+
SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const;
/// \brief Return the value bound to the specified location.
@@ -311,7 +309,7 @@ public:
SVal getSVal(const MemRegion* R) const;
SVal getSValAsScalarOrLoc(const MemRegion *R) const;
-
+
/// \brief Visits the symbols reachable from the given SVal using the provided
/// SymbolVisitor.
///
@@ -320,22 +318,22 @@ public:
/// visitor to avoid repeated initialization cost.
/// \sa ScanReachableSymbols
bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
-
+
/// \brief Visits the symbols reachable from the SVals in the given range
/// using the provided SymbolVisitor.
bool scanReachableSymbols(const SVal *I, const SVal *E,
SymbolVisitor &visitor) const;
-
+
/// \brief Visits the symbols reachable from the regions in the given
/// MemRegions range using the provided SymbolVisitor.
- bool scanReachableSymbols(const MemRegion * const *I,
+ bool scanReachableSymbols(const MemRegion * const *I,
const MemRegion * const *E,
SymbolVisitor &visitor) const;
template <typename CB> CB scanReachableSymbols(SVal val) const;
template <typename CB> CB scanReachableSymbols(const SVal *beg,
const SVal *end) const;
-
+
template <typename CB> CB
scanReachableSymbols(const MemRegion * const *beg,
const MemRegion * const *end) const;
@@ -470,7 +468,7 @@ private:
/// A BumpPtrAllocator to allocate states.
llvm::BumpPtrAllocator &Alloc;
-
+
/// A vector of ProgramStates that we can reuse.
std::vector<ProgramState *> freeStates;
@@ -633,9 +631,9 @@ public:
inline ConstraintManager &ProgramState::getConstraintManager() const {
return stateMgr->getConstraintManager();
}
-
+
inline const VarRegion* ProgramState::getRegion(const VarDecl *D,
- const LocationContext *LC) const
+ const LocationContext *LC) const
{
return getStateManager().getRegionManager().getVarRegion(D, LC);
}
@@ -648,7 +646,7 @@ inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond,
return getStateManager().ConstraintMgr
->assume(this, Cond.castAs<DefinedSVal>(), Assumption);
}
-
+
inline std::pair<ProgramStateRef , ProgramStateRef >
ProgramState::assume(DefinedOrUnknownSVal Cond) const {
if (Cond.isUnknown())
@@ -658,31 +656,29 @@ ProgramState::assume(DefinedOrUnknownSVal Cond) const {
->assumeDual(this, Cond.castAs<DefinedSVal>());
}
-inline ProgramStateRef
-ProgramState::assumeWithinInclusiveRange(DefinedOrUnknownSVal Val,
- const llvm::APSInt &From,
- const llvm::APSInt &To,
- bool Assumption) const {
+inline ProgramStateRef ProgramState::assumeInclusiveRange(
+ DefinedOrUnknownSVal Val, const llvm::APSInt &From, const llvm::APSInt &To,
+ bool Assumption) const {
if (Val.isUnknown())
return this;
assert(Val.getAs<NonLoc>() && "Only NonLocs are supported!");
- return getStateManager().ConstraintMgr->assumeWithinInclusiveRange(
- this, Val.castAs<NonLoc>(), From, To, Assumption);
+ return getStateManager().ConstraintMgr->assumeInclusiveRange(
+ this, Val.castAs<NonLoc>(), From, To, Assumption);
}
inline std::pair<ProgramStateRef, ProgramStateRef>
-ProgramState::assumeWithinInclusiveRange(DefinedOrUnknownSVal Val,
- const llvm::APSInt &From,
- const llvm::APSInt &To) const {
+ProgramState::assumeInclusiveRange(DefinedOrUnknownSVal Val,
+ const llvm::APSInt &From,
+ const llvm::APSInt &To) const {
if (Val.isUnknown())
return std::make_pair(this, this);
assert(Val.getAs<NonLoc>() && "Only NonLocs are supported!");
- return getStateManager().ConstraintMgr
- ->assumeWithinInclusiveRangeDual(this, Val.castAs<NonLoc>(), From, To);
+ return getStateManager().ConstraintMgr->assumeInclusiveRangeDual(
+ this, Val.castAs<NonLoc>(), From, To);
}
inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
@@ -811,7 +807,7 @@ CB ProgramState::scanReachableSymbols(SVal val) const {
scanReachableSymbols(val, cb);
return cb;
}
-
+
template <typename CB>
CB ProgramState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
CB cb(this);
@@ -828,8 +824,9 @@ CB ProgramState::scanReachableSymbols(const MemRegion * const *beg,
}
/// \class ScanReachableSymbols
-/// A Utility class that allows to visit the reachable symbols using a custom
-/// SymbolVisitor.
+/// A utility class that visits the reachable symbols using a custom
+/// SymbolVisitor. Terminates recursive traversal when the visitor function
+/// returns false.
class ScanReachableSymbols {
typedef llvm::DenseSet<const void*> VisitedItems;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
index 6b4da7db244d..a04fa9005955 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This file defines partial implementations of template specializations of
-// the class ProgramStateTrait<>. ProgramStateTrait<> is used by ProgramState
+// the class ProgramStateTrait<>. ProgramStateTrait<> is used by ProgramState
// to implement set/get methods for manipulating a ProgramState's
// generic data map.
//
@@ -81,6 +81,10 @@ namespace ento {
return F.remove(B, K);
}
+ static bool Contains(data_type B, key_type K) {
+ return B.contains(K);
+ }
+
static inline context_type MakeContext(void *p) {
return *((typename data_type::Factory*) p);
}
@@ -185,7 +189,7 @@ namespace ento {
}
};
-
+
// Partial specialization for bool.
template <> struct ProgramStatePartialTrait<bool> {
typedef bool data_type;
@@ -198,7 +202,7 @@ namespace ento {
return (void*) (uintptr_t) d;
}
};
-
+
// Partial specialization for unsigned.
template <> struct ProgramStatePartialTrait<unsigned> {
typedef unsigned data_type;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index e4be349c0263..a4c01fc45334 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -198,9 +198,13 @@ public:
DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(
SymbolRef parentSymbol, const TypedValueRegion *region);
- DefinedSVal getMetadataSymbolVal(
- const void *symbolTag, const MemRegion *region,
- const Expr *expr, QualType type, unsigned count);
+ DefinedSVal getMetadataSymbolVal(const void *symbolTag,
+ const MemRegion *region,
+ const Expr *expr, QualType type,
+ const LocationContext *LCtx,
+ unsigned count);
+
+ DefinedSVal getMemberPointer(const DeclaratorDecl *DD);
DefinedSVal getFunctionPointer(const FunctionDecl *func);
@@ -224,6 +228,14 @@ public:
BasicVals.getLazyCompoundValData(store, region));
}
+ NonLoc makePointerToMember(const DeclaratorDecl *DD) {
+ return nonloc::PointerToMember(DD);
+ }
+
+ NonLoc makePointerToMember(const PointerToMemberData *PTMD) {
+ return nonloc::PointerToMember(PTMD);
+ }
+
NonLoc makeZeroArrayIndex() {
return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy));
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
index 2faec670b338..a0e309937892 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
@@ -66,6 +66,7 @@ ABSTRACT_SVAL(DefinedOrUnknownSVal, SVal)
NONLOC_SVAL(LazyCompoundVal, NonLoc)
NONLOC_SVAL(LocAsInteger, NonLoc)
NONLOC_SVAL(SymbolVal, NonLoc)
+ NONLOC_SVAL(PointerToMember, NonLoc)
#undef NONLOC_SVAL
#undef LOC_SVAL
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index dbc7c99c6101..cc3c02a02c64 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -32,6 +32,7 @@ namespace ento {
class CompoundValData;
class LazyCompoundValData;
+class PointerToMemberData;
class ProgramState;
class BasicValueFactory;
class MemRegion;
@@ -459,6 +460,51 @@ private:
}
};
+/// \brief Value representing pointer-to-member.
+///
+/// This value is qualified as NonLoc because neither loading nor storing
+/// operations are aplied to it. Instead, the analyzer uses the L-value coming
+/// from pointer-to-member applied to an object.
+/// This SVal is represented by a DeclaratorDecl which can be a member function
+/// pointer or a member data pointer and a list of CXXBaseSpecifiers. This list
+/// is required to accumulate the pointer-to-member cast history to figure out
+/// the correct subobject field.
+class PointerToMember : public NonLoc {
+ friend class ento::SValBuilder;
+
+public:
+ typedef llvm::PointerUnion<const DeclaratorDecl *,
+ const PointerToMemberData *> PTMDataType;
+ const PTMDataType getPTMData() const {
+ return PTMDataType::getFromOpaqueValue(const_cast<void *>(Data));
+ }
+ bool isNullMemberPointer() const {
+ return getPTMData().isNull();
+ }
+ const DeclaratorDecl *getDecl() const;
+ template<typename AdjustedDecl>
+ const AdjustedDecl* getDeclAs() const {
+ return dyn_cast_or_null<AdjustedDecl>(getDecl());
+ }
+ typedef llvm::ImmutableList<const CXXBaseSpecifier *>::iterator iterator;
+ iterator begin() const;
+ iterator end() const;
+
+private:
+ explicit PointerToMember(const PTMDataType D)
+ : NonLoc(PointerToMemberKind, D.getOpaqueValue()) {}
+ friend class SVal;
+ PointerToMember() {}
+ static bool isKind(const SVal& V) {
+ return V.getBaseKind() == NonLocKind &&
+ V.getSubKind() == PointerToMemberKind;
+ }
+
+ static bool isKind(const NonLoc& V) {
+ return V.getSubKind() == PointerToMemberKind;
+ }
+};
+
} // end namespace ento::nonloc
//==------------------------------------------------------------------------==//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index a03b6306a0ed..fa7d3f72abf1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -18,7 +18,6 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/Optional.h"
namespace clang {
@@ -124,15 +123,18 @@ public:
SVal evalDerivedToBase(SVal Derived, QualType DerivedPtrType,
bool IsVirtual);
- /// \brief Evaluates C++ dynamic_cast cast.
+ /// \brief Attempts to do a down cast. Used to model BaseToDerived and C++
+ /// dynamic_cast.
/// The callback may result in the following 3 scenarios:
/// - Successful cast (ex: derived is subclass of base).
/// - Failed cast (ex: derived is definitely not a subclass of base).
+ /// The distinction of this case from the next one is necessary to model
+ /// dynamic_cast.
/// - We don't know (base is a symbolic region and we don't have
/// enough info to determine if the cast will succeed at run time).
/// The function returns an SVal representing the derived class; it's
/// valid only if Failed flag is set to false.
- SVal evalDynamicCast(SVal Base, QualType DerivedPtrType, bool &Failed);
+ SVal attemptDownCast(SVal Base, QualType DerivedPtrType, bool &Failed);
const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index 1a731cf865ea..581ef206cff3 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -109,7 +109,8 @@ public:
/// Called by CoreEngine. Used to notify checkers that processing a
/// function has ended. Called for both inlined and and top-level functions.
virtual void processEndOfFunction(NodeBuilderContext& BC,
- ExplodedNode *Pred) = 0;
+ ExplodedNode *Pred,
+ const ReturnStmt *RS = nullptr) = 0;
// Generate the entry node of the callee.
virtual void processCallEnter(NodeBuilderContext& BC, CallEnter CE,
@@ -123,10 +124,6 @@ public:
virtual ProgramStateRef processAssume(ProgramStateRef state,
SVal cond, bool assumption) = 0;
- /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
- /// region change should trigger a processRegionChanges update.
- virtual bool wantsRegionChangeUpdate(ProgramStateRef state) = 0;
-
/// processRegionChanges - Called by ProgramStateManager whenever a change is
/// made to the store. Used to update checkers that track region values.
virtual ProgramStateRef
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h
index ed878515988a..52d78b6a3c82 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h
@@ -15,9 +15,6 @@
#ifndef LLVM_CLANG_GR_SUMMARY
#define LLVM_CLANG_GR_SUMMARY
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Support/Allocator.h"
-
namespace clang {
namespace ento {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index 087430583e0c..f00dce568e3a 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -186,15 +186,18 @@ class SymbolMetadata : public SymbolData {
const MemRegion* R;
const Stmt *S;
QualType T;
+ const LocationContext *LCtx;
unsigned Count;
const void *Tag;
public:
SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt *s, QualType t,
- unsigned count, const void *tag)
- : SymbolData(SymbolMetadataKind, sym), R(r), S(s), T(t), Count(count), Tag(tag) {}
+ const LocationContext *LCtx, unsigned count, const void *tag)
+ : SymbolData(SymbolMetadataKind, sym), R(r), S(s), T(t), LCtx(LCtx),
+ Count(count), Tag(tag) {}
const MemRegion *getRegion() const { return R; }
const Stmt *getStmt() const { return S; }
+ const LocationContext *getLocationContext() const { return LCtx; }
unsigned getCount() const { return Count; }
const void *getTag() const { return Tag; }
@@ -203,18 +206,19 @@ public:
void dumpToStream(raw_ostream &os) const override;
static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R,
- const Stmt *S, QualType T, unsigned Count,
- const void *Tag) {
+ const Stmt *S, QualType T, const LocationContext *LCtx,
+ unsigned Count, const void *Tag) {
profile.AddInteger((unsigned) SymbolMetadataKind);
profile.AddPointer(R);
profile.AddPointer(S);
profile.Add(T);
+ profile.AddPointer(LCtx);
profile.AddInteger(Count);
profile.AddPointer(Tag);
}
void Profile(llvm::FoldingSetNodeID& profile) override {
- Profile(profile, R, S, T, Count, Tag);
+ Profile(profile, R, S, T, LCtx, Count, Tag);
}
// Implement isa<T> support.
@@ -435,7 +439,9 @@ public:
/// VisitCount can be used to differentiate regions corresponding to
/// different loop iterations, thus, making the symbol path-dependent.
const SymbolMetadata *getMetadataSymbol(const MemRegion *R, const Stmt *S,
- QualType T, unsigned VisitCount,
+ QualType T,
+ const LocationContext *LCtx,
+ unsigned VisitCount,
const void *SymbolTag = nullptr);
const SymbolCast* getCastSymbol(const SymExpr *Operand,
diff --git a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
index 37ea05fb99cf..a9dad6c5e9a2 100644
--- a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
+++ b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
@@ -17,9 +17,7 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/Basic/LLVM.h"
-#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
-#include <string>
+#include <memory>
namespace clang {
@@ -29,6 +27,7 @@ class CodeInjector;
class CompilerInstance;
namespace ento {
+class PathDiagnosticConsumer;
class CheckerManager;
class AnalysisASTConsumer : public ASTConsumer {
diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
index 36afb4bc5d73..e66d48b1be1d 100644
--- a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
+++ b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
@@ -17,6 +17,7 @@
namespace clang {
class Stmt;
+class AnalyzerOptions;
namespace ento {
@@ -52,6 +53,8 @@ private:
};
void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins);
+void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins,
+ const AnalyzerOptions &opts);
} // end GR namespace
diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h
index 08a0ffec9d63..4611d3cdae5e 100644
--- a/include/clang/Tooling/CompilationDatabase.h
+++ b/include/clang/Tooling/CompilationDatabase.h
@@ -43,10 +43,11 @@ namespace tooling {
struct CompileCommand {
CompileCommand() {}
CompileCommand(Twine Directory, Twine Filename,
- std::vector<std::string> CommandLine)
+ std::vector<std::string> CommandLine, Twine Output)
: Directory(Directory.str()),
Filename(Filename.str()),
- CommandLine(std::move(CommandLine)) {}
+ CommandLine(std::move(CommandLine)),
+ Output(Output.str()){}
/// \brief The working directory the command was executed from.
std::string Directory;
@@ -57,6 +58,9 @@ struct CompileCommand {
/// \brief The command line that was executed.
std::vector<std::string> CommandLine;
+ /// The output file associated with the command.
+ std::string Output;
+
/// \brief An optional mapping from each file's path to its content for all
/// files needed for the compilation that are not available via the file
/// system.
diff --git a/include/clang/Tooling/Core/Replacement.h b/include/clang/Tooling/Core/Replacement.h
index 4815302ee455..95dc3cd6e763 100644
--- a/include/clang/Tooling/Core/Replacement.h
+++ b/include/clang/Tooling/Core/Replacement.h
@@ -19,13 +19,17 @@
#ifndef LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
#define LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
+#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
#include <map>
#include <set>
#include <string>
+#include <system_error>
#include <vector>
namespace clang {
@@ -123,37 +127,185 @@ public:
/// \brief Returns a human readable string representation.
std::string toString() const;
- private:
- void setFromSourceLocation(const SourceManager &Sources,
- SourceLocation Start, unsigned Length,
- StringRef ReplacementText);
- void setFromSourceRange(const SourceManager &Sources,
- const CharSourceRange &Range,
- StringRef ReplacementText,
- const LangOptions &LangOpts);
+private:
+ void setFromSourceLocation(const SourceManager &Sources, SourceLocation Start,
+ unsigned Length, StringRef ReplacementText);
+ void setFromSourceRange(const SourceManager &Sources,
+ const CharSourceRange &Range,
+ StringRef ReplacementText,
+ const LangOptions &LangOpts);
std::string FilePath;
Range ReplacementRange;
std::string ReplacementText;
};
+enum class replacement_error {
+ fail_to_apply = 0,
+ wrong_file_path,
+ overlap_conflict,
+ insert_conflict,
+};
+
+/// \brief Carries extra error information in replacement-related llvm::Error,
+/// e.g. fail applying replacements and replacements conflict.
+class ReplacementError : public llvm::ErrorInfo<ReplacementError> {
+public:
+ ReplacementError(replacement_error Err) : Err(Err) {}
+
+ /// \brief Constructs an error related to an existing replacement.
+ ReplacementError(replacement_error Err, Replacement Existing)
+ : Err(Err), ExistingReplacement(std::move(Existing)) {}
+
+ /// \brief Constructs an error related to a new replacement and an existing
+ /// replacement in a set of replacements.
+ ReplacementError(replacement_error Err, Replacement New, Replacement Existing)
+ : Err(Err), NewReplacement(std::move(New)),
+ ExistingReplacement(std::move(Existing)) {}
+
+ std::string message() const override;
+
+ void log(raw_ostream &OS) const override { OS << message(); }
+
+ replacement_error get() const { return Err; }
+
+ static char ID;
+
+ const llvm::Optional<Replacement> &getNewReplacement() const {
+ return NewReplacement;
+ }
+
+ const llvm::Optional<Replacement> &getExistingReplacement() const {
+ return ExistingReplacement;
+ }
+
+private:
+ // Users are not expected to use error_code.
+ std::error_code convertToErrorCode() const override {
+ return llvm::inconvertibleErrorCode();
+ }
+
+ replacement_error Err;
+ // A new replacement, which is to expected be added into a set of
+ // replacements, that is causing problem.
+ llvm::Optional<Replacement> NewReplacement;
+ // An existing replacement in a replacements set that is causing problem.
+ llvm::Optional<Replacement> ExistingReplacement;
+};
+
/// \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 Maintains a set of replacements that are conflict-free.
+/// Two replacements are considered conflicts if they overlap or have the same
+/// offset (i.e. order-dependent).
+class Replacements {
+ private:
+ typedef std::set<Replacement> ReplacementsImpl;
+
+ public:
+ typedef ReplacementsImpl::const_iterator const_iterator;
+ typedef ReplacementsImpl::const_reverse_iterator const_reverse_iterator;
+
+ Replacements() = default;
+
+ explicit Replacements(const Replacement &R) { Replaces.insert(R); }
+
+ /// \brief Adds a new replacement \p R to the current set of replacements.
+ /// \p R must have the same file path as all existing replacements.
+ /// Returns `success` if the replacement is successfully inserted; otherwise,
+ /// it returns an llvm::Error, i.e. there is a conflict between R and the
+ /// existing replacements (i.e. they are order-dependent) or R's file path is
+ /// different from the filepath of existing replacements. Callers must
+ /// explicitly check the Error returned, and the returned error can be
+ /// converted to a string message with `llvm::toString()`. This prevents users
+ /// from adding order-dependent replacements. To control the order in which
+ /// order-dependent replacements are applied, use merge({R}) with R referring
+ /// to the changed code after applying all existing replacements.
+ /// Two replacements A and B are considered order-independent if applying them
+ /// in either order produces the same result. Note that the range of the
+ /// replacement that is applied later still refers to the original code.
+ /// These include (but not restricted to) replacements that:
+ /// - don't overlap (being directly adjacent is fine) and
+ /// - are overlapping deletions.
+ /// - are insertions at the same offset and applying them in either order
+ /// has the same effect, i.e. X + Y = Y + X when inserting X and Y
+ /// respectively.
+ /// - are identical replacements, i.e. applying the same replacement twice
+ /// is equivalent to applying it once.
+ /// Examples:
+ /// 1. Replacement A(0, 0, "a") and B(0, 0, "aa") are order-independent since
+ /// applying them in either order gives replacement (0, 0, "aaa").
+ /// However, A(0, 0, "a") and B(0, 0, "b") are order-dependent since
+ /// applying A first gives (0, 0, "ab") while applying B first gives (B, A,
+ /// "ba").
+ /// 2. Replacement A(0, 2, "123") and B(0, 2, "123") are order-independent
+ /// since applying them in either order gives (0, 2, "123").
+ /// 3. Replacement A(0, 3, "123") and B(2, 3, "321") are order-independent
+ /// since either order gives (0, 5, "12321").
+ /// 4. Replacement A(0, 3, "ab") and B(0, 3, "ab") are order-independent since
+ /// applying the same replacement twice is equivalent to applying it once.
+ /// Replacements with offset UINT_MAX are special - we do not detect conflicts
+ /// for such replacements since users may add them intentionally as a special
+ /// category of replacements.
+ llvm::Error add(const Replacement &R);
+
+ /// \brief Merges \p Replaces into the current replacements. \p Replaces
+ /// refers to code after applying the current replacements.
+ Replacements merge(const Replacements &Replaces) const;
+
+ // Returns the affected ranges in the changed code.
+ std::vector<Range> getAffectedRanges() const;
+
+ // Returns the new offset in the code after replacements being applied.
+ // Note that if there is an insertion at Offset in the current replacements,
+ // \p Offset will be shifted to Offset + Length in inserted text.
+ unsigned getShiftedCodePosition(unsigned Position) const;
+
+ unsigned size() const { return Replaces.size(); }
+
+ void clear() { Replaces.clear(); }
+
+ bool empty() const { return Replaces.empty(); }
+
+ const_iterator begin() const { return Replaces.begin(); }
+
+ const_iterator end() const { return Replaces.end(); }
+
+ const_reverse_iterator rbegin() const { return Replaces.rbegin(); }
+
+ const_reverse_iterator rend() const { return Replaces.rend(); }
+
+ bool operator==(const Replacements &RHS) const {
+ return Replaces == RHS.Replaces;
+ }
-/// \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);
+
+private:
+ Replacements(const_iterator Begin, const_iterator End)
+ : Replaces(Begin, End) {}
+
+ // Returns `R` with new range that refers to code after `Replaces` being
+ // applied.
+ Replacement getReplacementInChangedCode(const Replacement &R) const;
+
+ // Returns a set of replacements that is equivalent to the current
+ // replacements by merging all adjacent replacements. Two sets of replacements
+ // are considered equivalent if they have the same effect when they are
+ // applied.
+ Replacements getCanonicalReplacements() const;
+
+ // If `R` and all existing replacements are order-indepedent, then merge it
+ // with `Replaces` and returns the merged replacements; otherwise, returns an
+ // error.
+ llvm::Expected<Replacements>
+ mergeIfOrderIndependent(const Replacement &R) const;
+
+ ReplacementsImpl Replaces;
+};
/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
///
@@ -161,8 +313,7 @@ bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
/// other applications.
///
/// \returns true if all replacements apply. false otherwise.
-bool applyAllReplacements(const std::vector<Replacement> &Replaces,
- Rewriter &Rewrite);
+bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
/// \brief Applies all replacements in \p Replaces to \p Code.
///
@@ -174,27 +325,6 @@ bool applyAllReplacements(const std::vector<Replacement> &Replaces,
llvm::Expected<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.
@@ -208,14 +338,6 @@ struct TranslationUnitReplacements {
std::vector<Replacement> Replacements;
};
-/// \brief Calculates the ranges in a single file that are affected by the
-/// Replacements. Overlapping ranges will be merged.
-///
-/// \pre Replacements must be for the same file.
-///
-/// \returns a non-overlapping and sorted ranges.
-std::vector<Range> calculateChangedRanges(const Replacements &Replaces);
-
/// \brief Calculates the new ranges after \p Replaces are applied. These
/// include both the original \p Ranges and the affected ranges of \p Replaces
/// in the new code.
@@ -228,16 +350,12 @@ std::vector<Range>
calculateRangesAfterReplacements(const Replacements &Replaces,
const std::vector<Range> &Ranges);
-/// \brief Groups a random set of replacements by file path. Replacements
-/// related to the same file entry are put into the same vector.
-std::map<std::string, Replacements>
-groupReplacementsByFile(const Replacements &Replaces);
-
-/// \brief Merges two sets of replacements with the second set referring to the
-/// code after applying the first set. Within both 'First' and 'Second',
-/// replacements must not overlap.
-Replacements mergeReplacements(const Replacements &First,
- const Replacements &Second);
+/// \brief If there are multiple <File, Replacements> pairs with the same file
+/// entry, we only keep one pair and discard the rest.
+/// If a file does not exist, its corresponding replacements will be ignored.
+std::map<std::string, Replacements> groupReplacementsByFile(
+ FileManager &FileMgr,
+ const std::map<std::string, Replacements> &FileToReplaces);
template <typename Node>
Replacement::Replacement(const SourceManager &Sources,
diff --git a/include/clang/Tooling/FileMatchTrie.h b/include/clang/Tooling/FileMatchTrie.h
index 745c1645068a..882979ef8ff6 100644
--- a/include/clang/Tooling/FileMatchTrie.h
+++ b/include/clang/Tooling/FileMatchTrie.h
@@ -16,10 +16,11 @@
#define LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
#include <memory>
-#include <string>
-#include <vector>
+
+namespace llvm {
+class StringRef;
+}
namespace clang {
namespace tooling {
diff --git a/include/clang/Tooling/JSONCompilationDatabase.h b/include/clang/Tooling/JSONCompilationDatabase.h
index 2a13fc155cea..9a6866240b08 100644
--- a/include/clang/Tooling/JSONCompilationDatabase.h
+++ b/include/clang/Tooling/JSONCompilationDatabase.h
@@ -55,6 +55,7 @@ namespace tooling {
///
/// JSON compilation databases can for example be generated in CMake projects
/// by setting the flag -DCMAKE_EXPORT_COMPILE_COMMANDS.
+enum class JSONCommandLineSyntax { Windows, Gnu, AutoDetect };
class JSONCompilationDatabase : public CompilationDatabase {
public:
/// \brief Loads a JSON compilation database from the specified file.
@@ -62,15 +63,17 @@ public:
/// Returns NULL and sets ErrorMessage if the database could not be
/// loaded from the given file.
static std::unique_ptr<JSONCompilationDatabase>
- loadFromFile(StringRef FilePath, std::string &ErrorMessage);
+ loadFromFile(StringRef FilePath, std::string &ErrorMessage,
+ JSONCommandLineSyntax Syntax);
/// \brief Loads a JSON compilation database from a data buffer.
///
/// Returns NULL and sets ErrorMessage if the database could not be loaded.
static std::unique_ptr<JSONCompilationDatabase>
- loadFromBuffer(StringRef DatabaseString, std::string &ErrorMessage);
+ loadFromBuffer(StringRef DatabaseString, std::string &ErrorMessage,
+ JSONCommandLineSyntax Syntax);
- /// \brief Returns all compile comamnds in which the specified file was
+ /// \brief Returns all compile commands in which the specified file was
/// compiled.
///
/// FIXME: Currently FilePath must be an absolute path inside the
@@ -89,8 +92,9 @@ public:
private:
/// \brief Constructs a JSON compilation database on a memory buffer.
- JSONCompilationDatabase(std::unique_ptr<llvm::MemoryBuffer> Database)
- : Database(std::move(Database)),
+ JSONCompilationDatabase(std::unique_ptr<llvm::MemoryBuffer> Database,
+ JSONCommandLineSyntax Syntax)
+ : Database(std::move(Database)), Syntax(Syntax),
YAMLStream(this->Database->getBuffer(), SM) {}
/// \brief Parses the database file and creates the index.
@@ -99,15 +103,17 @@ private:
/// failed.
bool parse(std::string &ErrorMessage);
- // Tuple (directory, filename, commandline) where 'commandline' points to the
- // corresponding scalar nodes in the YAML stream.
+ // Tuple (directory, filename, commandline, output) where 'commandline'
+ // points to the corresponding scalar nodes in the YAML stream.
// If the command line contains a single argument, it is a shell-escaped
// command line.
// Otherwise, each entry in the command line vector is a literal
// argument to the compiler.
+ // The output field may be a nullptr.
typedef std::tuple<llvm::yaml::ScalarNode *,
llvm::yaml::ScalarNode *,
- std::vector<llvm::yaml::ScalarNode *>> CompileCommandRef;
+ std::vector<llvm::yaml::ScalarNode *>,
+ llvm::yaml::ScalarNode *> CompileCommandRef;
/// \brief Converts the given array of CompileCommandRefs to CompileCommands.
void getCommands(ArrayRef<CompileCommandRef> CommandsRef,
@@ -123,6 +129,7 @@ private:
FileMatchTrie MatchTrie;
std::unique_ptr<llvm::MemoryBuffer> Database;
+ JSONCommandLineSyntax Syntax;
llvm::SourceMgr SM;
llvm::yaml::Stream YAMLStream;
};
diff --git a/include/clang/Tooling/Refactoring.h b/include/clang/Tooling/Refactoring.h
index 06ec8b087629..bc95c3b09ec2 100644
--- a/include/clang/Tooling/Refactoring.h
+++ b/include/clang/Tooling/Refactoring.h
@@ -21,6 +21,7 @@
#include "clang/Tooling/Core/Replacement.h"
#include "clang/Tooling/Tooling.h"
+#include <map>
#include <string>
namespace clang {
@@ -42,9 +43,9 @@ public:
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>());
- /// \brief Returns the set of replacements to which replacements should
- /// be added during the run of the tool.
- Replacements &getReplacements();
+ /// \brief Returns the file path to replacements map to which replacements
+ /// should be added during the run of the tool.
+ std::map<std::string, Replacements> &getReplacements();
/// \brief Call run(), apply all generated replacements, and immediately save
/// the results to disk.
@@ -54,6 +55,9 @@ public:
/// \brief Apply all stored replacements to the given Rewriter.
///
+ /// FileToReplaces will be deduplicated with `groupReplacementsByFile` before
+ /// application.
+ ///
/// Replacement applications happen independently of the success of other
/// applications.
///
@@ -65,7 +69,7 @@ private:
int saveRewrittenFiles(Rewriter &Rewrite);
private:
- Replacements Replace;
+ std::map<std::string, Replacements> FileToReplaces;
};
/// \brief Groups \p Replaces by the file path and applies each group of
@@ -74,17 +78,21 @@ private:
///
/// \pre Replacements must be conflict-free.
///
+/// FileToReplaces will be deduplicated with `groupReplacementsByFile` before
+/// application.
+///
/// Replacement applications happen independently of the success of other
/// applications.
///
-/// \param[in] Replaces Replacements to apply.
+/// \param[in] FileToReplaces Replacements (grouped by files) to apply.
/// \param[in] Rewrite The `Rewritter` to apply replacements on.
/// \param[in] Style The style name used for reformatting. See ```getStyle``` in
/// "include/clang/Format/Format.h" for all possible style forms.
///
/// \returns true if all replacements applied and formatted. false otherwise.
-bool formatAndApplyAllReplacements(const Replacements &Replaces,
- Rewriter &Rewrite, StringRef Style = "file");
+bool formatAndApplyAllReplacements(
+ const std::map<std::string, Replacements> &FileToReplaces,
+ Rewriter &Rewrite, StringRef Style = "file");
} // end namespace tooling
} // end namespace clang
diff --git a/include/clang/Tooling/ReplacementsYaml.h b/include/clang/Tooling/ReplacementsYaml.h
index 4a7666d2c555..47b7f3f9a534 100644
--- a/include/clang/Tooling/ReplacementsYaml.h
+++ b/include/clang/Tooling/ReplacementsYaml.h
@@ -19,7 +19,6 @@
#include "clang/Tooling/Refactoring.h"
#include "llvm/Support/YAMLTraits.h"
#include <string>
-#include <vector>
LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Replacement)
diff --git a/include/clang/module.modulemap b/include/clang/module.modulemap
index 7fa8b82515eb..3b4238110026 100644
--- a/include/clang/module.modulemap
+++ b/include/clang/module.modulemap
@@ -38,6 +38,7 @@ module Clang_Basic {
textual header "Basic/BuiltinsSystemZ.def"
textual header "Basic/BuiltinsWebAssembly.def"
textual header "Basic/BuiltinsX86.def"
+ textual header "Basic/BuiltinsX86_64.def"
textual header "Basic/BuiltinsXCore.def"
textual header "Basic/DiagnosticOptions.def"
textual header "Basic/LangOptions.def"