diff --git a/LICENSE.TXT b/LICENSE.TXT index 9e71121218a6..24806ab4c9eb 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,5 +1,240 @@ ============================================================================== -LLVM Release License +The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: +============================================================================== + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +---- LLVM Exceptions to the Apache 2.0 License ---- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. + +============================================================================== +Software from third parties included in the LLVM Project: +============================================================================== +The LLVM Project contains third party software which is under different license +terms. All such code will be identified clearly using at least one of two +mechanisms: +1) It will be in a separate directory tree with its own `LICENSE.txt` or + `LICENSE` file at the top containing the specific license and restrictions + which apply to that software, or +2) It will contain specific license and restriction terms at the top of every + file. + +============================================================================== +Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): ============================================================================== University of Illinois/NCSA Open Source License @@ -41,23 +276,3 @@ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. - -============================================================================== -The LLVM software contains code written by third parties. Such software will -have its own individual LICENSE.TXT file in the directory in which it appears. -This file will describe the copyrights, license, and restrictions which apply -to that code. - -The disclaimer of warranty in the University of Illinois Open Source License -applies to all code in the LLVM Distribution, and nothing in any of the -other licenses gives permission to use the names of the LLVM Team or the -University of Illinois to endorse or promote products derived from this -Software. - -The following pieces of software have additional or alternate copyrights, -licenses, and/or restrictions: - -Program Directory -------- --------- - - diff --git a/include/clang-c/BuildSystem.h b/include/clang-c/BuildSystem.h index 3cfec388308c..8f26a8611719 100644 --- a/include/clang-c/BuildSystem.h +++ b/include/clang-c/BuildSystem.h @@ -1,9 +1,9 @@ /*==-- clang-c/BuildSystem.h - Utilities for use by build systems -*- C -*-===*\ |* *| -|* The LLVM Compiler Infrastructure *| -|* *| -|* This file is distributed under the University of Illinois Open Source *| -|* License. See LICENSE.TXT for details. *| +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| +|* Exceptions. *| +|* See https://llvm.org/LICENSE.txt for license information. *| +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| |* *| |*===----------------------------------------------------------------------===*| |* *| diff --git a/include/clang-c/CXCompilationDatabase.h b/include/clang-c/CXCompilationDatabase.h index 6f483ee28b56..2669c1a792c1 100644 --- a/include/clang-c/CXCompilationDatabase.h +++ b/include/clang-c/CXCompilationDatabase.h @@ -1,9 +1,9 @@ /*===-- clang-c/CXCompilationDatabase.h - Compilation database ---*- C -*-===*\ |* *| -|* The LLVM Compiler Infrastructure *| -|* *| -|* This file is distributed under the University of Illinois Open Source *| -|* License. See LICENSE.TXT for details. *| +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| +|* Exceptions. *| +|* See https://llvm.org/LICENSE.txt for license information. *| +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| |* *| |*===----------------------------------------------------------------------===*| |* *| diff --git a/include/clang-c/CXErrorCode.h b/include/clang-c/CXErrorCode.h index caee48d76832..fed195ec1f33 100644 --- a/include/clang-c/CXErrorCode.h +++ b/include/clang-c/CXErrorCode.h @@ -1,9 +1,9 @@ /*===-- clang-c/CXErrorCode.h - C Index Error Codes --------------*- C -*-===*\ |* *| -|* The LLVM Compiler Infrastructure *| -|* *| -|* This file is distributed under the University of Illinois Open Source *| -|* License. See LICENSE.TXT for details. *| +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| +|* Exceptions. *| +|* See https://llvm.org/LICENSE.txt for license information. *| +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| |* *| |*===----------------------------------------------------------------------===*| |* *| diff --git a/include/clang-c/CXString.h b/include/clang-c/CXString.h index 76eeda180109..1eb3442ccb24 100644 --- a/include/clang-c/CXString.h +++ b/include/clang-c/CXString.h @@ -1,9 +1,9 @@ /*===-- clang-c/CXString.h - C Index strings --------------------*- C -*-===*\ |* *| -|* The LLVM Compiler Infrastructure *| -|* *| -|* This file is distributed under the University of Illinois Open Source *| -|* License. See LICENSE.TXT for details. *| +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| +|* Exceptions. *| +|* See https://llvm.org/LICENSE.txt for license information. *| +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| |* *| |*===----------------------------------------------------------------------===*| |* *| diff --git a/include/clang-c/Documentation.h b/include/clang-c/Documentation.h index 58c8af5aa47c..4af8c93a367e 100644 --- a/include/clang-c/Documentation.h +++ b/include/clang-c/Documentation.h @@ -1,9 +1,9 @@ /*==-- clang-c/Documentation.h - Utilities for comment processing -*- C -*-===*\ |* *| -|* The LLVM Compiler Infrastructure *| -|* *| -|* This file is distributed under the University of Illinois Open Source *| -|* License. See LICENSE.TXT for details. *| +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| +|* Exceptions. *| +|* See https://llvm.org/LICENSE.txt for license information. *| +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| |* *| |*===----------------------------------------------------------------------===*| |* *| diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index c51dfb1598b9..74badac740b6 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -1,9 +1,9 @@ /*===-- clang-c/Index.h - Indexing Public C Interface -------------*- C -*-===*\ |* *| -|* The LLVM Compiler Infrastructure *| -|* *| -|* This file is distributed under the University of Illinois Open Source *| -|* License. See LICENSE.TXT for details. *| +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| +|* Exceptions. *| +|* See https://llvm.org/LICENSE.txt for license information. *| +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| |* *| |*===----------------------------------------------------------------------===*| |* *| @@ -32,7 +32,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 50 +#define CINDEX_VERSION_MINOR 59 #define CINDEX_VERSION_ENCODE(major, minor) ( \ ((major) * 10000) \ @@ -221,7 +221,12 @@ enum CXCursor_ExceptionSpecificationKind { /** * The exception specification has not been parsed yet. */ - CXCursor_ExceptionSpecificationKind_Unparsed + CXCursor_ExceptionSpecificationKind_Unparsed, + + /** + * The cursor has a __declspec(nothrow) exception specification. + */ + CXCursor_ExceptionSpecificationKind_NoThrow }; /** @@ -1341,7 +1346,17 @@ enum CXTranslationUnit_Flags { /** * Used to indicate that implicit attributes should be visited. */ - CXTranslationUnit_VisitImplicitAttributes = 0x2000 + CXTranslationUnit_VisitImplicitAttributes = 0x2000, + + /** + * Used to indicate that non-errors from included files should be ignored. + * + * If set, clang_getDiagnosticSetFromTU() will not report e.g. warnings from + * included files anymore. This speeds up clang_getDiagnosticSetFromTU() for + * the case where these warnings are not of interest, as for an IDE for + * example, which typically shows only the diagnostics in the main file. + */ + CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles = 0x4000 }; /** @@ -2531,7 +2546,11 @@ enum CXCursorKind { */ CXCursor_OMPTargetTeamsDistributeSimdDirective = 279, - CXCursor_LastStmt = CXCursor_OMPTargetTeamsDistributeSimdDirective, + /** C++2a std::bit_cast expression. + */ + CXCursor_BuiltinBitCastExpr = 280, + + CXCursor_LastStmt = CXCursor_BuiltinBitCastExpr, /** * Cursor that represents the translation unit itself. @@ -2586,7 +2605,11 @@ enum CXCursorKind { CXCursor_ObjCRuntimeVisible = 435, CXCursor_ObjCBoxable = 436, CXCursor_FlagEnum = 437, - CXCursor_LastAttr = CXCursor_FlagEnum, + CXCursor_ConvergentAttr = 438, + CXCursor_WarnUnusedAttr = 439, + CXCursor_WarnUnusedResultAttr = 440, + CXCursor_AlignedAttr = 441, + CXCursor_LastAttr = CXCursor_AlignedAttr, /* Preprocessing */ CXCursor_PreprocessingDirective = 500, @@ -3311,7 +3334,9 @@ enum CXTypeKind { CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout = 173, CXType_OCLIntelSubgroupAVCImeSingleRefStreamin = 174, - CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175 + CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175, + + CXType_ExtVector = 176 }; /** @@ -3838,7 +3863,11 @@ enum CXTypeLayoutError { /** * The Field name is not valid for this record. */ - CXTypeLayoutError_InvalidFieldName = -5 + CXTypeLayoutError_InvalidFieldName = -5, + /** + * The type is undeduced. + */ + CXTypeLayoutError_Undeduced = -6 }; /** @@ -3910,11 +3939,23 @@ CINDEX_LINKAGE CXType clang_Type_getModifiedType(CXType T); */ CINDEX_LINKAGE long long clang_Cursor_getOffsetOfField(CXCursor C); +/** + * Determine whether the given cursor represents an anonymous + * tag or namespace + */ +CINDEX_LINKAGE unsigned clang_Cursor_isAnonymous(CXCursor C); + /** * Determine whether the given cursor represents an anonymous record * declaration. */ -CINDEX_LINKAGE unsigned clang_Cursor_isAnonymous(CXCursor C); +CINDEX_LINKAGE unsigned clang_Cursor_isAnonymousRecordDecl(CXCursor C); + +/** + * Determine whether the given cursor represents an inline namespace + * declaration. + */ +CINDEX_LINKAGE unsigned clang_Cursor_isInlineNamespace(CXCursor C); enum CXRefQualifierKind { /** No ref-qualifier was provided. */ diff --git a/include/clang-c/Platform.h b/include/clang-c/Platform.h index e2a4dccbdaf0..5284b533253d 100644 --- a/include/clang-c/Platform.h +++ b/include/clang-c/Platform.h @@ -1,9 +1,9 @@ /*===-- clang-c/Platform.h - C Index platform decls -------------*- C -*-===*\ |* *| -|* The LLVM Compiler Infrastructure *| -|* *| -|* This file is distributed under the University of Illinois Open Source *| -|* License. See LICENSE.TXT for details. *| +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| +|* Exceptions. *| +|* See https://llvm.org/LICENSE.txt for license information. *| +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| |* *| |*===----------------------------------------------------------------------===*| |* *| diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h index 30c24f1cdb10..49e94a92cd0b 100644 --- a/include/clang/ARCMigrate/ARCMT.h +++ b/include/clang/ARCMigrate/ARCMT.h @@ -1,9 +1,8 @@ //===-- ARCMT.h - ARC Migration Rewriter ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h index 2571ca75be51..641c259b3867 100644 --- a/include/clang/ARCMigrate/ARCMTActions.h +++ b/include/clang/ARCMigrate/ARCMTActions.h @@ -1,9 +1,8 @@ //===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h index 731307f24e22..76b65b2f6884 100644 --- a/include/clang/ARCMigrate/FileRemapper.h +++ b/include/clang/ARCMigrate/FileRemapper.h @@ -1,9 +1,8 @@ //===-- FileRemapper.h - File Remapping Helper ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h index d4057c9da5f3..6943479831ec 100644 --- a/include/clang/AST/APValue.h +++ b/include/clang/AST/APValue.h @@ -1,9 +1,8 @@ //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -14,6 +13,7 @@ #ifndef LLVM_CLANG_AST_APVALUE_H #define LLVM_CLANG_AST_APVALUE_H +#include "clang/Basic/FixedPoint.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" @@ -24,14 +24,52 @@ namespace clang { class AddrLabelExpr; class ASTContext; class CharUnits; + class CXXRecordDecl; + class Decl; class DiagnosticBuilder; class Expr; class FieldDecl; - class Decl; + struct PrintingPolicy; + class Type; class ValueDecl; - class CXXRecordDecl; - class QualType; +/// Symbolic representation of typeid(T) for some type T. +class TypeInfoLValue { + const Type *T; + +public: + TypeInfoLValue() : T() {} + explicit TypeInfoLValue(const Type *T); + + const Type *getType() const { return T; } + explicit operator bool() const { return T; } + + void *getOpaqueValue() { return const_cast(T); } + static TypeInfoLValue getFromOpaqueValue(void *Value) { + TypeInfoLValue V; + V.T = reinterpret_cast(Value); + return V; + } + + void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const; +}; +} + +namespace llvm { +template<> struct PointerLikeTypeTraits { + static void *getAsVoidPointer(clang::TypeInfoLValue V) { + return V.getOpaqueValue(); + } + static clang::TypeInfoLValue getFromVoidPointer(void *P) { + return clang::TypeInfoLValue::getFromOpaqueValue(P); + } + // Validated by static_assert in APValue.cpp; hardcoded to avoid needing + // to include Type.h. + static constexpr int NumLowBitsAvailable = 3; +}; +} + +namespace clang { /// APValue - This class implements a discriminated union of [uninitialized] /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset], /// [Vector: N * APValue], [Array: N * APValue] @@ -40,9 +78,13 @@ class APValue { typedef llvm::APFloat APFloat; public: enum ValueKind { - Uninitialized, + /// There is no such object (it's outside its lifetime). + None, + /// This object has an indeterminate value (C++ [basic.indet]). + Indeterminate, Int, Float, + FixedPoint, ComplexInt, ComplexFloat, LValue, @@ -55,14 +97,14 @@ public: }; class LValueBase { + typedef llvm::PointerUnion + PtrTy; + public: - typedef llvm::PointerUnion PtrTy; - - LValueBase() : CallIndex(0), Version(0) {} - - template - LValueBase(T P, unsigned I = 0, unsigned V = 0) - : Ptr(P), CallIndex(I), Version(V) {} + LValueBase() : Local{} {} + LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0); + LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0); + static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo); template bool is() const { return Ptr.is(); } @@ -77,45 +119,73 @@ public: bool isNull() const; - explicit operator bool () const; + explicit operator bool() const; - PtrTy getPointer() const { - return Ptr; - } + unsigned getCallIndex() const; + unsigned getVersion() const; + QualType getTypeInfoType() const; - unsigned getCallIndex() const { - return CallIndex; - } - - void setCallIndex(unsigned Index) { - CallIndex = Index; - } - - unsigned getVersion() const { - return Version; - } - - bool operator==(const LValueBase &Other) const { - return Ptr == Other.Ptr && CallIndex == Other.CallIndex && - Version == Other.Version; + friend bool operator==(const LValueBase &LHS, const LValueBase &RHS); + friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) { + return !(LHS == RHS); } + friend llvm::hash_code hash_value(const LValueBase &Base); private: PtrTy Ptr; - unsigned CallIndex, Version; + struct LocalState { + unsigned CallIndex, Version; + }; + union { + LocalState Local; + /// The type std::type_info, if this is a TypeInfoLValue. + void *TypeInfoType; + }; }; + /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we + /// mean a virtual or non-virtual base class subobject. typedef llvm::PointerIntPair BaseOrMemberType; - union LValuePathEntry { - /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item - /// in the path. An opaque value of type BaseOrMemberType. - void *BaseOrMember; - /// ArrayIndex - The array index of the next item in the path. - uint64_t ArrayIndex; + + /// A non-discriminated union of a base, field, or array index. + class LValuePathEntry { + static_assert(sizeof(uintptr_t) <= sizeof(uint64_t), + "pointer doesn't fit in 64 bits?"); + uint64_t Value; + + public: + LValuePathEntry() : Value() {} + LValuePathEntry(BaseOrMemberType BaseOrMember) + : Value{reinterpret_cast(BaseOrMember.getOpaqueValue())} {} + static LValuePathEntry ArrayIndex(uint64_t Index) { + LValuePathEntry Result; + Result.Value = Index; + return Result; + } + + BaseOrMemberType getAsBaseOrMember() const { + return BaseOrMemberType::getFromOpaqueValue( + reinterpret_cast(Value)); + } + uint64_t getAsArrayIndex() const { return Value; } + + friend bool operator==(LValuePathEntry A, LValuePathEntry B) { + return A.Value == B.Value; + } + friend bool operator!=(LValuePathEntry A, LValuePathEntry B) { + return A.Value != B.Value; + } + friend llvm::hash_code hash_value(LValuePathEntry A) { + return llvm::hash_value(A.Value); + } }; struct NoLValuePath {}; struct UninitArray {}; struct UninitStruct {}; + + friend class ASTReader; + friend class ASTWriter; + private: ValueKind Kind; @@ -168,55 +238,64 @@ private: DataType Data; public: - APValue() : Kind(Uninitialized) {} - explicit APValue(APSInt I) : Kind(Uninitialized) { + APValue() : Kind(None) {} + explicit APValue(APSInt I) : Kind(None) { MakeInt(); setInt(std::move(I)); } - explicit APValue(APFloat F) : Kind(Uninitialized) { + explicit APValue(APFloat F) : Kind(None) { MakeFloat(); setFloat(std::move(F)); } - explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) { + explicit APValue(APFixedPoint FX) : Kind(None) { + MakeFixedPoint(std::move(FX)); + } + explicit APValue(const APValue *E, unsigned N) : Kind(None) { MakeVector(); setVector(E, N); } - APValue(APSInt R, APSInt I) : Kind(Uninitialized) { + APValue(APSInt R, APSInt I) : Kind(None) { MakeComplexInt(); setComplexInt(std::move(R), std::move(I)); } - APValue(APFloat R, APFloat I) : Kind(Uninitialized) { + APValue(APFloat R, APFloat I) : Kind(None) { MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I)); } APValue(const APValue &RHS); - APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); } + APValue(APValue &&RHS) : Kind(None) { swap(RHS); } APValue(LValueBase B, const CharUnits &O, NoLValuePath N, bool IsNullPtr = false) - : Kind(Uninitialized) { + : Kind(None) { MakeLValue(); setLValue(B, O, N, IsNullPtr); } APValue(LValueBase B, const CharUnits &O, ArrayRef Path, bool OnePastTheEnd, bool IsNullPtr = false) - : Kind(Uninitialized) { + : Kind(None) { MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr); } - APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) { + APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) { MakeArray(InitElts, Size); } - APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) { + APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) { MakeStruct(B, M); } explicit APValue(const FieldDecl *D, const APValue &V = APValue()) - : Kind(Uninitialized) { + : Kind(None) { MakeUnion(); setUnion(D, V); } APValue(const ValueDecl *Member, bool IsDerivedMember, - ArrayRef Path) : Kind(Uninitialized) { + ArrayRef Path) : Kind(None) { MakeMemberPointer(Member, IsDerivedMember, Path); } APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) - : Kind(Uninitialized) { + : Kind(None) { MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr); } + static APValue IndeterminateValue() { + APValue Result; + Result.Kind = Indeterminate; + return Result; + } ~APValue() { - MakeUninit(); + if (Kind != None && Kind != Indeterminate) + DestroyDataAndMakeUninit(); } /// Returns whether the object performed allocations. @@ -230,9 +309,14 @@ public: void swap(APValue &RHS); ValueKind getKind() const { return Kind; } - bool isUninit() const { return Kind == Uninitialized; } + + bool isAbsent() const { return Kind == None; } + bool isIndeterminate() const { return Kind == Indeterminate; } + bool hasValue() const { return Kind != None && Kind != Indeterminate; } + bool isInt() const { return Kind == Int; } bool isFloat() const { return Kind == Float; } + bool isFixedPoint() const { return Kind == FixedPoint; } bool isComplexInt() const { return Kind == ComplexInt; } bool isComplexFloat() const { return Kind == ComplexFloat; } bool isLValue() const { return Kind == LValue; } @@ -246,8 +330,8 @@ public: void dump() const; void dump(raw_ostream &OS) const; - void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const; - std::string getAsString(ASTContext &Ctx, QualType Ty) const; + void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const; + std::string getAsString(const ASTContext &Ctx, QualType Ty) const; APSInt &getInt() { assert(isInt() && "Invalid accessor"); @@ -257,6 +341,12 @@ public: return const_cast(this)->getInt(); } + /// Try to convert this value to an integral constant. This works if it's an + /// integer, null pointer, or offset from a null pointer. Returns true on + /// success. + bool toIntegralConstant(APSInt &Result, QualType SrcTy, + const ASTContext &Ctx) const; + APFloat &getFloat() { assert(isFloat() && "Invalid accessor"); return *(APFloat*)(char*)Data.buffer; @@ -265,6 +355,14 @@ public: return const_cast(this)->getFloat(); } + APFixedPoint &getFixedPoint() { + assert(isFixedPoint() && "Invalid accessor"); + return *(APFixedPoint *)(char *)Data.buffer; + } + const APFixedPoint &getFixedPoint() const { + return const_cast(this)->getFixedPoint(); + } + APSInt &getComplexIntReal() { assert(isComplexInt() && "Invalid accessor"); return ((ComplexAPSInt*)(char*)Data.buffer)->Real; @@ -406,6 +504,10 @@ public: assert(isFloat() && "Invalid accessor"); *(APFloat *)(char *)Data.buffer = std::move(F); } + void setFixedPoint(APFixedPoint FX) { + assert(isFixedPoint() && "Invalid accessor"); + *(APFixedPoint *)(char *)Data.buffer = std::move(FX); + } void setVector(const APValue *E, unsigned N) { assert(isVector() && "Invalid accessor"); ((Vec*)(char*)Data.buffer)->Elts = new APValue[N]; @@ -451,51 +553,52 @@ public: private: void DestroyDataAndMakeUninit(); - void MakeUninit() { - if (Kind != Uninitialized) - DestroyDataAndMakeUninit(); - } void MakeInt() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)Data.buffer) APSInt(1); Kind = Int; } void MakeFloat() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) APFloat(0.0); Kind = Float; } + void MakeFixedPoint(APFixedPoint &&FX) { + assert(isAbsent() && "Bad state change"); + new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX)); + Kind = FixedPoint; + } void MakeVector() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) Vec(); Kind = Vector; } void MakeComplexInt() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) ComplexAPSInt(); Kind = ComplexInt; } void MakeComplexFloat() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) ComplexAPFloat(); Kind = ComplexFloat; } void MakeLValue(); void MakeArray(unsigned InitElts, unsigned Size); void MakeStruct(unsigned B, unsigned M) { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) StructData(B, M); Kind = Struct; } void MakeUnion() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) UnionData(); Kind = Union; } void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, ArrayRef Path); void MakeAddrLabelDiff() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) AddrLabelDiffData(); Kind = AddrLabelDiff; } diff --git a/include/clang/AST/AST.h b/include/clang/AST/AST.h index 6db351d1064b..6d0f274121b2 100644 --- a/include/clang/AST/AST.h +++ b/include/clang/AST/AST.h @@ -1,9 +1,8 @@ //===--- AST.h - "Umbrella" header for AST library --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index 1167c566a35f..dc216a89c205 100644 --- a/include/clang/AST/ASTConsumer.h +++ b/include/clang/AST/ASTConsumer.h @@ -1,9 +1,8 @@ //===--- ASTConsumer.h - Abstract interface for reading ASTs ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 13870116c7fd..1d1aaf4fb115 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -1,9 +1,8 @@ //===- ASTContext.h - Context to hold long-lived AST nodes ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -266,17 +265,21 @@ private: /// Mapping from __block VarDecls to BlockVarCopyInit. llvm::DenseMap BlockVarCopyInits; - /// Mapping from class scope functions specialization to their - /// template patterns. - llvm::DenseMap - ClassScopeSpecializationPattern; - /// Mapping from materialized temporaries with static storage duration /// that appear in constant initializers to their evaluated values. These are /// allocated in a std::map because their address must be stable. llvm::DenseMap MaterializedTemporaryValues; + /// Used to cleanups APValues stored in the AST. + mutable llvm::SmallVector APValueCleanups; + + /// A cache mapping a string value to a StringLiteral object with the same + /// value. + /// + /// This is lazily created. This is intentionally not serialized. + mutable llvm::StringMap StringLiteralCache; + /// Representation of a "canonical" template template parameter that /// is used in canonical template names. class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode { @@ -892,11 +895,6 @@ public: TemplateOrSpecializationInfo getTemplateOrSpecializationInfo(const VarDecl *Var); - FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD); - - void setClassScopeSpecializationPattern(FunctionDecl *FD, - FunctionDecl *Pattern); - /// Note that the static data member \p Inst is an instantiation of /// the static data member template \p Tmpl of a class template. void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl, @@ -1334,6 +1332,10 @@ public: ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const; + /// Return a type for a constant array for a string literal of the + /// specified element type and length. + QualType getStringLiteralArrayType(QualType EltTy, unsigned Length) const; + /// Returns a vla type where known sizes are replaced with [*]. QualType getVariableArrayDecayedType(QualType Ty) const; @@ -1452,6 +1454,9 @@ public: QualType getParenType(QualType NamedType) const; + QualType getMacroQualifiedType(QualType UnderlyingTy, + const IdentifierInfo *MacroII) const; + QualType getElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, TagDecl *OwnedTagDecl = nullptr) const; @@ -1520,7 +1525,7 @@ public: /// C++11 deduced auto type. QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, - bool IsDependent) const; + bool IsDependent, bool IsPack = false) const; /// C++11 deduction pattern for 'auto' type. QualType getAutoDeductType() const; @@ -1985,6 +1990,7 @@ public: TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin, UnresolvedSetIterator End) const; + TemplateName getAssumedTemplateName(DeclarationName Name) const; TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, @@ -2003,6 +2009,9 @@ public: /// No error GE_None, + /// Missing a type + GE_Missing_type, + /// Missing a type from GE_Missing_stdio, @@ -2086,6 +2095,16 @@ public: CharUnits getTypeSizeInChars(QualType T) const; CharUnits getTypeSizeInChars(const Type *T) const; + Optional getTypeSizeInCharsIfKnown(QualType Ty) const { + if (Ty->isIncompleteType() || Ty->isDependentType()) + return None; + return getTypeSizeInChars(Ty); + } + + Optional getTypeSizeInCharsIfKnown(const Type *Ty) const { + return getTypeSizeInCharsIfKnown(QualType(Ty, 0)); + } + /// Return the ABI-specified alignment of a (complete) type \p T, in /// bits. unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; } @@ -2160,6 +2179,13 @@ public: /// pointers and large arrays get extra alignment. CharUnits getDeclAlign(const Decl *D, bool ForAlignof = false) const; + /// Return the alignment (in bytes) of the thrown exception object. This is + /// only meaningful for targets that allocate C++ exceptions in a system + /// runtime, such as those using the Itanium C++ ABI. + CharUnits getExnObjectAlignment() const { + return toCharUnitsFromBits(Target->getExnObjectAlignment()); + } + /// Get or compute information about the layout of the specified /// record (struct/union/class) \p D, which indicates its size and field /// position information. @@ -2225,7 +2251,8 @@ public: VTableContextBase *getVTableContext(); - MangleContext *createMangleContext(); + /// If \p T is null pointer, assume the target in ASTContext. + MangleContext *createMangleContext(const TargetInfo *T = nullptr); void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass, SmallVectorImpl &Ivars) const; @@ -2371,7 +2398,8 @@ public: /// Retrieves the default calling convention for the current target. CallingConv getDefaultCallingConvention(bool IsVariadic, - bool IsCXXMethod) const; + bool IsCXXMethod, + bool IsBuiltin = false) const; /// Retrieves the "canonical" template name that refers to a /// given template. @@ -2488,6 +2516,11 @@ public: /// \p LHS < \p RHS, return -1. int getFloatingTypeOrder(QualType LHS, QualType RHS) const; + /// Compare the rank of two floating point types as above, but compare equal + /// if both types have the same floating-point semantics on the target (i.e. + /// long double and double on AArch64 will return 0). + int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const; + /// Return a real floating point or a complex type (based on /// \p typeDomain/\p typeSize). /// @@ -2624,6 +2657,12 @@ public: // corresponding saturated type for a given fixed point type. QualType getCorrespondingSaturatedType(QualType Ty) const; + // This method accepts fixed point types and returns the corresponding signed + // type. Unlike getCorrespondingUnsignedType(), this only accepts unsigned + // fixed point types because there are unsigned integer types like bool and + // char8_t that don't have signed equivalents. + QualType getCorrespondingSignedFixedPointType(QualType Ty) const; + //===--------------------------------------------------------------------===// // Integer Values //===--------------------------------------------------------------------===// @@ -2677,7 +2716,7 @@ public: /// otherwise returns null. const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const; - /// Set the copy inialization expression of a block var decl. \p CanThrow + /// Set the copy initialization expression of a block var decl. \p CanThrow /// indicates whether the copy expression can throw or not. void setBlockVarCopyInit(const VarDecl* VD, Expr *CopyExpr, bool CanThrow); @@ -2712,12 +2751,11 @@ public: /// /// \param Data Pointer data that will be provided to the callback function /// when it is called. - void AddDeallocation(void (*Callback)(void*), void *Data); + void AddDeallocation(void (*Callback)(void *), void *Data) const; /// If T isn't trivially destructible, calls AddDeallocation to register it /// for destruction. - template - void addDestruction(T *Ptr) { + template void addDestruction(T *Ptr) const { if (!std::is_trivially_destructible::value) { auto DestroyPtr = [](void *V) { static_cast(V)->~T(); }; AddDeallocation(DestroyPtr, Ptr); @@ -2780,51 +2818,56 @@ public: APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E, bool MayCreate); + /// Return a string representing the human readable name for the specified + /// function declaration or file name. Used by SourceLocExpr and + /// PredefinedExpr to cache evaluated results. + StringLiteral *getPredefinedStringLiteralFromCache(StringRef Key) const; + //===--------------------------------------------------------------------===// // Statistics //===--------------------------------------------------------------------===// /// The number of implicitly-declared default constructors. - static unsigned NumImplicitDefaultConstructors; + unsigned NumImplicitDefaultConstructors = 0; /// The number of implicitly-declared default constructors for /// which declarations were built. - static unsigned NumImplicitDefaultConstructorsDeclared; + unsigned NumImplicitDefaultConstructorsDeclared = 0; /// The number of implicitly-declared copy constructors. - static unsigned NumImplicitCopyConstructors; + unsigned NumImplicitCopyConstructors = 0; /// The number of implicitly-declared copy constructors for /// which declarations were built. - static unsigned NumImplicitCopyConstructorsDeclared; + unsigned NumImplicitCopyConstructorsDeclared = 0; /// The number of implicitly-declared move constructors. - static unsigned NumImplicitMoveConstructors; + unsigned NumImplicitMoveConstructors = 0; /// The number of implicitly-declared move constructors for /// which declarations were built. - static unsigned NumImplicitMoveConstructorsDeclared; + unsigned NumImplicitMoveConstructorsDeclared = 0; /// The number of implicitly-declared copy assignment operators. - static unsigned NumImplicitCopyAssignmentOperators; + unsigned NumImplicitCopyAssignmentOperators = 0; /// The number of implicitly-declared copy assignment operators for /// which declarations were built. - static unsigned NumImplicitCopyAssignmentOperatorsDeclared; + unsigned NumImplicitCopyAssignmentOperatorsDeclared = 0; /// The number of implicitly-declared move assignment operators. - static unsigned NumImplicitMoveAssignmentOperators; + unsigned NumImplicitMoveAssignmentOperators = 0; /// The number of implicitly-declared move assignment operators for /// which declarations were built. - static unsigned NumImplicitMoveAssignmentOperatorsDeclared; + unsigned NumImplicitMoveAssignmentOperatorsDeclared = 0; /// The number of implicitly-declared destructors. - static unsigned NumImplicitDestructors; + unsigned NumImplicitDestructors = 0; /// The number of implicitly-declared destructors for which /// declarations were built. - static unsigned NumImplicitDestructorsDeclared; + unsigned NumImplicitDestructorsDeclared = 0; public: /// Initialize built-in types. @@ -2839,18 +2882,51 @@ public: private: void InitBuiltinType(CanQualType &R, BuiltinType::Kind K); + class ObjCEncOptions { + unsigned Bits; + + ObjCEncOptions(unsigned Bits) : Bits(Bits) {} + + public: + ObjCEncOptions() : Bits(0) {} + ObjCEncOptions(const ObjCEncOptions &RHS) : Bits(RHS.Bits) {} + +#define OPT_LIST(V) \ + V(ExpandPointedToStructures, 0) \ + V(ExpandStructures, 1) \ + V(IsOutermostType, 2) \ + V(EncodingProperty, 3) \ + V(IsStructField, 4) \ + V(EncodeBlockParameters, 5) \ + V(EncodeClassNames, 6) \ + +#define V(N,I) ObjCEncOptions& set##N() { Bits |= 1 << I; return *this; } +OPT_LIST(V) +#undef V + +#define V(N,I) bool N() const { return Bits & 1 << I; } +OPT_LIST(V) +#undef V + +#undef OPT_LIST + + LLVM_NODISCARD ObjCEncOptions keepingOnly(ObjCEncOptions Mask) const { + return Bits & Mask.Bits; + } + + LLVM_NODISCARD ObjCEncOptions forComponentType() const { + ObjCEncOptions Mask = ObjCEncOptions() + .setIsOutermostType() + .setIsStructField(); + return Bits & ~Mask.Bits; + } + }; + // Return the Objective-C type encoding for a given type. void getObjCEncodingForTypeImpl(QualType t, std::string &S, - bool ExpandPointedToStructures, - bool ExpandStructures, + ObjCEncOptions Options, const FieldDecl *Field, - bool OutermostType = false, - bool EncodingProperty = false, - bool StructField = false, - bool EncodeBlockParameters = false, - bool EncodeClassNames = false, - bool EncodePointerToObjCTypedef = false, - QualType *NotEncodedT=nullptr) const; + QualType *NotEncodedT = nullptr) const; // Adds the encoding of the structure's members. void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S, @@ -2908,7 +2984,7 @@ private: // in order to track and run destructors while we're tearing things down. using DeallocationFunctionsAndArguments = llvm::SmallVector, 16>; - DeallocationFunctionsAndArguments Deallocations; + mutable DeallocationFunctionsAndArguments Deallocations; // FIXME: This currently contains the set of StoredDeclMaps used // by DeclContext objects. This probably should not be in ASTContext, diff --git a/include/clang/AST/ASTContextAllocate.h b/include/clang/AST/ASTContextAllocate.h index 5b9eed208a4d..70c8e24f9185 100644 --- a/include/clang/AST/ASTContextAllocate.h +++ b/include/clang/AST/ASTContextAllocate.h @@ -1,9 +1,8 @@ //===- ASTContextAllocate.h - ASTContext allocate functions -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h index fe92604587ef..d6549e12d92a 100644 --- a/include/clang/AST/ASTDiagnostic.h +++ b/include/clang/AST/ASTDiagnostic.h @@ -1,9 +1,8 @@ //===--- ASTDiagnostic.h - Diagnostics for the AST library ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/ASTDumper.h b/include/clang/AST/ASTDumper.h new file mode 100644 index 000000000000..61202f057a80 --- /dev/null +++ b/include/clang/AST/ASTDumper.h @@ -0,0 +1,56 @@ +//===--- ASTDumper.h - Dumping implementation for ASTs --------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_ASTDUMPER_H +#define LLVM_CLANG_AST_ASTDUMPER_H + +#include "clang/AST/ASTNodeTraverser.h" +#include "clang/AST/TextNodeDumper.h" + +namespace clang { + +class ASTDumper : public ASTNodeTraverser { + + TextNodeDumper NodeDumper; + + raw_ostream &OS; + + const bool ShowColors; + +public: + ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits, + const SourceManager *SM) + : ASTDumper(OS, Traits, SM, SM && SM->getDiagnostics().getShowColors()) {} + + ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits, + const SourceManager *SM, bool ShowColors) + : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {} + ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits, + const SourceManager *SM, bool ShowColors, + const PrintingPolicy &PrintPolicy) + : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS), + ShowColors(ShowColors) {} + + TextNodeDumper &doGetNodeDelegate() { return NodeDumper; } + + void dumpLookups(const DeclContext *DC, bool DumpDecls); + + template + void dumpTemplateDeclSpecialization(const SpecializationDecl *D, + bool DumpExplicitInst, bool DumpRefOnly); + template + void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst); + + void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); + void VisitClassTemplateDecl(const ClassTemplateDecl *D); + void VisitVarTemplateDecl(const VarTemplateDecl *D); +}; + +} // namespace clang + +#endif diff --git a/include/clang/AST/ASTDumperUtils.h b/include/clang/AST/ASTDumperUtils.h index 5e62e902b423..55a085449a9b 100644 --- a/include/clang/AST/ASTDumperUtils.h +++ b/include/clang/AST/ASTDumperUtils.h @@ -1,9 +1,8 @@ //===--- ASTDumperUtils.h - Printing of AST nodes -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -18,6 +17,12 @@ namespace clang { +/// Used to specify the format for printing AST dump information. +enum ASTDumpOutputFormat { + ADOF_Default, + ADOF_JSON +}; + // Colors used for various parts of the AST dump // Do not use bold yellow for any text. It is hard to read on white screens. diff --git a/include/clang/AST/ASTFwd.h b/include/clang/AST/ASTFwd.h index 038d5c3d3611..93919bbdd52f 100644 --- a/include/clang/AST/ASTFwd.h +++ b/include/clang/AST/ASTFwd.h @@ -1,9 +1,8 @@ //===--- ASTFwd.h ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===--------------------------------------------------------------===// /// diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h index dbb9cf35ddea..4a55c120a457 100644 --- a/include/clang/AST/ASTImporter.h +++ b/include/clang/AST/ASTImporter.h @@ -1,9 +1,8 @@ //===- ASTImporter.h - Importing ASTs from other Contexts -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -15,6 +14,7 @@ #ifndef LLVM_CLANG_AST_ASTIMPORTER_H #define LLVM_CLANG_AST_ASTIMPORTER_H +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" @@ -33,7 +33,8 @@ namespace clang { class ASTContext; -class ASTImporterLookupTable; +class ASTImporterSharedState; +class Attr; class CXXBaseSpecifier; class CXXCtorInitializer; class Decl; @@ -43,8 +44,8 @@ class FileManager; class NamedDecl; class Stmt; class TagDecl; +class TranslationUnitDecl; class TypeSourceInfo; -class Attr; class ImportError : public llvm::ErrorInfo { public: @@ -87,14 +88,140 @@ class Attr; using ImportedCXXBaseSpecifierMap = llvm::DenseMap; - private: + // An ImportPath is the list of the AST nodes which we visit during an + // Import call. + // If node `A` depends on node `B` then the path contains an `A`->`B` edge. + // From the call stack of the import functions we can read the very same + // path. + // + // Now imagine the following AST, where the `->` represents dependency in + // therms of the import. + // ``` + // A->B->C->D + // `->E + // ``` + // We would like to import A. + // The import behaves like a DFS, so we will visit the nodes in this order: + // ABCDE. + // During the visitation we will have the following ImportPaths: + // ``` + // A + // AB + // ABC + // ABCD + // ABC + // AB + // ABE + // AB + // A + // ``` + // If during the visit of E there is an error then we set an error for E, + // then as the call stack shrinks for B, then for A: + // ``` + // A + // AB + // ABC + // ABCD + // ABC + // AB + // ABE // Error! Set an error to E + // AB // Set an error to B + // A // Set an error to A + // ``` + // However, during the import we could import C and D without any error and + // they are independent from A,B and E. + // We must not set up an error for C and D. + // So, at the end of the import we have an entry in `ImportDeclErrors` for + // A,B,E but not for C,D. + // + // Now what happens if there is a cycle in the import path? + // Let's consider this AST: + // ``` + // A->B->C->A + // `->E + // ``` + // During the visitation we will have the below ImportPaths and if during + // the visit of E there is an error then we will set up an error for E,B,A. + // But what's up with C? + // ``` + // A + // AB + // ABC + // ABCA + // ABC + // AB + // ABE // Error! Set an error to E + // AB // Set an error to B + // A // Set an error to A + // ``` + // This time we know that both B and C are dependent on A. + // This means we must set up an error for C too. + // As the call stack reverses back we get to A and we must set up an error + // to all nodes which depend on A (this includes C). + // But C is no longer on the import path, it just had been previously. + // Such situation can happen only if during the visitation we had a cycle. + // If we didn't have any cycle, then the normal way of passing an Error + // object through the call stack could handle the situation. + // This is why we must track cycles during the import process for each + // visited declaration. + class ImportPathTy { + public: + using VecTy = llvm::SmallVector; - /// Pointer to the import specific lookup table, which may be shared - /// amongst several ASTImporter objects. - /// This is an externally managed resource (and should exist during the - /// lifetime of the ASTImporter object) - /// If not set then the original C/C++ lookup is used. - ASTImporterLookupTable *LookupTable = nullptr; + void push(Decl *D) { + Nodes.push_back(D); + ++Aux[D]; + } + + void pop() { + if (Nodes.empty()) + return; + --Aux[Nodes.back()]; + Nodes.pop_back(); + } + + /// Returns true if the last element can be found earlier in the path. + bool hasCycleAtBack() const { + auto Pos = Aux.find(Nodes.back()); + return Pos != Aux.end() && Pos->second > 1; + } + + using Cycle = llvm::iterator_range; + Cycle getCycleAtBack() const { + assert(Nodes.size() >= 2); + return Cycle(Nodes.rbegin(), + std::find(Nodes.rbegin() + 1, Nodes.rend(), Nodes.back()) + + 1); + } + + /// Returns the copy of the cycle. + VecTy copyCycleAtBack() const { + auto R = getCycleAtBack(); + return VecTy(R.begin(), R.end()); + } + + private: + // All nodes of the path. + VecTy Nodes; + // Auxiliary container to be able to answer "Do we have a cycle ending + // at last element?" as fast as possible. + // We count each Decl's occurrence over the path. + llvm::SmallDenseMap Aux; + }; + + private: + std::shared_ptr SharedState = nullptr; + + /// The path which we go through during the import of a given AST node. + ImportPathTy ImportPath; + /// Sometimes we have to save some part of an import path, so later we can + /// set up properties to the saved nodes. + /// We may have several of these import paths associated to one Decl. + using SavedImportPathsForOneDecl = + llvm::SmallVector; + using SavedImportPathsTy = + llvm::SmallDenseMap; + SavedImportPathsTy SavedImportPaths; /// The contexts we're importing to and from. ASTContext &ToContext, &FromContext; @@ -116,6 +243,18 @@ class Attr; /// context to the corresponding declarations in the "to" context. llvm::DenseMap ImportedDecls; + /// Mapping from the already-imported declarations in the "from" + /// context to the error status of the import of that declaration. + /// This map contains only the declarations that were not correctly + /// imported. The same declaration may or may not be included in + /// ImportedDecls. This map is updated continuously during imports and never + /// cleared (like ImportedDecls). + llvm::DenseMap ImportDeclErrors; + + /// Mapping from the already-imported declarations in the "to" + /// context to the corresponding declarations in the "from" context. + llvm::DenseMap ImportedFromDecls; + /// Mapping from the already-imported statements in the "from" /// context to the corresponding statements in the "to" context. llvm::DenseMap ImportedStmts; @@ -138,6 +277,15 @@ class Attr; void AddToLookupTable(Decl *ToD); + protected: + /// Can be overwritten by subclasses to implement their own import logic. + /// The overwritten method should call this method if it didn't import the + /// decl on its own. + virtual Expected ImportImpl(Decl *From); + + /// Used only in unittests to verify the behaviour of the error handling. + virtual bool returnWithErrorInTest() { return false; }; + public: /// \param ToContext The context we'll be importing into. @@ -152,13 +300,13 @@ class Attr; /// as little as it can, e.g., by importing declarations as forward /// declarations that can be completed at a later point. /// - /// \param LookupTable The importer specific lookup table which may be + /// \param SharedState The importer specific lookup table which may be /// shared amongst several ASTImporter objects. /// If not set then the original C/C++ lookup is used. ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, ASTContext &FromContext, FileManager &FromFileManager, bool MinimalImport, - ASTImporterLookupTable *LookupTable = nullptr); + std::shared_ptr SharedState = nullptr); virtual ~ASTImporter(); @@ -173,63 +321,51 @@ class Attr; /// \return Error information (success or error). template LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) { - To = Import(From); - if (From && !To) - return llvm::make_error(); - return llvm::Error::success(); - // FIXME: this should be the final code - //auto ToOrErr = Import(From); - //if (ToOrErr) - // To = *ToOrErr; - //return ToOrErr.takeError(); + auto ToOrErr = Import(From); + if (ToOrErr) + To = *ToOrErr; + return ToOrErr.takeError(); } /// Import the given type from the "from" context into the "to" /// context. A null type is imported as a null type (no error). /// /// \returns The equivalent type in the "to" context, or the import error. - llvm::Expected Import_New(QualType FromT); - // FIXME: Remove this version. - QualType Import(QualType FromT); + llvm::Expected Import(QualType FromT); /// Import the given type source information from the /// "from" context into the "to" context. /// /// \returns The equivalent type source information in the "to" /// context, or the import error. - llvm::Expected Import_New(TypeSourceInfo *FromTSI); - // FIXME: Remove this version. - TypeSourceInfo *Import(TypeSourceInfo *FromTSI); + llvm::Expected Import(TypeSourceInfo *FromTSI); /// Import the given attribute from the "from" context into the /// "to" context. /// /// \returns The equivalent attribute in the "to" context, or the import /// error. - llvm::Expected Import_New(const Attr *FromAttr); - // FIXME: Remove this version. - Attr *Import(const Attr *FromAttr); + llvm::Expected Import(const Attr *FromAttr); /// Import the given declaration from the "from" context into the /// "to" context. /// /// \returns The equivalent declaration in the "to" context, or the import /// error. - llvm::Expected Import_New(Decl *FromD); - llvm::Expected Import_New(const Decl *FromD) { - return Import_New(const_cast(FromD)); - } - // FIXME: Remove this version. - Decl *Import(Decl *FromD); - Decl *Import(const Decl *FromD) { + llvm::Expected Import(Decl *FromD); + llvm::Expected Import(const Decl *FromD) { return Import(const_cast(FromD)); } /// Return the copy of the given declaration in the "to" context if /// it has already been imported from the "from" context. Otherwise return - /// NULL. + /// nullptr. Decl *GetAlreadyImportedOrNull(const Decl *FromD) const; + /// Return the translation unit from where the declaration was + /// imported. If it does not exist nullptr is returned. + TranslationUnitDecl *GetFromTU(Decl *ToD); + /// Import the given declaration context from the "from" /// AST context into the "to" AST context. /// @@ -242,28 +378,21 @@ class Attr; /// /// \returns The equivalent expression in the "to" context, or the import /// error. - llvm::Expected Import_New(Expr *FromE); - // FIXME: Remove this version. - Expr *Import(Expr *FromE); + llvm::Expected Import(Expr *FromE); /// Import the given statement from the "from" context into the /// "to" context. /// /// \returns The equivalent statement in the "to" context, or the import /// error. - llvm::Expected Import_New(Stmt *FromS); - // FIXME: Remove this version. - Stmt *Import(Stmt *FromS); + llvm::Expected Import(Stmt *FromS); /// Import the given nested-name-specifier from the "from" /// context into the "to" context. /// /// \returns The equivalent nested-name-specifier in the "to" /// context, or the import error. - llvm::Expected - Import_New(NestedNameSpecifier *FromNNS); - // FIXME: Remove this version. - NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS); + llvm::Expected Import(NestedNameSpecifier *FromNNS); /// Import the given nested-name-specifier-loc from the "from" /// context into the "to" context. @@ -271,42 +400,32 @@ class Attr; /// \returns The equivalent nested-name-specifier-loc in the "to" /// context, or the import error. llvm::Expected - Import_New(NestedNameSpecifierLoc FromNNS); - // FIXME: Remove this version. - NestedNameSpecifierLoc Import(NestedNameSpecifierLoc FromNNS); + Import(NestedNameSpecifierLoc FromNNS); /// Import the given template name from the "from" context into the /// "to" context, or the import error. - llvm::Expected Import_New(TemplateName From); - // FIXME: Remove this version. - TemplateName Import(TemplateName From); + llvm::Expected Import(TemplateName From); /// Import the given source location from the "from" context into /// the "to" context. /// /// \returns The equivalent source location in the "to" context, or the /// import error. - llvm::Expected Import_New(SourceLocation FromLoc); - // FIXME: Remove this version. - SourceLocation Import(SourceLocation FromLoc); + llvm::Expected Import(SourceLocation FromLoc); /// Import the given source range from the "from" context into /// the "to" context. /// /// \returns The equivalent source range in the "to" context, or the import /// error. - llvm::Expected Import_New(SourceRange FromRange); - // FIXME: Remove this version. - SourceRange Import(SourceRange FromRange); + llvm::Expected Import(SourceRange FromRange); /// Import the given declaration name from the "from" /// context into the "to" context. /// /// \returns The equivalent declaration name in the "to" context, or the /// import error. - llvm::Expected Import_New(DeclarationName FromName); - // FIXME: Remove this version. - DeclarationName Import(DeclarationName FromName); + llvm::Expected Import(DeclarationName FromName); /// Import the given identifier from the "from" context /// into the "to" context. @@ -320,46 +439,32 @@ class Attr; /// /// \returns The equivalent selector in the "to" context, or the import /// error. - llvm::Expected Import_New(Selector FromSel); - // FIXME: Remove this version. - Selector Import(Selector FromSel); + llvm::Expected Import(Selector FromSel); /// Import the given file ID from the "from" context into the /// "to" context. /// /// \returns The equivalent file ID in the source manager of the "to" /// context, or the import error. - llvm::Expected Import_New(FileID); - // FIXME: Remove this version. - FileID Import(FileID); + llvm::Expected Import(FileID, bool IsBuiltin = false); /// Import the given C++ constructor initializer from the "from" /// context into the "to" context. /// /// \returns The equivalent initializer in the "to" context, or the import /// error. - llvm::Expected - Import_New(CXXCtorInitializer *FromInit); - // FIXME: Remove this version. - CXXCtorInitializer *Import(CXXCtorInitializer *FromInit); + llvm::Expected Import(CXXCtorInitializer *FromInit); /// Import the given CXXBaseSpecifier from the "from" context into /// the "to" context. /// /// \returns The equivalent CXXBaseSpecifier in the source manager of the /// "to" context, or the import error. - llvm::Expected - Import_New(const CXXBaseSpecifier *FromSpec); - // FIXME: Remove this version. - CXXBaseSpecifier *Import(const CXXBaseSpecifier *FromSpec); + llvm::Expected Import(const CXXBaseSpecifier *FromSpec); /// Import the definition of the given declaration, including all of /// the declarations it contains. - LLVM_NODISCARD llvm::Error ImportDefinition_New(Decl *From); - - // FIXME: Compatibility function. - // Usages of this should be changed to ImportDefinition_New. - void ImportDefinition(Decl *From); + LLVM_NODISCARD llvm::Error ImportDefinition(Decl *From); /// Cope with a name conflict when importing a declaration into the /// given context. @@ -422,9 +527,13 @@ class Attr; /// Subclasses can override this function to observe all of the \c From -> /// \c To declaration mappings as they are imported. - virtual Decl *Imported(Decl *From, Decl *To) { return To; } + virtual void Imported(Decl *From, Decl *To) {} + + void RegisterImportedDecl(Decl *FromD, Decl *ToD); /// Store and assign the imported declaration to its counterpart. + /// It may happen that several decls from the 'from' context are mapped to + /// the same decl in the 'to' context. Decl *MapImported(Decl *From, Decl *To); /// Called by StructuralEquivalenceContext. If a RecordDecl is @@ -435,6 +544,14 @@ class Attr; /// importation, eliminating this loop. virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; } + /// Return if import of the given declaration has failed and if yes + /// the kind of the problem. This gives the first error encountered with + /// the node. + llvm::Optional getImportDeclErrorIfAny(Decl *FromD) const; + + /// Mark (newly) imported declaration with error. + void setImportDeclError(Decl *From, ImportError Error); + /// Determine whether the given types are structurally /// equivalent. bool IsStructurallyEquivalent(QualType From, QualType To, @@ -445,7 +562,6 @@ class Attr; /// \returns The index of the field in its parent context (starting from 0). /// On error `None` is returned (parent context is non-record). static llvm::Optional getFieldIndex(Decl *F); - }; } // namespace clang diff --git a/include/clang/AST/ASTImporterLookupTable.h b/include/clang/AST/ASTImporterLookupTable.h index 14cafe817ddc..407478a51058 100644 --- a/include/clang/AST/ASTImporterLookupTable.h +++ b/include/clang/AST/ASTImporterLookupTable.h @@ -1,9 +1,8 @@ //===- ASTImporterLookupTable.h - ASTImporter specific lookup--*- C++ -*---===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ASTImporterSharedState.h b/include/clang/AST/ASTImporterSharedState.h new file mode 100644 index 000000000000..3635a62deef0 --- /dev/null +++ b/include/clang/AST/ASTImporterSharedState.h @@ -0,0 +1,81 @@ +//===- ASTImporterSharedState.h - ASTImporter specific state --*- C++ -*---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ASTImporter specific state, which may be shared +// amongst several ASTImporter objects. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_ASTIMPORTERSHAREDSTATE_H +#define LLVM_CLANG_AST_ASTIMPORTERSHAREDSTATE_H + +#include "clang/AST/ASTImporterLookupTable.h" +#include "clang/AST/Decl.h" +#include "llvm/ADT/DenseMap.h" +// FIXME We need this because of ImportError. +#include "clang/AST/ASTImporter.h" + +namespace clang { + +class TranslationUnitDecl; + +/// Importer specific state, which may be shared amongst several ASTImporter +/// objects. +class ASTImporterSharedState { + + /// Pointer to the import specific lookup table. + std::unique_ptr LookupTable; + + /// Mapping from the already-imported declarations in the "to" + /// context to the error status of the import of that declaration. + /// This map contains only the declarations that were not correctly + /// imported. The same declaration may or may not be included in + /// ImportedFromDecls. This map is updated continuously during imports and + /// never cleared (like ImportedFromDecls). + llvm::DenseMap ImportErrors; + + // FIXME put ImportedFromDecls here! + // And from that point we can better encapsulate the lookup table. + +public: + ASTImporterSharedState() = default; + + ASTImporterSharedState(TranslationUnitDecl &ToTU) { + LookupTable = llvm::make_unique(ToTU); + } + + ASTImporterLookupTable *getLookupTable() { return LookupTable.get(); } + + void addDeclToLookup(Decl *D) { + if (LookupTable) + if (auto *ND = dyn_cast(D)) + LookupTable->add(ND); + } + + void removeDeclFromLookup(Decl *D) { + if (LookupTable) + if (auto *ND = dyn_cast(D)) + LookupTable->remove(ND); + } + + llvm::Optional getImportDeclErrorIfAny(Decl *ToD) const { + auto Pos = ImportErrors.find(ToD); + if (Pos != ImportErrors.end()) + return Pos->second; + else + return Optional(); + } + + void setImportDeclError(Decl *To, ImportError Error) { + ImportErrors[To] = Error; + } +}; + +} // namespace clang +#endif // LLVM_CLANG_AST_ASTIMPORTERSHAREDSTATE_H diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h index 6fedcb8d3801..c1153168e41b 100644 --- a/include/clang/AST/ASTLambda.h +++ b/include/clang/AST/ASTLambda.h @@ -1,9 +1,8 @@ //===--- ASTLambda.h - Lambda Helper Functions --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index 80184e1cc740..8879f9f3229f 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -1,9 +1,8 @@ //===--- ASTMutationListener.h - AST Mutation Interface --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -128,6 +127,11 @@ public: virtual void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, const Attr *Attr) {} + /// A declaration is marked as a variable with OpenMP allocator. + /// + /// \param D the declaration marked as a variable with OpenMP allocator. + virtual void DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) {} + /// A definition has been made visible by being redefined locally. /// /// \param D The definition that was previously not visible. diff --git a/include/clang/AST/ASTNodeTraverser.h b/include/clang/AST/ASTNodeTraverser.h new file mode 100644 index 000000000000..e43eacef86c6 --- /dev/null +++ b/include/clang/AST/ASTNodeTraverser.h @@ -0,0 +1,654 @@ +//===--- ASTNodeTraverser.h - Traversal of AST nodes ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the AST traversal facilities. Other users +// of this class may make use of the same traversal logic by inheriting it, +// similar to RecursiveASTVisitor. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_ASTNODETRAVERSER_H +#define LLVM_CLANG_AST_ASTNODETRAVERSER_H + +#include "clang/AST/AttrVisitor.h" +#include "clang/AST/CommentVisitor.h" +#include "clang/AST/DeclVisitor.h" +#include "clang/AST/LocInfoType.h" +#include "clang/AST/StmtVisitor.h" +#include "clang/AST/TemplateArgumentVisitor.h" +#include "clang/AST/TypeVisitor.h" + +namespace clang { + +/** + +ASTNodeTraverser traverses the Clang AST for dumping purposes. + +The `Derived::doGetNodeDelegate()` method is required to be an accessible member +which returns a reference of type `NodeDelegateType &` which implements the +following interface: + +struct { + template void AddChild(Fn DoAddChild); + template void AddChild(StringRef Label, Fn DoAddChild); + + void Visit(const comments::Comment *C, const comments::FullComment *FC); + void Visit(const Attr *A); + void Visit(const TemplateArgument &TA, SourceRange R = {}, + const Decl *From = nullptr, StringRef Label = {}); + void Visit(const Stmt *Node); + void Visit(const Type *T); + void Visit(QualType T); + void Visit(const Decl *D); + void Visit(const CXXCtorInitializer *Init); + void Visit(const OMPClause *C); + void Visit(const BlockDecl::Capture &C); + void Visit(const GenericSelectionExpr::ConstAssociation &A); +}; +*/ +template +class ASTNodeTraverser + : public ConstDeclVisitor, + public ConstStmtVisitor, + public comments::ConstCommentVisitor, + public TypeVisitor, + public ConstAttrVisitor, + public ConstTemplateArgumentVisitor { + + /// Indicates whether we should trigger deserialization of nodes that had + /// not already been loaded. + bool Deserialize = false; + + NodeDelegateType &getNodeDelegate() { + return getDerived().doGetNodeDelegate(); + } + Derived &getDerived() { return *static_cast(this); } + +public: + void setDeserialize(bool D) { Deserialize = D; } + bool getDeserialize() const { return Deserialize; } + + void Visit(const Decl *D) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(D); + if (!D) + return; + + ConstDeclVisitor::Visit(D); + + for (const auto &A : D->attrs()) + Visit(A); + + if (const comments::FullComment *Comment = + D->getASTContext().getLocalCommentForDeclUncached(D)) + Visit(Comment, Comment); + + // Decls within functions are visited by the body. + if (!isa(*D) && !isa(*D)) { + if (const auto *DC = dyn_cast(D)) + dumpDeclContext(DC); + } + }); + } + + void Visit(const Stmt *S, StringRef Label = {}) { + getNodeDelegate().AddChild(Label, [=] { + getNodeDelegate().Visit(S); + + if (!S) { + return; + } + + ConstStmtVisitor::Visit(S); + + // Some statements have custom mechanisms for dumping their children. + if (isa(S) || isa(S)) { + return; + } + + for (const Stmt *SubStmt : S->children()) + Visit(SubStmt); + }); + } + + void Visit(QualType T) { + SplitQualType SQT = T.split(); + if (!SQT.Quals.hasQualifiers()) + return Visit(SQT.Ty); + + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(T); + Visit(T.split().Ty); + }); + } + + void Visit(const Type *T) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(T); + if (!T) + return; + TypeVisitor::Visit(T); + + QualType SingleStepDesugar = + T->getLocallyUnqualifiedSingleStepDesugaredType(); + if (SingleStepDesugar != QualType(T, 0)) + Visit(SingleStepDesugar); + }); + } + + void Visit(const Attr *A) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(A); + ConstAttrVisitor::Visit(A); + }); + } + + void Visit(const CXXCtorInitializer *Init) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(Init); + Visit(Init->getInit()); + }); + } + + void Visit(const TemplateArgument &A, SourceRange R = {}, + const Decl *From = nullptr, const char *Label = nullptr) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(A, R, From, Label); + ConstTemplateArgumentVisitor::Visit(A); + }); + } + + void Visit(const BlockDecl::Capture &C) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(C); + if (C.hasCopyExpr()) + Visit(C.getCopyExpr()); + }); + } + + void Visit(const OMPClause *C) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(C); + for (const auto *S : C->children()) + Visit(S); + }); + } + + void Visit(const GenericSelectionExpr::ConstAssociation &A) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(A); + if (const TypeSourceInfo *TSI = A.getTypeSourceInfo()) + Visit(TSI->getType()); + Visit(A.getAssociationExpr()); + }); + } + + void Visit(const comments::Comment *C, const comments::FullComment *FC) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(C, FC); + if (!C) { + return; + } + comments::ConstCommentVisitor::visit(C, + FC); + for (comments::Comment::child_iterator I = C->child_begin(), + E = C->child_end(); + I != E; ++I) + Visit(*I, FC); + }); + } + + void Visit(const ast_type_traits::DynTypedNode &N) { + // FIXME: Improve this with a switch or a visitor pattern. + if (const auto *D = N.get()) + Visit(D); + else if (const auto *S = N.get()) + Visit(S); + else if (const auto *QT = N.get()) + Visit(*QT); + else if (const auto *T = N.get()) + Visit(T); + else if (const auto *C = N.get()) + Visit(C); + else if (const auto *C = N.get()) + Visit(C); + else if (const auto *T = N.get()) + Visit(*T); + } + + void dumpDeclContext(const DeclContext *DC) { + if (!DC) + return; + + for (const auto *D : (Deserialize ? DC->decls() : DC->noload_decls())) + Visit(D); + } + + void dumpTemplateParameters(const TemplateParameterList *TPL) { + if (!TPL) + return; + + for (const auto &TP : *TPL) + Visit(TP); + } + + void + dumpASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *TALI) { + if (!TALI) + return; + + for (const auto &TA : TALI->arguments()) + dumpTemplateArgumentLoc(TA); + } + + void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A, + const Decl *From = nullptr, + const char *Label = nullptr) { + Visit(A.getArgument(), A.getSourceRange(), From, Label); + } + + void dumpTemplateArgumentList(const TemplateArgumentList &TAL) { + for (unsigned i = 0, e = TAL.size(); i < e; ++i) + Visit(TAL[i]); + } + + void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) { + if (!typeParams) + return; + + for (const auto &typeParam : *typeParams) { + Visit(typeParam); + } + } + + void VisitComplexType(const ComplexType *T) { Visit(T->getElementType()); } + void VisitLocInfoType(const LocInfoType *T) { + Visit(T->getTypeSourceInfo()->getType()); + } + void VisitPointerType(const PointerType *T) { Visit(T->getPointeeType()); } + void VisitBlockPointerType(const BlockPointerType *T) { + Visit(T->getPointeeType()); + } + void VisitReferenceType(const ReferenceType *T) { + Visit(T->getPointeeType()); + } + void VisitMemberPointerType(const MemberPointerType *T) { + Visit(T->getClass()); + Visit(T->getPointeeType()); + } + void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); } + void VisitVariableArrayType(const VariableArrayType *T) { + VisitArrayType(T); + Visit(T->getSizeExpr()); + } + void VisitDependentSizedArrayType(const DependentSizedArrayType *T) { + Visit(T->getElementType()); + Visit(T->getSizeExpr()); + } + void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) { + Visit(T->getElementType()); + Visit(T->getSizeExpr()); + } + void VisitVectorType(const VectorType *T) { Visit(T->getElementType()); } + void VisitFunctionType(const FunctionType *T) { Visit(T->getReturnType()); } + void VisitFunctionProtoType(const FunctionProtoType *T) { + VisitFunctionType(T); + for (const QualType &PT : T->getParamTypes()) + Visit(PT); + } + void VisitTypeOfExprType(const TypeOfExprType *T) { + Visit(T->getUnderlyingExpr()); + } + void VisitDecltypeType(const DecltypeType *T) { + Visit(T->getUnderlyingExpr()); + } + void VisitUnaryTransformType(const UnaryTransformType *T) { + Visit(T->getBaseType()); + } + void VisitAttributedType(const AttributedType *T) { + // FIXME: AttrKind + Visit(T->getModifiedType()); + } + void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { + Visit(T->getReplacedParameter()); + } + void + VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) { + Visit(T->getReplacedParameter()); + Visit(T->getArgumentPack()); + } + void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { + for (const auto &Arg : *T) + Visit(Arg); + if (T->isTypeAlias()) + Visit(T->getAliasedType()); + } + void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { + Visit(T->getPointeeType()); + } + void VisitAtomicType(const AtomicType *T) { Visit(T->getValueType()); } + void VisitPipeType(const PipeType *T) { Visit(T->getElementType()); } + void VisitAdjustedType(const AdjustedType *T) { Visit(T->getOriginalType()); } + void VisitPackExpansionType(const PackExpansionType *T) { + if (!T->isSugared()) + Visit(T->getPattern()); + } + // FIXME: ElaboratedType, DependentNameType, + // DependentTemplateSpecializationType, ObjCObjectType + + void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); } + + void VisitEnumConstantDecl(const EnumConstantDecl *D) { + if (const Expr *Init = D->getInitExpr()) + Visit(Init); + } + + void VisitFunctionDecl(const FunctionDecl *D) { + if (const auto *FTSI = D->getTemplateSpecializationInfo()) + dumpTemplateArgumentList(*FTSI->TemplateArguments); + + if (D->param_begin()) + for (const auto *Parameter : D->parameters()) + Visit(Parameter); + + if (const auto *C = dyn_cast(D)) + for (const auto *I : C->inits()) + Visit(I); + + if (D->doesThisDeclarationHaveABody()) + Visit(D->getBody()); + } + + void VisitFieldDecl(const FieldDecl *D) { + if (D->isBitField()) + Visit(D->getBitWidth()); + if (Expr *Init = D->getInClassInitializer()) + Visit(Init); + } + + void VisitVarDecl(const VarDecl *D) { + if (D->hasInit()) + Visit(D->getInit()); + } + + void VisitDecompositionDecl(const DecompositionDecl *D) { + VisitVarDecl(D); + for (const auto *B : D->bindings()) + Visit(B); + } + + void VisitBindingDecl(const BindingDecl *D) { + if (const auto *E = D->getBinding()) + Visit(E); + } + + void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { + Visit(D->getAsmString()); + } + + void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); } + + void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) { + for (const auto *E : D->varlists()) + Visit(E); + } + + void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) { + Visit(D->getCombiner()); + if (const auto *Initializer = D->getInitializer()) + Visit(Initializer); + } + + void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) { + for (const auto *C : D->clauselists()) + Visit(C); + } + + void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) { + Visit(D->getInit()); + } + + void VisitOMPAllocateDecl(const OMPAllocateDecl *D) { + for (const auto *E : D->varlists()) + Visit(E); + for (const auto *C : D->clauselists()) + Visit(C); + } + + template + void dumpTemplateDeclSpecialization(const SpecializationDecl *D) { + for (const auto *RedeclWithBadType : D->redecls()) { + // FIXME: The redecls() range sometimes has elements of a less-specific + // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives + // us TagDecls, and should give CXXRecordDecls). + auto *Redecl = dyn_cast(RedeclWithBadType); + if (!Redecl) { + // Found the injected-class-name for a class template. This will be + // dumped as part of its surrounding class so we don't need to dump it + // here. + assert(isa(RedeclWithBadType) && + "expected an injected-class-name"); + continue; + } + Visit(Redecl); + } + } + + template + void dumpTemplateDecl(const TemplateDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + + Visit(D->getTemplatedDecl()); + + for (const auto *Child : D->specializations()) + dumpTemplateDeclSpecialization(Child); + } + + void VisitTypeAliasDecl(const TypeAliasDecl *D) { + Visit(D->getUnderlyingType()); + } + + void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + Visit(D->getTemplatedDecl()); + } + + void VisitStaticAssertDecl(const StaticAssertDecl *D) { + Visit(D->getAssertExpr()); + Visit(D->getMessage()); + } + + void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { + dumpTemplateDecl(D); + } + + void VisitClassTemplateDecl(const ClassTemplateDecl *D) { + dumpTemplateDecl(D); + } + + void VisitClassTemplateSpecializationDecl( + const ClassTemplateSpecializationDecl *D) { + dumpTemplateArgumentList(D->getTemplateArgs()); + } + + void VisitClassTemplatePartialSpecializationDecl( + const ClassTemplatePartialSpecializationDecl *D) { + VisitClassTemplateSpecializationDecl(D); + dumpTemplateParameters(D->getTemplateParameters()); + } + + void VisitClassScopeFunctionSpecializationDecl( + const ClassScopeFunctionSpecializationDecl *D) { + Visit(D->getSpecialization()); + dumpASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten()); + } + void VisitVarTemplateDecl(const VarTemplateDecl *D) { dumpTemplateDecl(D); } + + void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + } + + void + VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *D) { + dumpTemplateArgumentList(D->getTemplateArgs()); + VisitVarDecl(D); + } + + void VisitVarTemplatePartialSpecializationDecl( + const VarTemplatePartialSpecializationDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + VisitVarTemplateSpecializationDecl(D); + } + + void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { + if (D->hasDefaultArgument()) + Visit(D->getDefaultArgument(), SourceRange(), + D->getDefaultArgStorage().getInheritedFrom(), + D->defaultArgumentWasInherited() ? "inherited from" : "previous"); + } + + void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { + if (D->hasDefaultArgument()) + Visit(D->getDefaultArgument(), SourceRange(), + D->getDefaultArgStorage().getInheritedFrom(), + D->defaultArgumentWasInherited() ? "inherited from" : "previous"); + } + + void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + if (D->hasDefaultArgument()) + dumpTemplateArgumentLoc( + D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(), + D->defaultArgumentWasInherited() ? "inherited from" : "previous"); + } + + void VisitConceptDecl(const ConceptDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + Visit(D->getConstraintExpr()); + } + + void VisitUsingShadowDecl(const UsingShadowDecl *D) { + if (auto *TD = dyn_cast(D->getUnderlyingDecl())) + Visit(TD->getTypeForDecl()); + } + + void VisitFriendDecl(const FriendDecl *D) { + if (!D->getFriendType()) + Visit(D->getFriendDecl()); + } + + void VisitObjCMethodDecl(const ObjCMethodDecl *D) { + if (D->isThisDeclarationADefinition()) + dumpDeclContext(D); + else + for (const ParmVarDecl *Parameter : D->parameters()) + Visit(Parameter); + + if (D->hasBody()) + Visit(D->getBody()); + } + + void VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { + dumpObjCTypeParamList(D->getTypeParamList()); + } + + void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { + dumpObjCTypeParamList(D->getTypeParamListAsWritten()); + } + + void VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { + for (const auto &I : D->inits()) + Visit(I); + } + + void VisitBlockDecl(const BlockDecl *D) { + for (const auto &I : D->parameters()) + Visit(I); + + for (const auto &I : D->captures()) + Visit(I); + Visit(D->getBody()); + } + + void VisitDeclStmt(const DeclStmt *Node) { + for (const auto &D : Node->decls()) + Visit(D); + } + + void VisitAttributedStmt(const AttributedStmt *Node) { + for (const auto *A : Node->getAttrs()) + Visit(A); + } + + void VisitCXXCatchStmt(const CXXCatchStmt *Node) { + Visit(Node->getExceptionDecl()); + } + + void VisitCapturedStmt(const CapturedStmt *Node) { + Visit(Node->getCapturedDecl()); + } + + void VisitOMPExecutableDirective(const OMPExecutableDirective *Node) { + for (const auto *C : Node->clauses()) + Visit(C); + } + + void VisitInitListExpr(const InitListExpr *ILE) { + if (auto *Filler = ILE->getArrayFiller()) { + Visit(Filler, "array_filler"); + } + } + + void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); } + + void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { + if (Expr *Source = Node->getSourceExpr()) + Visit(Source); + } + + void VisitGenericSelectionExpr(const GenericSelectionExpr *E) { + Visit(E->getControllingExpr()); + Visit(E->getControllingExpr()->getType()); // FIXME: remove + + for (const auto &Assoc : E->associations()) { + Visit(Assoc); + } + } + + void VisitLambdaExpr(const LambdaExpr *Node) { + Visit(Node->getLambdaClass()); + } + + void VisitSizeOfPackExpr(const SizeOfPackExpr *Node) { + if (Node->isPartiallySubstituted()) + for (const auto &A : Node->getPartialArguments()) + Visit(A); + } + + void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { + if (const VarDecl *CatchParam = Node->getCatchParamDecl()) + Visit(CatchParam); + } + + void VisitExpressionTemplateArgument(const TemplateArgument &TA) { + Visit(TA.getAsExpr()); + } + void VisitPackTemplateArgument(const TemplateArgument &TA) { + for (const auto &TArg : TA.pack_elements()) + Visit(TArg); + } + + // Implements Visit methods for Attrs. +#include "clang/AST/AttrNodeTraverse.inc" +}; + +} // namespace clang + +#endif // LLVM_CLANG_AST_ASTNODETRAVERSER_H diff --git a/include/clang/AST/ASTStructuralEquivalence.h b/include/clang/AST/ASTStructuralEquivalence.h index f8847505bc72..70e0daa08a9a 100644 --- a/include/clang/AST/ASTStructuralEquivalence.h +++ b/include/clang/AST/ASTStructuralEquivalence.h @@ -1,9 +1,8 @@ //===- ASTStructuralEquivalence.h -------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -112,6 +111,10 @@ struct StructuralEquivalenceContext { static llvm::Optional findUntaggedStructOrUnionIndex(RecordDecl *Anon); + // If ErrorOnTagTypeMismatch is set, return the the error, otherwise get the + // relevant warning for the input error diagnostic. + unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic); + private: /// Finish checking all of the structural equivalences. /// diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h index 9df9793370c4..a29a04e5d242 100644 --- a/include/clang/AST/ASTTypeTraits.h +++ b/include/clang/AST/ASTTypeTraits.h @@ -1,9 +1,8 @@ //===--- ASTTypeTraits.h ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,6 +18,7 @@ #include "clang/AST/ASTFwd.h" #include "clang/AST/Decl.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/OpenMPClause.h" #include "clang/AST/Stmt.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TypeLoc.h" @@ -38,6 +38,17 @@ struct PrintingPolicy; namespace ast_type_traits { +/// Defines how we descend a level in the AST when we pass +/// through expressions. +enum TraversalKind { + /// Will traverse all child nodes. + TK_AsIs, + + /// Will not traverse implicit casts and parentheses. + /// Corresponds to Expr::IgnoreParenImpCasts() + TK_IgnoreImplicitCastsAndParentheses +}; + /// Kind identifier. /// /// It can be constructed from any node kind and allows for runtime type @@ -59,6 +70,7 @@ public: static ASTNodeKind getFromNode(const Decl &D); static ASTNodeKind getFromNode(const Stmt &S); static ASTNodeKind getFromNode(const Type &T); + static ASTNodeKind getFromNode(const OMPClause &C); /// \} /// Returns \c true if \c this and \c Other represent the same kind. @@ -137,6 +149,9 @@ private: NKI_Type, #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type, #include "clang/AST/TypeNodes.def" + NKI_OMPClause, +#define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class, +#include "clang/Basic/OpenMPKinds.def" NKI_NumberOfKinds }; @@ -184,12 +199,15 @@ KIND_TO_KIND_ID(TypeLoc) KIND_TO_KIND_ID(Decl) KIND_TO_KIND_ID(Stmt) KIND_TO_KIND_ID(Type) +KIND_TO_KIND_ID(OMPClause) #define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl) #include "clang/AST/DeclNodes.inc" #define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED) #include "clang/AST/StmtNodes.inc" #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type) #include "clang/AST/TypeNodes.def" +#define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class) +#include "clang/Basic/OpenMPKinds.def" #undef KIND_TO_KIND_ID inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) { @@ -460,6 +478,11 @@ struct DynTypedNode::BaseConverter< T, typename std::enable_if::value>::type> : public DynCastPtrConverter {}; +template +struct DynTypedNode::BaseConverter< + T, typename std::enable_if::value>::type> + : public DynCastPtrConverter {}; + template <> struct DynTypedNode::BaseConverter< NestedNameSpecifier, void> : public PtrConverter {}; diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h index 9bf63bb6e2d7..8d2b23b3539a 100644 --- a/include/clang/AST/ASTUnresolvedSet.h +++ b/include/clang/AST/ASTUnresolvedSet.h @@ -1,9 +1,8 @@ //===- ASTUnresolvedSet.h - Unresolved sets of declarations -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h index 51de119f080e..d5a04767ca13 100644 --- a/include/clang/AST/ASTVector.h +++ b/include/clang/AST/ASTVector.h @@ -1,9 +1,8 @@ //===- ASTVector.h - Vector that uses ASTContext for allocation ---*- C++ -*-=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 3a319326d269..1fbed7ceebfa 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -1,9 +1,8 @@ //===--- Attr.h - Classes for representing attributes ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h index 43ad1c931967..78ce9314a2bb 100644 --- a/include/clang/AST/AttrIterator.h +++ b/include/clang/AST/AttrIterator.h @@ -1,9 +1,8 @@ //===- AttrIterator.h - Classes for attribute iteration ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/AttrVisitor.h b/include/clang/AST/AttrVisitor.h index 867f9e7ad18d..d271db010ed1 100644 --- a/include/clang/AST/AttrVisitor.h +++ b/include/clang/AST/AttrVisitor.h @@ -1,9 +1,8 @@ //===- AttrVisitor.h - Visitor for Attr subclasses --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/Availability.h b/include/clang/AST/Availability.h index 28f3c3c01d20..527fc4b59a5f 100644 --- a/include/clang/AST/Availability.h +++ b/include/clang/AST/Availability.h @@ -1,9 +1,8 @@ //===--- Availability.h - Classes for availability --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h index 8fd4ac69ebd6..15600f02fcef 100644 --- a/include/clang/AST/BaseSubobject.h +++ b/include/clang/AST/BaseSubobject.h @@ -1,9 +1,8 @@ //===- BaseSubobject.h - BaseSubobject class --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -81,11 +80,6 @@ template<> struct DenseMapInfo { } }; -// It's OK to treat BaseSubobject as a POD type. -template <> struct isPodLike { - static const bool value = true; -}; - } // namespace llvm #endif // LLVM_CLANG_AST_BASESUBOBJECT_H diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def index 400efcb1981f..74a45ee4ccc0 100644 --- a/include/clang/AST/BuiltinTypes.def +++ b/include/clang/AST/BuiltinTypes.def @@ -1,9 +1,8 @@ //===-- BuiltinTypes.def - Metadata about BuiltinTypes ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index f5e23f8e8505..bb2ad9c64d3b 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -1,9 +1,8 @@ //===- CXXInheritance.h - C++ Inheritance -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index c2f01e7d5460..2e00d344533d 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -1,9 +1,8 @@ //===- CanonicalType.h - C Language Family Type Representation --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -510,7 +509,7 @@ struct CanProxyAdaptor } LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getTypeQuals) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getMethodQuals) using param_type_iterator = CanTypeIterator; diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h index 0aadf06fffc9..37f489c7708a 100644 --- a/include/clang/AST/CharUnits.h +++ b/include/clang/AST/CharUnits.h @@ -1,9 +1,8 @@ //===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -238,10 +237,6 @@ template<> struct DenseMapInfo { } }; -template <> struct isPodLike { - static const bool value = true; -}; - } // end namespace llvm #endif // LLVM_CLANG_AST_CHARUNITS_H diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h index 1b590562e152..2c284a271bb7 100644 --- a/include/clang/AST/Comment.h +++ b/include/clang/AST/Comment.h @@ -1,9 +1,8 @@ //===--- Comment.h - Comment AST nodes --------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CommentBriefParser.h b/include/clang/AST/CommentBriefParser.h index baa22930539e..cfd2137bd68c 100644 --- a/include/clang/AST/CommentBriefParser.h +++ b/include/clang/AST/CommentBriefParser.h @@ -1,9 +1,8 @@ //===--- CommentBriefParser.h - Dumb comment parser -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h index 4fd007872c01..83a29a540d42 100644 --- a/include/clang/AST/CommentCommandTraits.h +++ b/include/clang/AST/CommentCommandTraits.h @@ -1,9 +1,8 @@ //===--- CommentCommandTraits.h - Comment command properties ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CommentDiagnostic.h b/include/clang/AST/CommentDiagnostic.h index b9816f1a8e62..2e498d5db386 100644 --- a/include/clang/AST/CommentDiagnostic.h +++ b/include/clang/AST/CommentDiagnostic.h @@ -1,9 +1,8 @@ //===--- CommentDiagnostic.h - Diagnostics for the AST library --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h index 3ef5b7c8c998..9ddbb7d31d99 100644 --- a/include/clang/AST/CommentLexer.h +++ b/include/clang/AST/CommentLexer.h @@ -1,9 +1,8 @@ //===--- CommentLexer.h - Lexer for structured comments ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h index fa8862899c14..1a0cfb06e52b 100644 --- a/include/clang/AST/CommentParser.h +++ b/include/clang/AST/CommentParser.h @@ -1,9 +1,8 @@ //===--- CommentParser.h - Doxygen comment parser ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h index 632eba782b92..307618fa5363 100644 --- a/include/clang/AST/CommentSema.h +++ b/include/clang/AST/CommentSema.h @@ -1,9 +1,8 @@ //===--- CommentSema.h - Doxygen comment semantic analysis ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CommentVisitor.h b/include/clang/AST/CommentVisitor.h index e37e9d6cd299..d9a7439f7cc0 100644 --- a/include/clang/AST/CommentVisitor.h +++ b/include/clang/AST/CommentVisitor.h @@ -1,9 +1,8 @@ //===- CommentVisitor.h - Visitor for Comment subclasses --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/ComparisonCategories.h b/include/clang/AST/ComparisonCategories.h index 23bfd708e7eb..9d591cc81495 100644 --- a/include/clang/AST/ComparisonCategories.h +++ b/include/clang/AST/ComparisonCategories.h @@ -1,9 +1,8 @@ //===- ComparisonCategories.h - Three Way Comparison Data -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CurrentSourceLocExprScope.h b/include/clang/AST/CurrentSourceLocExprScope.h new file mode 100644 index 000000000000..4ebbdf63abb5 --- /dev/null +++ b/include/clang/AST/CurrentSourceLocExprScope.h @@ -0,0 +1,75 @@ +//===--- CurrentSourceLocExprScope.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines types used to track the current context needed to evaluate +// a SourceLocExpr. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H +#define LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H + +#include + +namespace clang { +class Expr; + +/// Represents the current source location and context used to determine the +/// value of the source location builtins (ex. __builtin_LINE), including the +/// context of default argument and default initializer expressions. +class CurrentSourceLocExprScope { + /// The CXXDefaultArgExpr or CXXDefaultInitExpr we're currently evaluating. + const Expr *DefaultExpr = nullptr; + +public: + /// A RAII style scope guard used for tracking the current source + /// location and context as used by the source location builtins + /// (ex. __builtin_LINE). + class SourceLocExprScopeGuard; + + const Expr *getDefaultExpr() const { return DefaultExpr; } + + explicit CurrentSourceLocExprScope() = default; + +private: + explicit CurrentSourceLocExprScope(const Expr *DefaultExpr) + : DefaultExpr(DefaultExpr) {} + + CurrentSourceLocExprScope(CurrentSourceLocExprScope const &) = default; + CurrentSourceLocExprScope & + operator=(CurrentSourceLocExprScope const &) = default; +}; + +class CurrentSourceLocExprScope::SourceLocExprScopeGuard { +public: + SourceLocExprScopeGuard(const Expr *DefaultExpr, + CurrentSourceLocExprScope &Current) + : Current(Current), OldVal(Current), Enable(false) { + assert(DefaultExpr && "the new scope should not be empty"); + if ((Enable = (Current.getDefaultExpr() == nullptr))) + Current = CurrentSourceLocExprScope(DefaultExpr); + } + + ~SourceLocExprScopeGuard() { + if (Enable) + Current = OldVal; + } + +private: + SourceLocExprScopeGuard(SourceLocExprScopeGuard const &) = delete; + SourceLocExprScopeGuard &operator=(SourceLocExprScopeGuard const &) = delete; + + CurrentSourceLocExprScope &Current; + CurrentSourceLocExprScope OldVal; + bool Enable; +}; + +} // end namespace clang + +#endif // LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H diff --git a/include/clang/AST/DataCollection.h b/include/clang/AST/DataCollection.h index 8b2a8345d941..37f101793ecc 100644 --- a/include/clang/AST/DataCollection.h +++ b/include/clang/AST/DataCollection.h @@ -1,9 +1,8 @@ //===--- DatatCollection.h --------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index de2765391f0f..02742801f37c 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1,9 +1,8 @@ //===- Decl.h - Classes for representing declarations -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -1227,10 +1226,15 @@ public: void setInit(Expr *I); - /// Determine whether this variable's value can be used in a + /// Determine whether this variable's value might be usable in a /// constant expression, according to the relevant language standard. /// This only checks properties of the declaration, and does not check /// whether the initializer is in fact a constant expression. + bool mightBeUsableInConstantExpressions(ASTContext &C) const; + + /// Determine whether this variable's value can be used in a + /// constant expression, according to the relevant language standard, + /// including checking whether it was initialized by a constant expression. bool isUsableInConstantExpressions(ASTContext &C) const; EvaluatedStmt *ensureEvaluatedStmt() const; @@ -1396,6 +1400,10 @@ public: NonParmVarDeclBits.IsInitCapture = IC; } + /// Determine whether this variable is actually a function parameter pack or + /// init-capture pack. + bool isParameterPack() const; + /// Whether this local extern variable declaration's previous declaration /// was declared in the same block scope. Only correct in C++. bool isPreviousDeclInSameBlockScope() const { @@ -1435,6 +1443,12 @@ public: /// template specialization or instantiation this is. TemplateSpecializationKind getTemplateSpecializationKind() const; + /// Get the template specialization kind of this variable for the purposes of + /// template instantiation. This differs from getTemplateSpecializationKind() + /// for an instantiation of a class-scope explicit specialization. + TemplateSpecializationKind + getTemplateSpecializationKindForInstantiation() const; + /// If this variable is an instantiation of a variable template or a /// static data member of a class template, determine its point of /// instantiation. @@ -1683,10 +1697,6 @@ public: QualType getOriginalType() const; - /// Determine whether this parameter is actually a function - /// parameter pack. - bool isParameterPack() const; - /// Sets the function declaration that owns this /// ParmVarDecl. Since ParmVarDecls are often created before the /// FunctionDecls that own them, this routine is required to update @@ -1743,10 +1753,19 @@ class FunctionDecl : public DeclaratorDecl, public: /// The kind of templated function a FunctionDecl can be. enum TemplatedKind { + // Not templated. TK_NonTemplate, + // The pattern in a function template declaration. TK_FunctionTemplate, + // A non-template function that is an instantiation or explicit + // specialization of a member of a templated class. TK_MemberSpecialization, + // An instantiation or explicit specialization of a function template. + // Note: this might have been instantiated from a templated class if it + // is a class-scope explicit specialization. TK_FunctionTemplateSpecialization, + // A function template specialization that hasn't yet been resolved to a + // particular specialized function template. TK_DependentFunctionTemplateSpecialization }; @@ -1842,7 +1861,7 @@ protected: FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified, - bool isConstexprSpecified); + ConstexprSpecKind ConstexprKind); using redeclarable_base = Redeclarable; @@ -1872,29 +1891,24 @@ public: using redeclarable_base::getMostRecentDecl; using redeclarable_base::isFirstDecl; - static FunctionDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation StartLoc, SourceLocation NLoc, - DeclarationName N, QualType T, - TypeSourceInfo *TInfo, - StorageClass SC, - bool isInlineSpecified = false, - bool hasWrittenPrototype = true, - bool isConstexprSpecified = false) { + static FunctionDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation NLoc, DeclarationName N, QualType T, + TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified = false, + bool hasWrittenPrototype = true, + ConstexprSpecKind ConstexprKind = CSK_unspecified) { DeclarationNameInfo NameInfo(N, NLoc); - return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, - SC, + return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC, isInlineSpecified, hasWrittenPrototype, - isConstexprSpecified); + ConstexprKind); } static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - StorageClass SC, - bool isInlineSpecified, - bool hasWrittenPrototype, - bool isConstexprSpecified = false); + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, StorageClass SC, + bool isInlineSpecified, bool hasWrittenPrototype, + ConstexprSpecKind ConstexprKind); static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2091,8 +2105,21 @@ public: } /// Whether this is a (C++11) constexpr function or constexpr constructor. - bool isConstexpr() const { return FunctionDeclBits.IsConstexpr; } - void setConstexpr(bool IC) { FunctionDeclBits.IsConstexpr = IC; } + bool isConstexpr() const { + return FunctionDeclBits.ConstexprKind != CSK_unspecified; + } + void setConstexprKind(ConstexprSpecKind CSK) { + FunctionDeclBits.ConstexprKind = CSK; + } + ConstexprSpecKind getConstexprKind() const { + return static_cast(FunctionDeclBits.ConstexprKind); + } + bool isConstexprSpecified() const { + return FunctionDeclBits.ConstexprKind == CSK_constexpr; + } + bool isConsteval() const { + return FunctionDeclBits.ConstexprKind == CSK_consteval; + } /// Whether the instantiation of this function is pending. /// This bit is set when the decision to instantiate this function is made @@ -2256,7 +2283,7 @@ public: return const_cast(this)->getCanonicalDecl(); } - unsigned getBuiltinID() const; + unsigned getBuiltinID(bool ConsiderWrapperFunctions = false) const; // ArrayRef interface to parameters. ArrayRef parameters() const { @@ -2316,6 +2343,14 @@ public: return T->castAs()->getReturnType(); } + /// Gets the ExceptionSpecificationType as declared. + ExceptionSpecificationType getExceptionSpecType() const { + auto *TSI = getTypeSourceInfo(); + QualType T = TSI ? TSI->getType() : getType(); + const auto *FPT = T->getAs(); + return FPT ? FPT->getExceptionSpecType() : EST_None; + } + /// Attempt to compute an informative source range covering the /// function exception specification, if any. SourceRange getExceptionSpecSourceRange() const; @@ -2355,22 +2390,14 @@ public: /// that was defined in the class body. bool isInlined() const { return FunctionDeclBits.IsInline; } - /// Whether this function is marked as explicit explicitly. - bool isExplicitSpecified() const { - return FunctionDeclBits.IsExplicitSpecified; - } - - /// State that this function is marked as explicit explicitly. - void setExplicitSpecified(bool ExpSpec = true) { - FunctionDeclBits.IsExplicitSpecified = ExpSpec; - } - bool isInlineDefinitionExternallyVisible() const; bool isMSExternInline() const; bool doesDeclarationForceExternallyVisibleDefinition() const; + bool isStatic() const { return getStorageClass() == SC_Static; } + /// Whether this function declaration represents an C++ overloaded /// operator, e.g., "operator+". bool isOverloadedOperator() const { @@ -2441,10 +2468,6 @@ public: return getPrimaryTemplate() != nullptr; } - /// Retrieve the class scope template pattern that this function - /// template specialization is instantiated from. - FunctionDecl *getClassScopeSpecializationPattern() const; - /// If this function is actually a function template specialization, /// retrieve information about this function template specialization. /// Otherwise, returns NULL. @@ -2531,6 +2554,11 @@ public: /// represents. TemplateSpecializationKind getTemplateSpecializationKind() const; + /// Determine the kind of template specialization this function represents + /// for the purpose of template instantiation. + TemplateSpecializationKind + getTemplateSpecializationKindForInstantiation() const; + /// Determine what kind of template instantiation this function /// represents. void setTemplateSpecializationKind(TemplateSpecializationKind TSK, @@ -2703,6 +2731,11 @@ public: /// bit-fields. bool isZeroLengthBitField(const ASTContext &Ctx) const; + /// Determine if this field is a subobject of zero size, that is, either a + /// zero-length bit-field or a field of empty class type with the + /// [[no_unique_address]] attribute. + bool isZeroSize(const ASTContext &Ctx) const; + /// Get the kind of (C++11) default member initializer that this field has. InClassInitStyle getInClassInitStyle() const { InitStorageKind storageKind = InitStorage.getInt(); @@ -3713,6 +3746,30 @@ public: RecordDeclBits.NonTrivialToPrimitiveDestroy = V; } + bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const { + return RecordDeclBits.HasNonTrivialToPrimitiveDefaultInitializeCUnion; + } + + void setHasNonTrivialToPrimitiveDefaultInitializeCUnion(bool V) { + RecordDeclBits.HasNonTrivialToPrimitiveDefaultInitializeCUnion = V; + } + + bool hasNonTrivialToPrimitiveDestructCUnion() const { + return RecordDeclBits.HasNonTrivialToPrimitiveDestructCUnion; + } + + void setHasNonTrivialToPrimitiveDestructCUnion(bool V) { + RecordDeclBits.HasNonTrivialToPrimitiveDestructCUnion = V; + } + + bool hasNonTrivialToPrimitiveCopyCUnion() const { + return RecordDeclBits.HasNonTrivialToPrimitiveCopyCUnion; + } + + void setHasNonTrivialToPrimitiveCopyCUnion(bool V) { + RecordDeclBits.HasNonTrivialToPrimitiveCopyCUnion = V; + } + /// Determine whether this class can be passed in registers. In C++ mode, /// it must have at least one trivial, non-deleted copy or move constructor. /// FIXME: This should be set as part of completeDefinition. @@ -3852,7 +3909,7 @@ public: static bool classofKind(Kind K) { return K == FileScopeAsm; } }; -/// Pepresents a block literal declaration, which is like an +/// Represents a block literal declaration, which is like an /// unnamed FunctionDecl. For example: /// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } class BlockDecl : public Decl, public DeclContext { @@ -4009,6 +4066,13 @@ public: bool doesNotEscape() const { return BlockDeclBits.DoesNotEscape; } void setDoesNotEscape(bool B = true) { BlockDeclBits.DoesNotEscape = B; } + bool canAvoidCopyToHeap() const { + return BlockDeclBits.CanAvoidCopyToHeap; + } + void setCanAvoidCopyToHeap(bool B = true) { + BlockDeclBits.CanAvoidCopyToHeap = B; + } + bool capturesVariable(const VarDecl *var) const; void setCaptures(ASTContext &Context, ArrayRef Captures, @@ -4233,8 +4297,10 @@ public: SourceLocation getRBraceLoc() const { return RBraceLoc; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } + bool hasBraces() const { return RBraceLoc.isValid(); } + SourceLocation getEndLoc() const LLVM_READONLY { - if (RBraceLoc.isValid()) + if (hasBraces()) return RBraceLoc; // No braces: get the end location of the (only) declaration in context // (if present). diff --git a/include/clang/AST/DeclAccessPair.h b/include/clang/AST/DeclAccessPair.h index 3c5056c6e55b..805342c2910a 100644 --- a/include/clang/AST/DeclAccessPair.h +++ b/include/clang/AST/DeclAccessPair.h @@ -1,9 +1,8 @@ //===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -61,12 +60,4 @@ public: }; } -// Take a moment to tell SmallVector that DeclAccessPair is POD. -namespace llvm { -template struct isPodLike; -template<> struct isPodLike { - static const bool value = true; -}; -} - #endif diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 8405a43fa098..d64d0cb425db 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -1,9 +1,8 @@ //===- DeclBase.h - Base Classes for representing declarations --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -14,6 +13,7 @@ #ifndef LLVM_CLANG_AST_DECLBASE_H #define LLVM_CLANG_AST_DECLBASE_H +#include "clang/AST/ASTDumperUtils.h" #include "clang/AST/AttrIterator.h" #include "clang/AST/DeclarationName.h" #include "clang/Basic/IdentifierTable.h" @@ -42,6 +42,7 @@ namespace clang { class ASTContext; class ASTMutationListener; class Attr; +class BlockDecl; class DeclContext; class ExternalSourceSymbolAttr; class FunctionDecl; @@ -176,7 +177,10 @@ public: IDNS_LocalExtern = 0x0800, /// This declaration is an OpenMP user defined reduction construction. - IDNS_OMPReduction = 0x1000 + IDNS_OMPReduction = 0x1000, + + /// This declaration is an OpenMP user defined mapper. + IDNS_OMPMapper = 0x2000, }; /// ObjCDeclQualifier - 'Qualifiers' written next to the return and @@ -324,7 +328,7 @@ protected: unsigned FromASTFile : 1; /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in. - unsigned IdentifierNamespace : 13; + unsigned IdentifierNamespace : 14; /// If 0, we have not computed the linkage of this declaration. /// Otherwise, it is the linkage + 1. @@ -364,6 +368,13 @@ private: return ModuleOwnershipKind::Unowned; } +public: + Decl() = delete; + Decl(const Decl&) = delete; + Decl(Decl &&) = delete; + Decl &operator=(const Decl&) = delete; + Decl &operator=(Decl&&) = delete; + protected: Decl(Kind DK, DeclContext *DC, SourceLocation L) : NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)), @@ -597,10 +608,6 @@ public: return getModuleOwnershipKind() == ModuleOwnershipKind::ModulePrivate; } - /// 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; @@ -1135,7 +1142,8 @@ public: // Same as dump(), but forces color printing. void dumpColor() const; - void dump(raw_ostream &Out, bool Deserialize = false) const; + void dump(raw_ostream &Out, bool Deserialize = false, + ASTDumpOutputFormat OutputFormat = ADOF_Default) const; /// \return Unique reproducible object identifier int64_t getID() const; @@ -1252,6 +1260,7 @@ public: /// NamespaceDecl /// TagDecl /// OMPDeclareReductionDecl +/// OMPDeclareMapperDecl /// FunctionDecl /// ObjCMethodDecl /// ObjCContainerDecl @@ -1431,6 +1440,13 @@ class DeclContext { uint64_t NonTrivialToPrimitiveCopy : 1; uint64_t NonTrivialToPrimitiveDestroy : 1; + /// The following bits indicate whether this is or contains a C union that + /// is non-trivial to default-initialize, destruct, or copy. These bits + /// imply the associated basic non-triviality predicates declared above. + uint64_t HasNonTrivialToPrimitiveDefaultInitializeCUnion : 1; + uint64_t HasNonTrivialToPrimitiveDestructCUnion : 1; + uint64_t HasNonTrivialToPrimitiveCopyCUnion : 1; + /// Indicates whether this struct is destroyed in the callee. uint64_t ParamDestroyedInCallee : 1; @@ -1439,7 +1455,7 @@ class DeclContext { }; /// Number of non-inherited bits in RecordDeclBitfields. - enum { NumRecordDeclBits = 11 }; + enum { NumRecordDeclBits = 14 }; /// Stores the bits used by OMPDeclareReductionDecl. /// If modified NumOMPDeclareReductionDeclBits and the accessor @@ -1472,10 +1488,6 @@ class DeclContext { uint64_t IsInline : 1; uint64_t IsInlineSpecified : 1; - /// This is shared by CXXConstructorDecl, - /// CXXConversionDecl, and CXXDeductionGuideDecl. - uint64_t IsExplicitSpecified : 1; - uint64_t IsVirtualAsWritten : 1; uint64_t IsPure : 1; uint64_t HasInheritedPrototype : 1; @@ -1495,7 +1507,9 @@ class DeclContext { uint64_t IsExplicitlyDefaulted : 1; uint64_t HasImplicitReturnZero : 1; uint64_t IsLateTemplateParsed : 1; - uint64_t IsConstexpr : 1; + + /// Kind of contexpr specifier as defined by ConstexprSpecKind. + uint64_t ConstexprKind : 2; uint64_t InstantiationIsPending : 1; /// Indicates if the function uses __try. @@ -1535,17 +1549,25 @@ class DeclContext { /// For the bits in FunctionDeclBitfields. uint64_t : NumFunctionDeclBits; - /// 25 bits to fit in the remaining availible space. + /// 24 bits to fit in the remaining available space. /// Note that this makes CXXConstructorDeclBitfields take /// exactly 64 bits and thus the width of NumCtorInitializers /// will need to be shrunk if some bit is added to NumDeclContextBitfields, /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields. - uint64_t NumCtorInitializers : 25; + uint64_t NumCtorInitializers : 23; uint64_t IsInheritingConstructor : 1; + + /// Whether this constructor has a trail-allocated explicit specifier. + uint64_t HasTrailingExplicitSpecifier : 1; + /// If this constructor does't have a trail-allocated explicit specifier. + /// Whether this constructor is explicit specified. + uint64_t IsSimpleExplicit : 1; }; /// Number of non-inherited bits in CXXConstructorDeclBitfields. - enum { NumCXXConstructorDeclBits = 26 }; + enum { + NumCXXConstructorDeclBits = 64 - NumDeclContextBits - NumFunctionDeclBits + }; /// Stores the bits used by ObjCMethodDecl. /// If modified NumObjCMethodDeclBits and the accessor @@ -1662,6 +1684,11 @@ class DeclContext { /// A bit that indicates this block is passed directly to a function as a /// non-escaping parameter. uint64_t DoesNotEscape : 1; + + /// A bit that indicates whether it's possible to avoid coying this block to + /// the heap when it initializes or is assigned to a local variable with + /// automatic storage. + uint64_t CanAvoidCopyToHeap : 1; }; /// Number of non-inherited bits in BlockDeclBitfields. @@ -1784,6 +1811,10 @@ public: bool isClosure() const { return getDeclKind() == Decl::Block; } + /// Return this DeclContext if it is a BlockDecl. Otherwise, return the + /// innermost enclosing BlockDecl or null if there are no enclosing blocks. + const BlockDecl *getInnermostBlockDecl() const; + bool isObjCContainer() const { switch (getDeclKind()) { case Decl::ObjCCategory: diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index d3357c245d86..7add83f89624 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1,9 +1,8 @@ //===- DeclCXX.h - Classes for representing C++ declarations --*- C++ -*-=====// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -64,6 +63,7 @@ class CXXDestructorDecl; class CXXFinalOverriderMap; class CXXIndirectPrimaryBaseSet; class CXXMethodDecl; +class DecompositionDecl; class DiagnosticBuilder; class FriendDecl; class FunctionTemplateDecl; @@ -334,10 +334,12 @@ class CXXRecordDecl : public RecordDecl { /// True when this class is a POD-type. unsigned PlainOldData : 1; - /// true when this class is empty for traits purposes, - /// i.e. has no data members other than 0-width bit-fields, has no - /// virtual function/base, and doesn't inherit from a non-empty - /// class. Doesn't take union-ness into account. + /// True when this class is empty for traits purposes, that is: + /// * has no data members other than 0-width bit-fields and empty fields + /// marked [[no_unique_address]] + /// * has no virtual function/base, and + /// * doesn't inherit from a non-empty class. + /// Doesn't take union-ness into account. unsigned Empty : 1; /// True when this class is polymorphic, i.e., has at @@ -1222,6 +1224,9 @@ public: /// lambda. TemplateParameterList *getGenericLambdaTemplateParameterList() const; + /// Retrieve the lambda template parameters that were specified explicitly. + ArrayRef getLambdaExplicitTemplateParameters() const; + LambdaCaptureDefault getLambdaCaptureDefault() const { assert(isLambda()); return static_cast(getLambdaData().CaptureDefault); @@ -1326,6 +1331,14 @@ public: /// \note This does NOT include a check for union-ness. bool isEmpty() const { return data().Empty; } + bool hasPrivateFields() const { + return data().HasPrivateFields; + } + + bool hasProtectedFields() const { + return data().HasProtectedFields; + } + /// Determine whether this class has direct non-static data members. bool hasDirectFields() const { auto &D = data(); @@ -1828,6 +1841,14 @@ public: static bool FindOMPReductionMember(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, DeclarationName Name); + /// Base-class lookup callback that determines whether there exists + /// an OpenMP declare mapper member with the given name. + /// + /// This callback can be used with \c lookupInBases() to find members + /// of the given name within a C++ class hierarchy. + static bool FindOMPMapperMember(const CXXBaseSpecifier *Specifier, + CXXBasePath &Path, DeclarationName Name); + /// Base-class lookup callback that determines whether there exists /// a member with the given name that can be used in a nested-name-specifier. /// @@ -1975,6 +1996,53 @@ public: } }; +/// Store information needed for an explicit specifier. +/// used by CXXDeductionGuideDecl, CXXConstructorDecl and CXXConversionDecl. +class ExplicitSpecifier { + llvm::PointerIntPair ExplicitSpec{ + nullptr, ExplicitSpecKind::ResolvedFalse}; + +public: + ExplicitSpecifier() = default; + ExplicitSpecifier(Expr *Expression, ExplicitSpecKind Kind) + : ExplicitSpec(Expression, Kind) {} + ExplicitSpecKind getKind() const { return ExplicitSpec.getInt(); } + const Expr *getExpr() const { return ExplicitSpec.getPointer(); } + Expr *getExpr() { return ExplicitSpec.getPointer(); } + + /// Return true if the ExplicitSpecifier isn't defaulted. + bool isSpecified() const { + return ExplicitSpec.getInt() != ExplicitSpecKind::ResolvedFalse || + ExplicitSpec.getPointer(); + } + + /// Check for Equivalence of explicit specifiers. + /// Return True if the explicit specifier are equivalent false otherwise. + bool isEquivalent(const ExplicitSpecifier Other) const; + /// Return true if the explicit specifier is already resolved to be explicit. + bool isExplicit() const { + return ExplicitSpec.getInt() == ExplicitSpecKind::ResolvedTrue; + } + /// Return true if the ExplicitSpecifier isn't valid. + /// This state occurs after a substitution failures. + bool isInvalid() const { + return ExplicitSpec.getInt() == ExplicitSpecKind::Unresolved && + !ExplicitSpec.getPointer(); + } + void setKind(ExplicitSpecKind Kind) { ExplicitSpec.setInt(Kind); } + void setExpr(Expr *E) { ExplicitSpec.setPointer(E); } + // getFromDecl - retrieve the explicit specifier in the given declaration. + // if the given declaration has no explicit. the returned explicit specifier + // is defaulted. .isSpecified() will be false. + static ExplicitSpecifier getFromDecl(FunctionDecl *Function); + static const ExplicitSpecifier getFromDecl(const FunctionDecl *Function) { + return getFromDecl(const_cast(Function)); + } + static ExplicitSpecifier Invalid() { + return ExplicitSpecifier(nullptr, ExplicitSpecKind::Unresolved); + } +}; + /// Represents a C++ deduction guide declaration. /// /// \code @@ -1990,31 +2058,36 @@ class CXXDeductionGuideDecl : public FunctionDecl { private: CXXDeductionGuideDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - bool IsExplicit, const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - SourceLocation EndLocation) + ExplicitSpecifier ES, + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, SourceLocation EndLocation) : FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo, - SC_None, false, false) { + SC_None, false, CSK_unspecified), + ExplicitSpec(ES) { if (EndLocation.isValid()) setRangeEnd(EndLocation); - setExplicitSpecified(IsExplicit); setIsCopyDeductionCandidate(false); } + ExplicitSpecifier ExplicitSpec; + void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; } + public: friend class ASTDeclReader; friend class ASTDeclWriter; - static CXXDeductionGuideDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation StartLoc, bool IsExplicit, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - SourceLocation EndLocation); + static CXXDeductionGuideDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, SourceLocation EndLocation); static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, unsigned ID); - /// Whether this deduction guide is explicit. - bool isExplicit() const { return isExplicitSpecified(); } + ExplicitSpecifier getExplicitSpecifier() { return ExplicitSpec; } + const ExplicitSpecifier getExplicitSpecifier() const { return ExplicitSpec; } + + /// Return true if the declartion is already resolved to be explicit. + bool isExplicit() const { return ExplicitSpec.isExplicit(); } /// Get the template for which this guide performs deduction. TemplateDecl *getDeducedTemplate() const { @@ -2044,11 +2117,11 @@ class CXXMethodDecl : public FunctionDecl { protected: CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - StorageClass SC, bool isInline, - bool isConstexpr, SourceLocation EndLocation) - : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, - SC, isInline, isConstexpr) { + QualType T, TypeSourceInfo *TInfo, StorageClass SC, + bool isInline, ConstexprSpecKind ConstexprKind, + SourceLocation EndLocation) + : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, isInline, + ConstexprKind) { if (EndLocation.isValid()) setRangeEnd(EndLocation); } @@ -2056,11 +2129,9 @@ protected: public: static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - StorageClass SC, - bool isInline, - bool isConstexpr, + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, StorageClass SC, + bool isInline, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation); static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2161,20 +2232,20 @@ public: overridden_method_range overridden_methods() const; - /// Returns the parent of this method declaration, which + /// Return the parent of this method declaration, which /// is the class in which this method is defined. const CXXRecordDecl *getParent() const { return cast(FunctionDecl::getParent()); } - /// Returns the parent of this method declaration, which + /// Return the parent of this method declaration, which /// is the class in which this method is defined. CXXRecordDecl *getParent() { return const_cast( cast(FunctionDecl::getParent())); } - /// Returns the type of the \c this pointer. + /// Return the type of the \c this pointer. /// /// Should only be called for instance (i.e., non-static) methods. Note /// that for the call operator of a lambda closure type, this returns the @@ -2182,11 +2253,19 @@ public: /// 'this' type. QualType getThisType() const; + /// Return the type of the object pointed by \c this. + /// + /// See getThisType() for usage restriction. + QualType getThisObjectType() const; + static QualType getThisType(const FunctionProtoType *FPT, const CXXRecordDecl *Decl); - Qualifiers getTypeQualifiers() const { - return getType()->getAs()->getTypeQuals(); + static QualType getThisObjectType(const FunctionProtoType *FPT, + const CXXRecordDecl *Decl); + + Qualifiers getMethodQualifiers() const { + return getType()->getAs()->getMethodQuals(); } /// Retrieve the ref-qualifier associated with this method. @@ -2231,6 +2310,17 @@ public: ->getCorrespondingMethodInClass(RD, MayBeBase); } + /// Find if \p RD declares a function that overrides this function, and if so, + /// return it. Does not search base classes. + CXXMethodDecl *getCorrespondingMethodDeclaredInClass(const CXXRecordDecl *RD, + bool MayBeBase = false); + const CXXMethodDecl * + getCorrespondingMethodDeclaredInClass(const CXXRecordDecl *RD, + bool MayBeBase = false) const { + return const_cast(this) + ->getCorrespondingMethodDeclaredInClass(RD, MayBeBase); + } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { @@ -2483,7 +2573,8 @@ public: /// \endcode class CXXConstructorDecl final : public CXXMethodDecl, - private llvm::TrailingObjects { + private llvm::TrailingObjects { // This class stores some data in DeclContext::CXXConstructorDeclBits // to save some space. Use the provided accessors to access it. @@ -2493,28 +2584,74 @@ class CXXConstructorDecl final LazyCXXCtorInitializersPtr CtorInitializers; CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - bool isExplicitSpecified, bool isInline, - bool isImplicitlyDeclared, bool isConstexpr, + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool isInline, + bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited); void anchor() override; + size_t numTrailingObjects(OverloadToken) const { + return CXXConstructorDeclBits.IsInheritingConstructor; + } + size_t numTrailingObjects(OverloadToken) const { + return CXXConstructorDeclBits.HasTrailingExplicitSpecifier; + } + + ExplicitSpecifier getExplicitSpecifierInternal() const { + if (CXXConstructorDeclBits.HasTrailingExplicitSpecifier) + return *getCanonicalDecl()->getTrailingObjects(); + return ExplicitSpecifier( + nullptr, getCanonicalDecl()->CXXConstructorDeclBits.IsSimpleExplicit + ? ExplicitSpecKind::ResolvedTrue + : ExplicitSpecKind::ResolvedFalse); + } + + void setExplicitSpecifier(ExplicitSpecifier ES) { + assert((!ES.getExpr() || + CXXConstructorDeclBits.HasTrailingExplicitSpecifier) && + "cannot set this explicit specifier. no trail-allocated space for " + "explicit"); + if (ES.getExpr()) + *getCanonicalDecl()->getTrailingObjects() = ES; + else + CXXConstructorDeclBits.IsSimpleExplicit = ES.isExplicit(); + } + + enum TraillingAllocKind { + TAKInheritsConstructor = 1, + TAKHasTailExplicit = 1 << 1, + }; + + uint64_t getTraillingAllocKind() const { + return numTrailingObjects(OverloadToken()) | + (numTrailingObjects(OverloadToken()) << 1); + } + public: friend class ASTDeclReader; friend class ASTDeclWriter; friend TrailingObjects; static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID, - bool InheritsConstructor); + uint64_t AllocKind); static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - bool isExplicit, bool isInline, bool isImplicitlyDeclared, - bool isConstexpr, + ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared, + ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited = InheritedConstructor()); + ExplicitSpecifier getExplicitSpecifier() { + return getExplicitSpecifierInternal(); + } + const ExplicitSpecifier getExplicitSpecifier() const { + return getExplicitSpecifierInternal(); + } + + /// Return true if the declartion is already resolved to be explicit. + bool isExplicit() const { return getExplicitSpecifier().isExplicit(); } + /// Iterates through the member/base initializer list. using init_iterator = CXXCtorInitializer **; @@ -2585,11 +2722,6 @@ public: CtorInitializers = Initializers; } - /// Whether this function is explicit. - bool isExplicit() const { - return getCanonicalDecl()->isExplicitSpecified(); - } - /// Determine whether this constructor is a delegating constructor. bool isDelegatingConstructor() const { return (getNumCtorInitializers() == 1) && @@ -2713,12 +2845,11 @@ class CXXDestructorDecl : public CXXMethodDecl { Expr *OperatorDeleteThisArg = nullptr; CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - bool isInline, bool isImplicitlyDeclared) - : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo, - SC_None, isInline, /*isConstexpr=*/false, SourceLocation()) - { + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, bool isInline, + bool isImplicitlyDeclared) + : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo, + SC_None, isInline, CSK_unspecified, SourceLocation()) { setImplicit(isImplicitlyDeclared); } @@ -2768,34 +2899,39 @@ public: class CXXConversionDecl : public CXXMethodDecl { CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, - TypeSourceInfo *TInfo, bool isInline, - bool isExplicitSpecified, bool isConstexpr, - SourceLocation EndLocation) + TypeSourceInfo *TInfo, bool isInline, ExplicitSpecifier ES, + ConstexprSpecKind ConstexprKind, SourceLocation EndLocation) : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo, - SC_None, isInline, isConstexpr, EndLocation) { - setExplicitSpecified(isExplicitSpecified); - } - + SC_None, isInline, ConstexprKind, EndLocation), + ExplicitSpec(ES) {} void anchor() override; + ExplicitSpecifier ExplicitSpec; + + void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; } + public: friend class ASTDeclReader; friend class ASTDeclWriter; - static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - bool isInline, bool isExplicit, - bool isConstexpr, - SourceLocation EndLocation); + static CXXConversionDecl * + Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, + bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, + SourceLocation EndLocation); static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID); - /// Whether this function is explicit. - bool isExplicit() const { - return getCanonicalDecl()->isExplicitSpecified(); + ExplicitSpecifier getExplicitSpecifier() { + return getCanonicalDecl()->ExplicitSpec; } + const ExplicitSpecifier getExplicitSpecifier() const { + return getCanonicalDecl()->ExplicitSpec; + } + + /// Return true if the declartion is already resolved to be explicit. + bool isExplicit() const { return getExplicitSpecifier().isExplicit(); } + /// Returns the type that this conversion function is converting to. QualType getConversionType() const { return getType()->getAs()->getReturnType(); @@ -3793,6 +3929,8 @@ public: /// x[0], x[1], and x[2] respectively, where x is the implicit /// DecompositionDecl of type 'int (&)[3]'. class BindingDecl : public ValueDecl { + /// The declaration that this binding binds to part of. + LazyDeclPtr Decomp; /// 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 @@ -3816,6 +3954,10 @@ public: /// decomposition declaration, and when the initializer is type-dependent. Expr *getBinding() const { return Binding; } + /// Get the decomposition declaration that this binding represents a + /// decomposition of. + ValueDecl *getDecomposedDecl() const; + /// 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; @@ -3828,6 +3970,9 @@ public: this->Binding = Binding; } + /// Set the decomposed variable for this BindingDecl. + void setDecomposedDecl(ValueDecl *Decomposed) { Decomp = Decomposed; } + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::Binding; } }; @@ -3855,6 +4000,8 @@ class DecompositionDecl final NumBindings(Bindings.size()) { std::uninitialized_copy(Bindings.begin(), Bindings.end(), getTrailingObjects()); + for (auto *B : Bindings) + B->setDecomposedDecl(this); } void anchor() override; diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h index ccd82d2cf0d2..e6a4cd4381e4 100644 --- a/include/clang/AST/DeclContextInternals.h +++ b/include/clang/AST/DeclContextInternals.h @@ -1,9 +1,8 @@ //===- DeclContextInternals.h - DeclContext Representation ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -114,12 +113,11 @@ public: } DeclsTy &Vec = *getAsVector(); - DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D); + DeclsTy::iterator I = llvm::find(Vec, D); assert(I != Vec.end() && "list does not contain decl"); Vec.erase(I); - assert(std::find(Vec.begin(), Vec.end(), D) - == Vec.end() && "list still contains decl"); + assert(llvm::find(Vec, D) == Vec.end() && "list still contains decl"); } /// Remove any declarations which were imported from an external diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index b5808f23de6f..6f8306c6025e 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -1,9 +1,8 @@ //===- DeclFriend.h - Classes for C++ friend declarations -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h index 6d5aaadf529c..2be9dae9431e 100644 --- a/include/clang/AST/DeclGroup.h +++ b/include/clang/AST/DeclGroup.h @@ -1,9 +1,8 @@ //===- DeclGroup.h - Classes for representing groups of Decls ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h index 9627f440d406..41c8999736ea 100644 --- a/include/clang/AST/DeclLookups.h +++ b/include/clang/AST/DeclLookups.h @@ -1,9 +1,8 @@ //===- DeclLookups.h - Low-level interface to all names in a DC -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 5b57411f9785..8d85ac36d861 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -1,9 +1,8 @@ //===- DeclObjC.h - Classes for representing declarations -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h index 8540cc5b25b6..437feaba28fb 100644 --- a/include/clang/AST/DeclOpenMP.h +++ b/include/clang/AST/DeclOpenMP.h @@ -1,9 +1,8 @@ //===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -207,6 +206,102 @@ public: } }; +/// This represents '#pragma omp declare mapper ...' directive. Map clauses are +/// allowed to use with this directive. The following example declares a user +/// defined mapper for the type 'struct vec'. This example instructs the fields +/// 'len' and 'data' should be mapped when mapping instances of 'struct vec'. +/// +/// \code +/// #pragma omp declare mapper(mid: struct vec v) map(v.len, v.data[0:N]) +/// \endcode +class OMPDeclareMapperDecl final : public ValueDecl, public DeclContext { + friend class ASTDeclReader; + + /// Clauses associated with this mapper declaration + MutableArrayRef Clauses; + + /// Mapper variable, which is 'v' in the example above + Expr *MapperVarRef = nullptr; + + /// Name of the mapper variable + DeclarationName VarName; + + LazyDeclPtr PrevDeclInScope; + + virtual void anchor(); + + OMPDeclareMapperDecl(Kind DK, DeclContext *DC, SourceLocation L, + DeclarationName Name, QualType Ty, + DeclarationName VarName, + OMPDeclareMapperDecl *PrevDeclInScope) + : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), VarName(VarName), + PrevDeclInScope(PrevDeclInScope) {} + + void setPrevDeclInScope(OMPDeclareMapperDecl *Prev) { + PrevDeclInScope = Prev; + } + + /// Sets an array of clauses to this mapper declaration + void setClauses(ArrayRef CL); + +public: + /// Creates declare mapper node. + static OMPDeclareMapperDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, DeclarationName Name, + QualType T, DeclarationName VarName, + OMPDeclareMapperDecl *PrevDeclInScope); + /// Creates deserialized declare mapper node. + static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, unsigned ID, + unsigned N); + + /// Creates an array of clauses to this mapper declaration and intializes + /// them. + void CreateClauses(ASTContext &C, ArrayRef CL); + + using clauselist_iterator = MutableArrayRef::iterator; + using clauselist_const_iterator = ArrayRef::iterator; + using clauselist_range = llvm::iterator_range; + using clauselist_const_range = + llvm::iterator_range; + + unsigned clauselist_size() const { return Clauses.size(); } + bool clauselist_empty() const { return Clauses.empty(); } + + clauselist_range clauselists() { + return clauselist_range(clauselist_begin(), clauselist_end()); + } + clauselist_const_range clauselists() const { + return clauselist_const_range(clauselist_begin(), clauselist_end()); + } + clauselist_iterator clauselist_begin() { return Clauses.begin(); } + clauselist_iterator clauselist_end() { return Clauses.end(); } + clauselist_const_iterator clauselist_begin() const { return Clauses.begin(); } + clauselist_const_iterator clauselist_end() const { return Clauses.end(); } + + /// Get the variable declared in the mapper + Expr *getMapperVarRef() { return MapperVarRef; } + const Expr *getMapperVarRef() const { return MapperVarRef; } + /// Set the variable declared in the mapper + void setMapperVarRef(Expr *MapperVarRefE) { MapperVarRef = MapperVarRefE; } + + /// Get the name of the variable declared in the mapper + DeclarationName getVarName() { return VarName; } + + /// Get reference to previous declare mapper construct in the same + /// scope with the same name. + OMPDeclareMapperDecl *getPrevDeclInScope(); + const OMPDeclareMapperDecl *getPrevDeclInScope() const; + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == OMPDeclareMapper; } + static DeclContext *castToDeclContext(const OMPDeclareMapperDecl *D) { + return static_cast(const_cast(D)); + } + static OMPDeclareMapperDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast(const_cast(DC)); + } +}; + /// Pseudo declaration for capturing expressions. Also is used for capturing of /// non-static data members in non-static member functions. /// @@ -310,6 +405,119 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == OMPRequires; } }; + +/// This represents '#pragma omp allocate ...' directive. +/// For example, in the following, the default allocator is used for both 'a' +/// and 'A::b': +/// +/// \code +/// int a; +/// #pragma omp allocate(a) +/// struct A { +/// static int b; +/// #pragma omp allocate(b) +/// }; +/// \endcode +/// +class OMPAllocateDecl final + : public Decl, + private llvm::TrailingObjects { + friend class ASTDeclReader; + friend TrailingObjects; + + /// Number of variable within the allocate directive. + unsigned NumVars = 0; + /// Number of clauses associated with the allocate directive. + unsigned NumClauses = 0; + + size_t numTrailingObjects(OverloadToken) const { + return NumVars; + } + size_t numTrailingObjects(OverloadToken) const { + return NumClauses; + } + + virtual void anchor(); + + OMPAllocateDecl(Kind DK, DeclContext *DC, SourceLocation L) + : Decl(DK, DC, L) {} + + ArrayRef getVars() const { + return llvm::makeArrayRef(getTrailingObjects(), NumVars); + } + + MutableArrayRef getVars() { + return MutableArrayRef(getTrailingObjects(), NumVars); + } + + void setVars(ArrayRef VL); + + /// Returns an array of immutable clauses associated with this directive. + ArrayRef getClauses() const { + return llvm::makeArrayRef(getTrailingObjects(), NumClauses); + } + + /// Returns an array of clauses associated with this directive. + MutableArrayRef getClauses() { + return MutableArrayRef(getTrailingObjects(), + NumClauses); + } + + /// Sets an array of clauses to this requires declaration + void setClauses(ArrayRef CL); + +public: + static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, ArrayRef VL, + ArrayRef CL); + static OMPAllocateDecl *CreateDeserialized(ASTContext &C, unsigned ID, + unsigned NVars, unsigned NClauses); + + typedef MutableArrayRef::iterator varlist_iterator; + typedef ArrayRef::iterator varlist_const_iterator; + typedef llvm::iterator_range varlist_range; + typedef llvm::iterator_range varlist_const_range; + using clauselist_iterator = MutableArrayRef::iterator; + using clauselist_const_iterator = ArrayRef::iterator; + using clauselist_range = llvm::iterator_range; + using clauselist_const_range = llvm::iterator_range; + + + unsigned varlist_size() const { return NumVars; } + bool varlist_empty() const { return NumVars == 0; } + unsigned clauselist_size() const { return NumClauses; } + bool clauselist_empty() const { return NumClauses == 0; } + + varlist_range varlists() { + return varlist_range(varlist_begin(), varlist_end()); + } + varlist_const_range varlists() const { + return varlist_const_range(varlist_begin(), varlist_end()); + } + varlist_iterator varlist_begin() { return getVars().begin(); } + varlist_iterator varlist_end() { return getVars().end(); } + varlist_const_iterator varlist_begin() const { return getVars().begin(); } + varlist_const_iterator varlist_end() const { return getVars().end(); } + + clauselist_range clauselists() { + return clauselist_range(clauselist_begin(), clauselist_end()); + } + clauselist_const_range clauselists() const { + return clauselist_const_range(clauselist_begin(), clauselist_end()); + } + clauselist_iterator clauselist_begin() { return getClauses().begin(); } + clauselist_iterator clauselist_end() { return getClauses().end(); } + clauselist_const_iterator clauselist_begin() const { + return getClauses().begin(); + } + clauselist_const_iterator clauselist_end() const { + return getClauses().end(); + } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == OMPAllocate; } +}; + } // end namespace clang #endif diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index f6e3d8f300ba..235b31c1c312 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -1,9 +1,8 @@ //===- DeclTemplate.h - Classes for representing C++ templates --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -177,6 +176,11 @@ public: return SourceRange(TemplateLoc, RAngleLoc); } + void print(raw_ostream &Out, const ASTContext &Context, + bool OmitTemplateKW = false) const; + void print(raw_ostream &Out, const ASTContext &Context, + const PrintingPolicy &Policy, bool OmitTemplateKW = false) const; + public: // FIXME: workaround for MSVC 2013; remove when no longer needed using FixedSizeStorageOwner = TrailingObjects::FixedSizeStorageOwner; @@ -505,29 +509,13 @@ public: /// Provides information about a function template specialization, /// which is a FunctionDecl that has been explicitly specialization or /// instantiated from a function template. -class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode { - FunctionTemplateSpecializationInfo(FunctionDecl *FD, - FunctionTemplateDecl *Template, - TemplateSpecializationKind TSK, - const TemplateArgumentList *TemplateArgs, - const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, - SourceLocation POI) - : Function(FD), Template(Template, TSK - 1), - TemplateArguments(TemplateArgs), - TemplateArgumentsAsWritten(TemplateArgsAsWritten), - PointOfInstantiation(POI) {} - -public: - static FunctionTemplateSpecializationInfo * - Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, - TemplateSpecializationKind TSK, - const TemplateArgumentList *TemplateArgs, - const TemplateArgumentListInfo *TemplateArgsAsWritten, - SourceLocation POI); - - /// The function template specialization that this structure - /// describes. - FunctionDecl *Function; +class FunctionTemplateSpecializationInfo final + : public llvm::FoldingSetNode, + private llvm::TrailingObjects { + /// The function template specialization that this structure describes and a + /// flag indicating if the function is a member specialization. + llvm::PointerIntPair Function; /// The function template from which this function template /// specialization was generated. @@ -535,17 +523,50 @@ public: /// The two bits contain the top 4 values of TemplateSpecializationKind. llvm::PointerIntPair Template; +public: /// The template arguments used to produce the function template /// specialization from the function template. const TemplateArgumentList *TemplateArguments; /// The template arguments as written in the sources, if provided. + /// FIXME: Normally null; tail-allocate this. const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten; /// The point at which this function template specialization was /// first instantiated. SourceLocation PointOfInstantiation; +private: + FunctionTemplateSpecializationInfo( + FunctionDecl *FD, FunctionTemplateDecl *Template, + TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs, + const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, + SourceLocation POI, MemberSpecializationInfo *MSInfo) + : Function(FD, MSInfo ? 1 : 0), Template(Template, TSK - 1), + TemplateArguments(TemplateArgs), + TemplateArgumentsAsWritten(TemplateArgsAsWritten), + PointOfInstantiation(POI) { + if (MSInfo) + getTrailingObjects()[0] = MSInfo; + } + + size_t numTrailingObjects(OverloadToken) const { + return Function.getInt(); + } + +public: + friend TrailingObjects; + + static FunctionTemplateSpecializationInfo * + Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, + TemplateSpecializationKind TSK, + const TemplateArgumentList *TemplateArgs, + const TemplateArgumentListInfo *TemplateArgsAsWritten, + SourceLocation POI, MemberSpecializationInfo *MSInfo); + + /// Retrieve the declaration of the function template specialization. + FunctionDecl *getFunction() const { return Function.getPointer(); } + /// Retrieve the template from which this function was specialized. FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); } @@ -588,9 +609,44 @@ public: PointOfInstantiation = POI; } + /// Get the specialization info if this function template specialization is + /// also a member specialization: + /// + /// \code + /// template struct A { + /// template void f(); + /// template<> void f(); // ClassScopeFunctionSpecializationDecl + /// }; + /// \endcode + /// + /// Here, A::f is a function template specialization that is + /// an explicit specialization of A::f, but it's also a member + /// specialization (an implicit instantiation in this case) of A::f. + /// Further: + /// + /// \code + /// template<> template<> void A::f() {} + /// \endcode + /// + /// ... declares a function template specialization that is an explicit + /// specialization of A::f, and is also an explicit member + /// specialization of A::f. + /// + /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo + /// need not be the same as that returned by getTemplateSpecializationKind(), + /// and represents the relationship between the function and the class-scope + /// explicit specialization in the original templated class -- whereas our + /// TemplateSpecializationKind represents the relationship between the + /// function and the function template, and should always be + /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo. + MemberSpecializationInfo *getMemberSpecializationInfo() const { + return numTrailingObjects(OverloadToken()) + ? getTrailingObjects()[0] + : nullptr; + } + void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, TemplateArguments->asArray(), - Function->getASTContext()); + Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext()); } static void @@ -956,7 +1012,7 @@ SpecEntryTraits { using DeclType = FunctionDecl; static DeclType *getDecl(FunctionTemplateSpecializationInfo *I) { - return I->Function; + return I->getFunction(); } static ArrayRef @@ -1747,6 +1803,20 @@ public: return getSpecializationKind() == TSK_ExplicitSpecialization; } + /// Is this an explicit specialization at class scope (within the class that + /// owns the primary template)? For example: + /// + /// \code + /// template struct Outer { + /// template struct Inner; + /// template<> struct Inner; // class-scope explicit specialization + /// }; + /// \endcode + bool isClassScopeExplicitSpecialization() const { + return isExplicitSpecialization() && + isa(getLexicalDeclContext()); + } + /// True if this declaration is an explicit specialization, /// explicit instantiation declaration, or explicit instantiation /// definition. @@ -2395,8 +2465,6 @@ public: /// Declaration of a function specialization at template class scope. /// -/// This is a non-standard extension needed to support MSVC. -/// /// For example: /// \code /// template @@ -2409,17 +2477,18 @@ public: /// "template<> foo(int a)" will be saved in Specialization as a normal /// CXXMethodDecl. Then during an instantiation of class A, it will be /// transformed into an actual function specialization. +/// +/// FIXME: This is redundant; we could store the same information directly on +/// the CXXMethodDecl as a DependentFunctionTemplateSpecializationInfo. class ClassScopeFunctionSpecializationDecl : public Decl { CXXMethodDecl *Specialization; - bool HasExplicitTemplateArgs; - TemplateArgumentListInfo TemplateArgs; + const ASTTemplateArgumentListInfo *TemplateArgs; - ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc, - CXXMethodDecl *FD, bool Args, - TemplateArgumentListInfo TemplArgs) + ClassScopeFunctionSpecializationDecl( + DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD, + const ASTTemplateArgumentListInfo *TemplArgs) : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc), - Specialization(FD), HasExplicitTemplateArgs(Args), - TemplateArgs(std::move(TemplArgs)) {} + Specialization(FD), TemplateArgs(TemplArgs) {} ClassScopeFunctionSpecializationDecl(EmptyShell Empty) : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {} @@ -2431,17 +2500,20 @@ public: friend class ASTDeclWriter; CXXMethodDecl *getSpecialization() const { return Specialization; } - bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } - const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; } + bool hasExplicitTemplateArgs() const { return TemplateArgs; } + const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { + return TemplateArgs; + } - static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C, - DeclContext *DC, - SourceLocation Loc, - CXXMethodDecl *FD, - bool HasExplicitTemplateArgs, - TemplateArgumentListInfo TemplateArgs) { + static ClassScopeFunctionSpecializationDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD, + bool HasExplicitTemplateArgs, + const TemplateArgumentListInfo &TemplateArgs) { return new (C, DC) ClassScopeFunctionSpecializationDecl( - DC, Loc, FD, HasExplicitTemplateArgs, std::move(TemplateArgs)); + DC, Loc, FD, + HasExplicitTemplateArgs + ? ASTTemplateArgumentListInfo::Create(C, TemplateArgs) + : nullptr); } static ClassScopeFunctionSpecializationDecl * @@ -2582,6 +2654,11 @@ public: return getSpecializationKind() == TSK_ExplicitSpecialization; } + bool isClassScopeExplicitSpecialization() const { + return isExplicitSpecialization() && + isa(getLexicalDeclContext()); + } + /// True if this declaration is an explicit specialization, /// explicit instantiation declaration, or explicit instantiation /// definition. @@ -3013,6 +3090,42 @@ public: static bool classofKind(Kind K) { return K == VarTemplate; } }; +// \brief Declaration of a C++2a concept. +class ConceptDecl : public TemplateDecl, public Mergeable { +protected: + Expr *ConstraintExpr; + + ConceptDecl(DeclContext *DC, + SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, + Expr *ConstraintExpr) + : TemplateDecl(nullptr, Concept, DC, L, Name, Params), + ConstraintExpr(ConstraintExpr) {}; +public: + static ConceptDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, + Expr *ConstraintExpr); + static ConceptDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + Expr *getConstraintExpr() const { + return ConstraintExpr; + } + + SourceRange getSourceRange() const override LLVM_READONLY { + return SourceRange(getTemplateParameters()->getTemplateLoc(), + ConstraintExpr->getEndLoc()); + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == Concept; } + + friend class ASTReader; + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + inline NamedDecl *getAsNamedDecl(TemplateParameter P) { if (auto *PD = P.dyn_cast()) return PD; diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h index c6cbc9ff7faa..8690cdda4bb7 100644 --- a/include/clang/AST/DeclVisitor.h +++ b/include/clang/AST/DeclVisitor.h @@ -1,9 +1,8 @@ //===- DeclVisitor.h - Visitor for Decl subclasses --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 62afae23ec79..90449147637d 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -1,9 +1,8 @@ //===- DeclarationName.h - Representation of declaration names --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -862,9 +861,26 @@ struct DenseMapInfo { } }; -template <> -struct isPodLike { static const bool value = true; }; - } // namespace llvm +// The definition of AssumedTemplateStorage is factored out of TemplateName to +// resolve a cyclic dependency between it and DeclarationName (via Type). +namespace clang { + +/// A structure for storing the information associated with a name that has +/// been assumed to be a template name (despite finding no TemplateDecls). +class AssumedTemplateStorage : public UncommonTemplateNameStorage { + friend class ASTContext; + + AssumedTemplateStorage(DeclarationName Name) + : UncommonTemplateNameStorage(Assumed, 0), Name(Name) {} + DeclarationName Name; + +public: + /// Get the name of the template. + DeclarationName getDeclName() const { return Name; } +}; + +} // namespace clang + #endif // LLVM_CLANG_AST_DECLARATIONNAME_H diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h index c21ef7907b8a..0a98dec0c25e 100644 --- a/include/clang/AST/DependentDiagnostic.h +++ b/include/clang/AST/DependentDiagnostic.h @@ -1,9 +1,8 @@ //==- DependentDiagnostic.h - Dependently-generated diagnostics --*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h index f356584144e6..2f6c314b4111 100644 --- a/include/clang/AST/EvaluatedExprVisitor.h +++ b/include/clang/AST/EvaluatedExprVisitor.h @@ -1,9 +1,8 @@ //===--- EvaluatedExprVisitor.h - Evaluated expression visitor --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 3de73428829b..d44a815c8699 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1,9 +1,8 @@ //===--- Expr.h - Classes for representing expressions ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -23,11 +22,14 @@ #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/FixedPoint.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SyncScope.h" #include "clang/Basic/TypeTraits.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/AtomicOrdering.h" @@ -103,13 +105,20 @@ struct SubobjectAdjustment { /// This represents one expression. Note that Expr's are subclasses of Stmt. /// This allows an expression to be transparently used any place a Stmt is /// required. -class Expr : public Stmt { +class Expr : public ValueStmt { QualType TR; +public: + Expr() = delete; + Expr(const Expr&) = delete; + Expr(Expr &&) = delete; + Expr &operator=(const Expr&) = delete; + Expr &operator=(Expr&&) = delete; + protected: Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack) - : Stmt(SC) + : ValueStmt(SC) { ExprBits.TypeDependent = TD; ExprBits.ValueDependent = VD; @@ -122,7 +131,7 @@ protected: } /// Construct an empty expression. - explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { } + explicit Expr(StmtClass SC, EmptyShell) : ValueStmt(SC) { } public: QualType getType() const { return TR; } @@ -590,7 +599,8 @@ public: /// which we can fold and convert to a boolean condition using /// any crazy technique that we want to, even if the expression has /// side-effects. - bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const; + bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, + bool InConstantContext = false) const; enum SideEffectsKind { SE_NoSideEffects, ///< Strictly evaluate the expression. @@ -602,14 +612,21 @@ public: /// EvaluateAsInt - Return true if this is a constant which we can fold and /// convert to an integer, using any crazy technique that we want to. bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, - SideEffectsKind AllowSideEffects = SE_NoSideEffects) const; + SideEffectsKind AllowSideEffects = SE_NoSideEffects, + bool InConstantContext = false) const; /// EvaluateAsFloat - Return true if this is a constant which we can fold and /// convert to a floating point value, using any crazy technique that we /// want to. - bool - EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, - SideEffectsKind AllowSideEffects = SE_NoSideEffects) const; + bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, + SideEffectsKind AllowSideEffects = SE_NoSideEffects, + bool InConstantContext = false) const; + + /// EvaluateAsFloat - Return true if this is a constant which we can fold and + /// convert to a fixed point value. + bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, + SideEffectsKind AllowSideEffects = SE_NoSideEffects, + bool InConstantContext = false) const; /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be /// constant folded without side-effects, but discard the result. @@ -645,7 +662,8 @@ public: /// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an /// lvalue with link time known address, with no side-effects. - bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const; + bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, + bool InConstantContext = false) const; /// EvaluateAsInitializer - Evaluate an expression as if it were the /// initializer of the given declaration. Returns true if the initializer @@ -738,67 +756,110 @@ public: /// member expression. static QualType findBoundMemberType(const Expr *expr); - /// IgnoreImpCasts - Skip past any implicit casts which might - /// surround this expression. Only skips ImplicitCastExprs. + /// Skip past any implicit casts which might surround this expression until + /// reaching a fixed point. Skips: + /// * ImplicitCastExpr + /// * FullExpr Expr *IgnoreImpCasts() LLVM_READONLY; - - /// IgnoreImplicit - Skip past any implicit AST nodes which might - /// surround this expression. - Expr *IgnoreImplicit() LLVM_READONLY { - return cast(Stmt::IgnoreImplicit()); + const Expr *IgnoreImpCasts() const { + return const_cast(this)->IgnoreImpCasts(); } - const Expr *IgnoreImplicit() const LLVM_READONLY { - return const_cast(this)->IgnoreImplicit(); - } - - /// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return - /// its subexpression. If that subexpression is also a ParenExpr, - /// then this method recursively returns its subexpression, and so forth. - /// Otherwise, the method returns the current Expr. - Expr *IgnoreParens() LLVM_READONLY; - - /// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr - /// or CastExprs, returning their operand. - Expr *IgnoreParenCasts() LLVM_READONLY; - - /// Ignore casts. Strip off any CastExprs, returning their operand. + /// Skip past any casts which might surround this expression until reaching + /// a fixed point. Skips: + /// * CastExpr + /// * FullExpr + /// * MaterializeTemporaryExpr + /// * SubstNonTypeTemplateParmExpr Expr *IgnoreCasts() LLVM_READONLY; + const Expr *IgnoreCasts() const { + return const_cast(this)->IgnoreCasts(); + } - /// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off - /// any ParenExpr or ImplicitCastExprs, returning their operand. + /// Skip past any implicit AST nodes which might surround this expression + /// until reaching a fixed point. Skips: + /// * What IgnoreImpCasts() skips + /// * MaterializeTemporaryExpr + /// * CXXBindTemporaryExpr + Expr *IgnoreImplicit() LLVM_READONLY; + const Expr *IgnoreImplicit() const { + return const_cast(this)->IgnoreImplicit(); + } + + /// Skip past any parentheses which might surround this expression until + /// reaching a fixed point. Skips: + /// * ParenExpr + /// * UnaryOperator if `UO_Extension` + /// * GenericSelectionExpr if `!isResultDependent()` + /// * ChooseExpr if `!isConditionDependent()` + /// * ConstantExpr + Expr *IgnoreParens() LLVM_READONLY; + const Expr *IgnoreParens() const { + return const_cast(this)->IgnoreParens(); + } + + /// Skip past any parentheses and implicit casts which might surround this + /// expression until reaching a fixed point. + /// FIXME: IgnoreParenImpCasts really ought to be equivalent to + /// IgnoreParens() + IgnoreImpCasts() until reaching a fixed point. However + /// this is currently not the case. Instead IgnoreParenImpCasts() skips: + /// * What IgnoreParens() skips + /// * What IgnoreImpCasts() skips + /// * MaterializeTemporaryExpr + /// * SubstNonTypeTemplateParmExpr Expr *IgnoreParenImpCasts() LLVM_READONLY; + const Expr *IgnoreParenImpCasts() const { + return const_cast(this)->IgnoreParenImpCasts(); + } - /// IgnoreConversionOperator - Ignore conversion operator. If this Expr is a - /// call to a conversion operator, return the argument. + /// Skip past any parentheses and casts which might surround this expression + /// until reaching a fixed point. Skips: + /// * What IgnoreParens() skips + /// * What IgnoreCasts() skips + Expr *IgnoreParenCasts() LLVM_READONLY; + const Expr *IgnoreParenCasts() const { + return const_cast(this)->IgnoreParenCasts(); + } + + /// Skip conversion operators. If this Expr is a call to a conversion + /// operator, return the argument. Expr *IgnoreConversionOperator() LLVM_READONLY; - - const Expr *IgnoreConversionOperator() const LLVM_READONLY { - return const_cast(this)->IgnoreConversionOperator(); + const Expr *IgnoreConversionOperator() const { + return const_cast(this)->IgnoreConversionOperator(); } - const Expr *IgnoreParenImpCasts() const LLVM_READONLY { - return const_cast(this)->IgnoreParenImpCasts(); - } - - /// Ignore parentheses and lvalue casts. Strip off any ParenExpr and - /// CastExprs that represent lvalue casts, returning their operand. + /// Skip past any parentheses and lvalue casts which might surround this + /// expression until reaching a fixed point. Skips: + /// * What IgnoreParens() skips + /// * What IgnoreCasts() skips, except that only lvalue-to-rvalue + /// casts are skipped + /// FIXME: This is intended purely as a temporary workaround for code + /// that hasn't yet been rewritten to do the right thing about those + /// casts, and may disappear along with the last internal use. Expr *IgnoreParenLValueCasts() LLVM_READONLY; - - const Expr *IgnoreParenLValueCasts() const LLVM_READONLY { - return const_cast(this)->IgnoreParenLValueCasts(); + const Expr *IgnoreParenLValueCasts() const { + return const_cast(this)->IgnoreParenLValueCasts(); } - /// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the - /// value (including ptr->int casts of the same size). Strip off any - /// ParenExpr or CastExprs, returning their operand. - Expr *IgnoreParenNoopCasts(ASTContext &Ctx) LLVM_READONLY; + /// Skip past any parenthese and casts which do not change the value + /// (including ptr->int casts of the same size) until reaching a fixed point. + /// Skips: + /// * What IgnoreParens() skips + /// * CastExpr which do not change the value + /// * SubstNonTypeTemplateParmExpr + Expr *IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY; + const Expr *IgnoreParenNoopCasts(const ASTContext &Ctx) const { + return const_cast(this)->IgnoreParenNoopCasts(Ctx); + } - /// Ignore parentheses and derived-to-base casts. + /// Skip past any parentheses and derived-to-base casts until reaching a + /// fixed point. Skips: + /// * What IgnoreParens() skips + /// * CastExpr which represent a derived-to-base cast (CK_DerivedToBase, + /// CK_UncheckedDerivedToBase and CK_NoOp) Expr *ignoreParenBaseCasts() LLVM_READONLY; - - const Expr *ignoreParenBaseCasts() const LLVM_READONLY { - return const_cast(this)->ignoreParenBaseCasts(); + const Expr *ignoreParenBaseCasts() const { + return const_cast(this)->ignoreParenBaseCasts(); } /// Determine whether this expression is a default function argument. @@ -817,24 +878,6 @@ public: /// Whether this expression is an implicit reference to 'this' in C++. bool isImplicitCXXThis() const; - const Expr *IgnoreImpCasts() const LLVM_READONLY { - return const_cast(this)->IgnoreImpCasts(); - } - const Expr *IgnoreParens() const LLVM_READONLY { - return const_cast(this)->IgnoreParens(); - } - const Expr *IgnoreParenCasts() const LLVM_READONLY { - return const_cast(this)->IgnoreParenCasts(); - } - /// Strip off casts, but keep parentheses. - const Expr *IgnoreCasts() const LLVM_READONLY { - return const_cast(this)->IgnoreCasts(); - } - - const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY { - return const_cast(this)->IgnoreParenNoopCasts(Ctx); - } - static bool hasAnyTypeDependentArguments(ArrayRef Exprs); /// For an expression of class type or pointer to class type, @@ -900,20 +943,63 @@ public: } }; -/// ConstantExpr - An expression that occurs in a constant context. -class ConstantExpr : public FullExpr { - ConstantExpr(Expr *subexpr) - : FullExpr(ConstantExprClass, subexpr) {} +/// ConstantExpr - An expression that occurs in a constant context and +/// optionally the result of evaluating the expression. +class ConstantExpr final + : public FullExpr, + private llvm::TrailingObjects { + static_assert(std::is_same::value, + "this class assumes llvm::APInt::WordType is uint64_t for " + "trail-allocated storage"); public: - static ConstantExpr *Create(const ASTContext &Context, Expr *E) { - assert(!isa(E)); - return new (Context) ConstantExpr(E); + /// Describes the kind of result that can be trail-allocated. + enum ResultStorageKind { RSK_None, RSK_Int64, RSK_APValue }; + +private: + size_t numTrailingObjects(OverloadToken) const { + return ConstantExprBits.ResultKind == ConstantExpr::RSK_APValue; + } + size_t numTrailingObjects(OverloadToken) const { + return ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64; } - /// Build an empty constant expression wrapper. - explicit ConstantExpr(EmptyShell Empty) - : FullExpr(ConstantExprClass, Empty) {} + void DefaultInit(ResultStorageKind StorageKind); + uint64_t &Int64Result() { + assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64 && + "invalid accessor"); + return *getTrailingObjects(); + } + const uint64_t &Int64Result() const { + return const_cast(this)->Int64Result(); + } + APValue &APValueResult() { + assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_APValue && + "invalid accessor"); + return *getTrailingObjects(); + } + const APValue &APValueResult() const { + return const_cast(this)->APValueResult(); + } + + ConstantExpr(Expr *subexpr, ResultStorageKind StorageKind); + ConstantExpr(ResultStorageKind StorageKind, EmptyShell Empty); + +public: + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; + static ConstantExpr *Create(const ASTContext &Context, Expr *E, + const APValue &Result); + static ConstantExpr *Create(const ASTContext &Context, Expr *E, + ResultStorageKind Storage = RSK_None); + static ConstantExpr *CreateEmpty(const ASTContext &Context, + ResultStorageKind StorageKind, + EmptyShell Empty); + + static ResultStorageKind getStorageKind(const APValue &Value); + static ResultStorageKind getStorageKind(const Type *T, + const ASTContext &Context); SourceLocation getBeginLoc() const LLVM_READONLY { return SubExpr->getBeginLoc(); @@ -926,6 +1012,20 @@ public: return T->getStmtClass() == ConstantExprClass; } + void SetResult(APValue Value, const ASTContext &Context) { + MoveIntoResult(Value, Context); + } + void MoveIntoResult(APValue &Value, const ASTContext &Context); + + APValue::ValueKind getResultAPValueKind() const { + return static_cast(ConstantExprBits.APValueKind); + } + ResultStorageKind getResultStorageKind() const { + return static_cast(ConstantExprBits.ResultKind); + } + APValue getAPValueResult() const; + const APValue &getResultAsAPValue() const { return APValueResult(); } + llvm::APSInt getResultAsAPSInt() const; // Iterators child_range children() { return child_range(&SubExpr, &SubExpr+1); } const_child_range children() const { @@ -1075,7 +1175,7 @@ class DeclRefExpr final bool RefersToEnlosingVariableOrCapture, const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, QualType T, - ExprValueKind VK); + ExprValueKind VK, NonOdrUseReason NOUR); /// Construct an empty declaration reference expression. explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {} @@ -1088,14 +1188,16 @@ public: DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T, ExprValueKind VK, SourceLocation L, - const DeclarationNameLoc &LocInfo = DeclarationNameLoc()); + const DeclarationNameLoc &LocInfo = DeclarationNameLoc(), + NonOdrUseReason NOUR = NOUR_None); static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD = nullptr, - const TemplateArgumentListInfo *TemplateArgs = nullptr); + const TemplateArgumentListInfo *TemplateArgs = nullptr, + NonOdrUseReason NOUR = NOUR_None); static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, @@ -1103,7 +1205,8 @@ public: bool RefersToEnclosingVariableOrCapture, const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK, NamedDecl *FoundD = nullptr, - const TemplateArgumentListInfo *TemplateArgs = nullptr); + const TemplateArgumentListInfo *TemplateArgs = nullptr, + NonOdrUseReason NOUR = NOUR_None); /// Construct an empty declaration reference expression. static DeclRefExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier, @@ -1234,6 +1337,11 @@ public: DeclRefExprBits.HadMultipleCandidates = V; } + /// Is this expression a non-odr-use reference, and if so, why? + NonOdrUseReason isNonOdrUse() const { + return static_cast(DeclRefExprBits.NonOdrUseReason); + } + /// Does this DeclRefExpr refer to an enclosing local or a captured /// variable? bool refersToEnclosingVariableOrCapture() const { @@ -1466,21 +1574,28 @@ public: /// Get a raw enumeration value representing the floating-point semantics of /// this literal (32-bit IEEE, x87, ...), suitable for serialisation. - APFloatSemantics getRawSemantics() const { - return static_cast(FloatingLiteralBits.Semantics); + llvm::APFloatBase::Semantics getRawSemantics() const { + return static_cast( + FloatingLiteralBits.Semantics); } /// Set the raw enumeration value representing the floating-point semantics of /// this literal (32-bit IEEE, x87, ...), suitable for serialisation. - void setRawSemantics(APFloatSemantics Sem) { + void setRawSemantics(llvm::APFloatBase::Semantics Sem) { FloatingLiteralBits.Semantics = Sem; } /// Return the APFloat semantics this literal uses. - const llvm::fltSemantics &getSemantics() const; + const llvm::fltSemantics &getSemantics() const { + return llvm::APFloatBase::EnumToSemantics( + static_cast( + FloatingLiteralBits.Semantics)); + } /// Set the APFloat semantics this literal uses. - void setSemantics(const llvm::fltSemantics &Sem); + void setSemantics(const llvm::fltSemantics &Sem) { + FloatingLiteralBits.Semantics = llvm::APFloatBase::SemanticsToEnum(Sem); + } bool isExact() const { return FloatingLiteralBits.IsExact; } void setExact(bool E) { FloatingLiteralBits.IsExact = E; } @@ -1837,6 +1952,11 @@ public: return child_range(getTrailingObjects(), getTrailingObjects() + hasFunctionName()); } + + const_child_range children() const { + return const_child_range(getTrailingObjects(), + getTrailingObjects() + hasFunctionName()); + } }; /// ParenExpr - This represents a parethesized expression, e.g. "(1)". This @@ -2577,6 +2697,11 @@ public: NumArgs = NewNumArgs; } + /// Bluntly set a new number of arguments without doing any checks whatsoever. + /// Only used during construction of a CallExpr in a few places in Sema. + /// FIXME: Find a way to remove it. + void setNumArgsUnsafe(unsigned NewNumArgs) { NumArgs = NewNumArgs; } + typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; typedef llvm::iterator_range arg_range; @@ -2685,6 +2810,7 @@ class MemberExpr final ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> { friend class ASTReader; + friend class ASTStmtReader; friend class ASTStmtWriter; friend TrailingObjects; @@ -2719,49 +2845,40 @@ class MemberExpr final return MemberExprBits.HasTemplateKWAndArgsInfo; } + MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc, + ValueDecl *MemberDecl, const DeclarationNameInfo &NameInfo, + QualType T, ExprValueKind VK, ExprObjectKind OK, + NonOdrUseReason NOUR); + MemberExpr(EmptyShell Empty) + : Expr(MemberExprClass, Empty), Base(), MemberDecl() {} + public: - MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc, - ValueDecl *memberdecl, const DeclarationNameInfo &NameInfo, - QualType ty, ExprValueKind VK, ExprObjectKind OK) - : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), - base->isValueDependent(), base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - Base(base), MemberDecl(memberdecl), MemberDNLoc(NameInfo.getInfo()), - MemberLoc(NameInfo.getLoc()) { - assert(memberdecl->getDeclName() == NameInfo.getName()); - MemberExprBits.IsArrow = isarrow; - MemberExprBits.HasQualifierOrFoundDecl = false; - MemberExprBits.HasTemplateKWAndArgsInfo = false; - MemberExprBits.HadMultipleCandidates = false; - MemberExprBits.OperatorLoc = operatorloc; - } - - // NOTE: this constructor should be used only when it is known that - // the member name can not provide additional syntactic info - // (i.e., source locations for C++ operator names or type source info - // for constructors, destructors and conversion operators). - MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc, - ValueDecl *memberdecl, SourceLocation l, QualType ty, - ExprValueKind VK, ExprObjectKind OK) - : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), - base->isValueDependent(), base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l) { - MemberExprBits.IsArrow = isarrow; - MemberExprBits.HasQualifierOrFoundDecl = false; - MemberExprBits.HasTemplateKWAndArgsInfo = false; - MemberExprBits.HadMultipleCandidates = false; - MemberExprBits.OperatorLoc = operatorloc; - } - - static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow, + static MemberExpr *Create(const ASTContext &C, Expr *Base, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, ValueDecl *memberdecl, - DeclAccessPair founddecl, + SourceLocation TemplateKWLoc, ValueDecl *MemberDecl, + DeclAccessPair FoundDecl, DeclarationNameInfo MemberNameInfo, - const TemplateArgumentListInfo *targs, QualType ty, - ExprValueKind VK, ExprObjectKind OK); + const TemplateArgumentListInfo *TemplateArgs, + QualType T, ExprValueKind VK, ExprObjectKind OK, + NonOdrUseReason NOUR); + + /// Create an implicit MemberExpr, with no location, qualifier, template + /// arguments, and so on. Suitable only for non-static member access. + static MemberExpr *CreateImplicit(const ASTContext &C, Expr *Base, + bool IsArrow, ValueDecl *MemberDecl, + QualType T, ExprValueKind VK, + ExprObjectKind OK) { + return Create(C, Base, IsArrow, SourceLocation(), NestedNameSpecifierLoc(), + SourceLocation(), MemberDecl, + DeclAccessPair::make(MemberDecl, MemberDecl->getAccess()), + DeclarationNameInfo(), nullptr, T, VK, OK, NOUR_None); + } + + static MemberExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier, + bool HasFoundDecl, + bool HasTemplateKWAndArgsInfo, + unsigned NumTemplateArgs); void setBase(Expr *E) { Base = E; } Expr *getBase() const { return cast(Base); } @@ -2909,6 +3026,12 @@ public: return LO.AppleKext || !hasQualifier(); } + /// Is this expression a non-odr-use reference, and if so, why? + /// This is only meaningful if the named member is a static member. + NonOdrUseReason isNonOdrUse() const { + return static_cast(MemberExprBits.NonOdrUseReason); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == MemberExprClass; } @@ -3072,6 +3195,13 @@ public: path_const_iterator path_begin() const { return path_buffer(); } path_const_iterator path_end() const { return path_buffer() + path_size(); } + llvm::iterator_range path() { + return llvm::make_range(path_begin(), path_end()); + } + llvm::iterator_range path() const { + return llvm::make_range(path_begin(), path_end()); + } + const FieldDecl *getTargetUnionField() const { assert(getCastKind() == CK_ToUnion); return getTargetFieldForToUnionCast(getType(), getSubExpr()->getType()); @@ -3159,18 +3289,6 @@ public: friend class CastExpr; }; -inline Expr *Expr::IgnoreImpCasts() { - Expr *e = this; - while (true) - if (ImplicitCastExpr *ice = dyn_cast(e)) - e = ice->getSubExpr(); - else if (FullExpr *fe = dyn_cast(e)) - e = fe->getSubExpr(); - else - break; - return e; -} - /// ExplicitCastExpr - An explicit cast written in the source /// code. /// @@ -3377,6 +3495,9 @@ public: static bool isComparisonOp(Opcode Opc) { return Opc >= BO_Cmp && Opc<=BO_NE; } bool isComparisonOp() const { return isComparisonOp(getOpcode()); } + static bool isCommaOp(Opcode Opc) { return Opc == BO_Comma; } + bool isCommaOp() const { return isCommaOp(getOpcode()); } + static Opcode negateComparisonOp(Opcode Opc) { switch (Opc) { default: @@ -4137,6 +4258,71 @@ public: } }; +/// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), +/// __builtin_FUNCTION(), or __builtin_FILE(). +class SourceLocExpr final : public Expr { + SourceLocation BuiltinLoc, RParenLoc; + DeclContext *ParentContext; + +public: + enum IdentKind { Function, File, Line, Column }; + + SourceLocExpr(const ASTContext &Ctx, IdentKind Type, SourceLocation BLoc, + SourceLocation RParenLoc, DeclContext *Context); + + /// Build an empty call expression. + explicit SourceLocExpr(EmptyShell Empty) : Expr(SourceLocExprClass, Empty) {} + + /// Return the result of evaluating this SourceLocExpr in the specified + /// (and possibly null) default argument or initialization context. + APValue EvaluateInContext(const ASTContext &Ctx, + const Expr *DefaultExpr) const; + + /// Return a string representing the name of the specific builtin function. + StringRef getBuiltinStr() const; + + IdentKind getIdentKind() const { + return static_cast(SourceLocExprBits.Kind); + } + + bool isStringType() const { + switch (getIdentKind()) { + case File: + case Function: + return true; + case Line: + case Column: + return false; + } + llvm_unreachable("unknown source location expression kind"); + } + bool isIntType() const LLVM_READONLY { return !isStringType(); } + + /// If the SourceLocExpr has been resolved return the subexpression + /// representing the resolved value. Otherwise return null. + const DeclContext *getParentContext() const { return ParentContext; } + DeclContext *getParentContext() { return ParentContext; } + + SourceLocation getLocation() const { return BuiltinLoc; } + SourceLocation getBeginLoc() const { return BuiltinLoc; } + SourceLocation getEndLoc() const { return RParenLoc; } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(child_iterator(), child_iterator()); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == SourceLocExprClass; + } + +private: + friend class ASTStmtReader; +}; + /// Describes an C or C++ initializer list. /// /// InitListExpr describes an initializer list, which can be used to @@ -5007,99 +5193,277 @@ public: /// which names a dependent type in its association list is result-dependent, /// which means that the choice of result expression is dependent. /// Result-dependent generic associations are both type- and value-dependent. -class GenericSelectionExpr : public Expr { - enum { CONTROLLING, END_EXPR }; - TypeSourceInfo **AssocTypes; - Stmt **SubExprs; - unsigned NumAssocs, ResultIndex; - SourceLocation GenericLoc, DefaultLoc, RParenLoc; +class GenericSelectionExpr final + : public Expr, + private llvm::TrailingObjects { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; -public: - GenericSelectionExpr(const ASTContext &Context, - SourceLocation GenericLoc, Expr *ControllingExpr, - ArrayRef AssocTypes, - ArrayRef AssocExprs, - SourceLocation DefaultLoc, SourceLocation RParenLoc, + /// The number of association expressions and the index of the result + /// expression in the case where the generic selection expression is not + /// result-dependent. The result index is equal to ResultDependentIndex + /// if and only if the generic selection expression is result-dependent. + unsigned NumAssocs, ResultIndex; + enum : unsigned { + ResultDependentIndex = std::numeric_limits::max(), + ControllingIndex = 0, + AssocExprStartIndex = 1 + }; + + /// The location of the "default" and of the right parenthesis. + SourceLocation DefaultLoc, RParenLoc; + + // GenericSelectionExpr is followed by several trailing objects. + // They are (in order): + // + // * A single Stmt * for the controlling expression. + // * An array of getNumAssocs() Stmt * for the association expressions. + // * An array of getNumAssocs() TypeSourceInfo *, one for each of the + // association expressions. + unsigned numTrailingObjects(OverloadToken) const { + // Add one to account for the controlling expression; the remainder + // are the associated expressions. + return 1 + getNumAssocs(); + } + + unsigned numTrailingObjects(OverloadToken) const { + return getNumAssocs(); + } + + template class AssociationIteratorTy; + /// Bundle together an association expression and its TypeSourceInfo. + /// The Const template parameter is for the const and non-const versions + /// of AssociationTy. + template class AssociationTy { + friend class GenericSelectionExpr; + template friend class AssociationIteratorTy; + using ExprPtrTy = + typename std::conditional::type; + using TSIPtrTy = typename std::conditional::type; + ExprPtrTy E; + TSIPtrTy TSI; + bool Selected; + AssociationTy(ExprPtrTy E, TSIPtrTy TSI, bool Selected) + : E(E), TSI(TSI), Selected(Selected) {} + + public: + ExprPtrTy getAssociationExpr() const { return E; } + TSIPtrTy getTypeSourceInfo() const { return TSI; } + QualType getType() const { return TSI ? TSI->getType() : QualType(); } + bool isSelected() const { return Selected; } + AssociationTy *operator->() { return this; } + const AssociationTy *operator->() const { return this; } + }; // class AssociationTy + + /// Iterator over const and non-const Association objects. The Association + /// objects are created on the fly when the iterator is dereferenced. + /// This abstract over how exactly the association expressions and the + /// corresponding TypeSourceInfo * are stored. + template + class AssociationIteratorTy + : public llvm::iterator_facade_base< + AssociationIteratorTy, std::input_iterator_tag, + AssociationTy, std::ptrdiff_t, AssociationTy, + AssociationTy> { + friend class GenericSelectionExpr; + // FIXME: This iterator could conceptually be a random access iterator, and + // it would be nice if we could strengthen the iterator category someday. + // However this iterator does not satisfy two requirements of forward + // iterators: + // a) reference = T& or reference = const T& + // b) If It1 and It2 are both dereferenceable, then It1 == It2 if and only + // if *It1 and *It2 are bound to the same objects. + // An alternative design approach was discussed during review; + // store an Association object inside the iterator, and return a reference + // to it when dereferenced. This idea was discarded beacuse of nasty + // lifetime issues: + // AssociationIterator It = ...; + // const Association &Assoc = *It++; // Oops, Assoc is dangling. + using BaseTy = typename AssociationIteratorTy::iterator_facade_base; + using StmtPtrPtrTy = + typename std::conditional::type; + using TSIPtrPtrTy = + typename std::conditional::type; + StmtPtrPtrTy E; // = nullptr; FIXME: Once support for gcc 4.8 is dropped. + TSIPtrPtrTy TSI; // Kept in sync with E. + unsigned Offset = 0, SelectedOffset = 0; + AssociationIteratorTy(StmtPtrPtrTy E, TSIPtrPtrTy TSI, unsigned Offset, + unsigned SelectedOffset) + : E(E), TSI(TSI), Offset(Offset), SelectedOffset(SelectedOffset) {} + + public: + AssociationIteratorTy() : E(nullptr), TSI(nullptr) {} + typename BaseTy::reference operator*() const { + return AssociationTy(cast(*E), *TSI, + Offset == SelectedOffset); + } + typename BaseTy::pointer operator->() const { return **this; } + using BaseTy::operator++; + AssociationIteratorTy &operator++() { + ++E; + ++TSI; + ++Offset; + return *this; + } + bool operator==(AssociationIteratorTy Other) const { return E == Other.E; } + }; // class AssociationIterator + + /// Build a non-result-dependent generic selection expression. + GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc, + Expr *ControllingExpr, + ArrayRef AssocTypes, + ArrayRef AssocExprs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, unsigned ResultIndex); - /// This constructor is used in the result-dependent case. - GenericSelectionExpr(const ASTContext &Context, - SourceLocation GenericLoc, Expr *ControllingExpr, - ArrayRef AssocTypes, - ArrayRef AssocExprs, - SourceLocation DefaultLoc, SourceLocation RParenLoc, + /// Build a result-dependent generic selection expression. + GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc, + Expr *ControllingExpr, + ArrayRef AssocTypes, + ArrayRef AssocExprs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack); - explicit GenericSelectionExpr(EmptyShell Empty) - : Expr(GenericSelectionExprClass, Empty) { } + /// Build an empty generic selection expression for deserialization. + explicit GenericSelectionExpr(EmptyShell Empty, unsigned NumAssocs); +public: + /// Create a non-result-dependent generic selection expression. + static GenericSelectionExpr * + Create(const ASTContext &Context, SourceLocation GenericLoc, + Expr *ControllingExpr, ArrayRef AssocTypes, + ArrayRef AssocExprs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, + unsigned ResultIndex); + + /// Create a result-dependent generic selection expression. + static GenericSelectionExpr * + Create(const ASTContext &Context, SourceLocation GenericLoc, + Expr *ControllingExpr, ArrayRef AssocTypes, + ArrayRef AssocExprs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack); + + /// Create an empty generic selection expression for deserialization. + static GenericSelectionExpr *CreateEmpty(const ASTContext &Context, + unsigned NumAssocs); + + using Association = AssociationTy; + using ConstAssociation = AssociationTy; + using AssociationIterator = AssociationIteratorTy; + using ConstAssociationIterator = AssociationIteratorTy; + using association_range = llvm::iterator_range; + using const_association_range = + llvm::iterator_range; + + /// The number of association expressions. unsigned getNumAssocs() const { return NumAssocs; } - SourceLocation getGenericLoc() const { return GenericLoc; } - SourceLocation getDefaultLoc() const { return DefaultLoc; } - SourceLocation getRParenLoc() const { return RParenLoc; } - - const Expr *getAssocExpr(unsigned i) const { - return cast(SubExprs[END_EXPR+i]); - } - Expr *getAssocExpr(unsigned i) { return cast(SubExprs[END_EXPR+i]); } - ArrayRef getAssocExprs() const { - return NumAssocs - ? llvm::makeArrayRef( - &reinterpret_cast(SubExprs)[END_EXPR], NumAssocs) - : None; - } - const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const { - return AssocTypes[i]; - } - TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; } - ArrayRef getAssocTypeSourceInfos() const { - return NumAssocs ? llvm::makeArrayRef(&AssocTypes[0], NumAssocs) : None; - } - - QualType getAssocType(unsigned i) const { - if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i)) - return TS->getType(); - else - return QualType(); - } - - const Expr *getControllingExpr() const { - return cast(SubExprs[CONTROLLING]); - } - Expr *getControllingExpr() { return cast(SubExprs[CONTROLLING]); } - - /// Whether this generic selection is result-dependent. - bool isResultDependent() const { return ResultIndex == -1U; } - /// The zero-based index of the result expression's generic association in /// the generic selection's association list. Defined only if the /// generic selection is not result-dependent. unsigned getResultIndex() const { - assert(!isResultDependent() && "Generic selection is result-dependent"); + assert(!isResultDependent() && + "Generic selection is result-dependent but getResultIndex called!"); return ResultIndex; } - /// The generic selection's result expression. Defined only if the - /// generic selection is not result-dependent. - const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); } - Expr *getResultExpr() { return getAssocExpr(getResultIndex()); } + /// Whether this generic selection is result-dependent. + bool isResultDependent() const { return ResultIndex == ResultDependentIndex; } - SourceLocation getBeginLoc() const LLVM_READONLY { return GenericLoc; } - SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } + /// Return the controlling expression of this generic selection expression. + Expr *getControllingExpr() { + return cast(getTrailingObjects()[ControllingIndex]); + } + const Expr *getControllingExpr() const { + return cast(getTrailingObjects()[ControllingIndex]); + } + + /// Return the result expression of this controlling expression. Defined if + /// and only if the generic selection expression is not result-dependent. + Expr *getResultExpr() { + return cast( + getTrailingObjects()[AssocExprStartIndex + getResultIndex()]); + } + const Expr *getResultExpr() const { + return cast( + getTrailingObjects()[AssocExprStartIndex + getResultIndex()]); + } + + ArrayRef getAssocExprs() const { + return {reinterpret_cast(getTrailingObjects() + + AssocExprStartIndex), + NumAssocs}; + } + ArrayRef getAssocTypeSourceInfos() const { + return {getTrailingObjects(), NumAssocs}; + } + + /// Return the Ith association expression with its TypeSourceInfo, + /// bundled together in GenericSelectionExpr::(Const)Association. + Association getAssociation(unsigned I) { + assert(I < getNumAssocs() && + "Out-of-range index in GenericSelectionExpr::getAssociation!"); + return Association( + cast(getTrailingObjects()[AssocExprStartIndex + I]), + getTrailingObjects()[I], + !isResultDependent() && (getResultIndex() == I)); + } + ConstAssociation getAssociation(unsigned I) const { + assert(I < getNumAssocs() && + "Out-of-range index in GenericSelectionExpr::getAssociation!"); + return ConstAssociation( + cast(getTrailingObjects()[AssocExprStartIndex + I]), + getTrailingObjects()[I], + !isResultDependent() && (getResultIndex() == I)); + } + + association_range associations() { + AssociationIterator Begin(getTrailingObjects() + + AssocExprStartIndex, + getTrailingObjects(), + /*Offset=*/0, ResultIndex); + AssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs, + /*Offset=*/NumAssocs, ResultIndex); + return llvm::make_range(Begin, End); + } + + const_association_range associations() const { + ConstAssociationIterator Begin(getTrailingObjects() + + AssocExprStartIndex, + getTrailingObjects(), + /*Offset=*/0, ResultIndex); + ConstAssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs, + /*Offset=*/NumAssocs, ResultIndex); + return llvm::make_range(Begin, End); + } + + SourceLocation getGenericLoc() const { + return GenericSelectionExprBits.GenericLoc; + } + SourceLocation getDefaultLoc() const { return DefaultLoc; } + SourceLocation getRParenLoc() const { return RParenLoc; } + SourceLocation getBeginLoc() const { return getGenericLoc(); } + SourceLocation getEndLoc() const { return getRParenLoc(); } static bool classof(const Stmt *T) { return T->getStmtClass() == GenericSelectionExprClass; } child_range children() { - return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs); + return child_range(getTrailingObjects(), + getTrailingObjects() + + numTrailingObjects(OverloadToken())); } const_child_range children() const { - return const_child_range(SubExprs, SubExprs + END_EXPR + NumAssocs); + return const_child_range(getTrailingObjects(), + getTrailingObjects() + + numTrailingObjects(OverloadToken())); } - friend class ASTStmtReader; }; //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 6ef837a2fc40..28ed6cdfde14 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1,9 +1,8 @@ //===- ExprCXX.h - Classes for representing expressions ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -217,6 +216,8 @@ public: /// Represents a call to a CUDA kernel function. class CUDAKernelCallExpr final : public CallExpr { + friend class ASTStmtReader; + enum { CONFIG, END_PREARG }; // CUDAKernelCallExpr has some trailing objects belonging @@ -242,20 +243,6 @@ public: } CallExpr *getConfig() { return cast_or_null(getPreArg(CONFIG)); } - /// Sets the kernel configuration expression. - /// - /// Note that this method cannot be called if config has already been set to a - /// non-null value. - void setConfig(CallExpr *E) { - assert(!getConfig() && - "Cannot call setConfig if config is not null"); - setPreArg(CONFIG, E); - setInstantiationDependent(isInstantiationDependent() || - E->isInstantiationDependent()); - setContainsUnexpandedParameterPack(containsUnexpandedParameterPack() || - E->containsUnexpandedParameterPack()); - } - static bool classof(const Stmt *T) { return T->getStmtClass() == CUDAKernelCallExprClass; } @@ -588,6 +575,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// The null pointer literal (C++11 [lex.nullptr]) @@ -617,6 +608,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// Implicit construction of a std::initializer_list object from an @@ -659,6 +654,10 @@ public: } child_range children() { return child_range(&SubExpr, &SubExpr + 1); } + + const_child_range children() const { + return const_child_range(&SubExpr, &SubExpr + 1); + } }; /// A C++ \c typeid expression (C++ [expr.typeid]), which gets @@ -749,6 +748,15 @@ public: auto **begin = reinterpret_cast(&Operand); return child_range(begin, begin + 1); } + + const_child_range children() const { + if (isTypeOperand()) + return const_child_range(const_child_iterator(), const_child_iterator()); + + auto **begin = + reinterpret_cast(&const_cast(this)->Operand); + return const_child_range(begin, begin + 1); + } }; /// A member reference to an MSPropertyDecl. @@ -803,6 +811,11 @@ public: return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == MSPropertyRefExprClass; } @@ -878,6 +891,10 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS); } + + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS); + } }; /// A Microsoft C++ @c __uuidof expression, which gets @@ -959,6 +976,14 @@ public: auto **begin = reinterpret_cast(&Operand); return child_range(begin, begin + 1); } + + const_child_range children() const { + if (isTypeOperand()) + return const_child_range(const_child_iterator(), const_child_iterator()); + auto **begin = + reinterpret_cast(&const_cast(this)->Operand); + return const_child_range(begin, begin + 1); + } }; /// Represents the \c this expression in C++. @@ -1005,6 +1030,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// A C++ throw-expression (C++ [except.throw]). @@ -1063,6 +1092,10 @@ public: child_range children() { return child_range(&Operand, Operand ? &Operand + 1 : &Operand); } + + const_child_range children() const { + return const_child_range(&Operand, Operand ? &Operand + 1 : &Operand); + } }; /// A default argument (C++ [dcl.fct.default]). @@ -1076,7 +1109,11 @@ class CXXDefaultArgExpr final : public Expr { /// The parameter whose default is being used. ParmVarDecl *Param; - CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param) + /// The context where the default argument expression was used. + DeclContext *UsedContext; + + CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param, + DeclContext *UsedContext) : Expr(SC, Param->hasUnparsedDefaultArg() ? Param->getType().getNonReferenceType() @@ -1084,7 +1121,7 @@ class CXXDefaultArgExpr final : public Expr { Param->getDefaultArg()->getValueKind(), Param->getDefaultArg()->getObjectKind(), false, false, false, false), - Param(Param) { + Param(Param), UsedContext(UsedContext) { CXXDefaultArgExprBits.Loc = Loc; } @@ -1094,8 +1131,10 @@ public: // \p Param is the parameter whose default argument is used by this // expression. static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc, - ParmVarDecl *Param) { - return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param); + ParmVarDecl *Param, + DeclContext *UsedContext) { + return new (C) + CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, UsedContext); } // Retrieve the parameter that the argument was created from. @@ -1106,6 +1145,9 @@ public: const Expr *getExpr() const { return getParam()->getDefaultArg(); } Expr *getExpr() { return getParam()->getDefaultArg(); } + const DeclContext *getUsedContext() const { return UsedContext; } + DeclContext *getUsedContext() { return UsedContext; } + /// Retrieve the location where this default argument was actually used. SourceLocation getUsedLocation() const { return CXXDefaultArgExprBits.Loc; } @@ -1124,6 +1166,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// A use of a default initializer in a constructor or in aggregate @@ -1141,8 +1187,11 @@ class CXXDefaultInitExpr : public Expr { /// The field whose default is being used. FieldDecl *Field; + /// The context where the default initializer expression was used. + DeclContext *UsedContext; + CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc, - FieldDecl *Field, QualType Ty); + FieldDecl *Field, QualType Ty, DeclContext *UsedContext); CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {} @@ -1150,8 +1199,8 @@ public: /// \p Field is the non-static data member whose default initializer is used /// by this expression. static CXXDefaultInitExpr *Create(const ASTContext &Ctx, SourceLocation Loc, - FieldDecl *Field) { - return new (Ctx) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType()); + FieldDecl *Field, DeclContext *UsedContext) { + return new (Ctx) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType(), UsedContext); } /// Get the field whose initializer will be used. @@ -1168,6 +1217,13 @@ public: return Field->getInClassInitializer(); } + const DeclContext *getUsedContext() const { return UsedContext; } + DeclContext *getUsedContext() { return UsedContext; } + + /// Retrieve the location where this default initializer expression was + /// actually used. + SourceLocation getUsedLocation() const { return getBeginLoc(); } + SourceLocation getBeginLoc() const { return CXXDefaultInitExprBits.Loc; } SourceLocation getEndLoc() const { return CXXDefaultInitExprBits.Loc; } @@ -1179,6 +1235,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// Represents a C++ temporary. @@ -1256,6 +1316,10 @@ public: // Iterators child_range children() { return child_range(&SubExpr, &SubExpr + 1); } + + const_child_range children() const { + return const_child_range(&SubExpr, &SubExpr + 1); + } }; /// Represents a call to a C++ constructor. @@ -1439,6 +1503,11 @@ public: child_range children() { return child_range(getTrailingArgs(), getTrailingArgs() + getNumArgs()); } + + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } }; /// Represents a call to an inherited base class constructor from an @@ -1507,6 +1576,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// Represents an explicit C++ type conversion that uses "functional" @@ -1833,6 +1906,10 @@ public: /// parameter list associated with it, or else return null. TemplateParameterList *getTemplateParameterList() const; + /// Get the template parameters were explicitly specified (as opposed to being + /// invented by use of an auto parameter). + ArrayRef getExplicitTemplateParameters() const; + /// Whether this is a generic lambda. bool isGenericLambda() const { return getTemplateParameterList(); } @@ -1864,6 +1941,11 @@ public: // Includes initialization exprs plus body stmt return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1); } + + const_child_range children() const { + return const_child_range(getStoredStmts(), + getStoredStmts() + NumCaptures + 1); + } }; /// An expression "T()" which creates a value-initialized rvalue of type @@ -1907,6 +1989,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// Represents a new-expression for memory allocation and constructor @@ -1979,7 +2065,7 @@ private: CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew, FunctionDecl *OperatorDelete, bool ShouldPassAlignment, bool UsualArrayDeleteWantsSize, ArrayRef PlacementArgs, - SourceRange TypeIdParens, Expr *ArraySize, + SourceRange TypeIdParens, Optional ArraySize, InitializationStyle InitializationStyle, Expr *Initializer, QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, SourceRange DirectInitRange); @@ -1994,7 +2080,7 @@ public: Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew, FunctionDecl *OperatorDelete, bool ShouldPassAlignment, bool UsualArrayDeleteWantsSize, ArrayRef PlacementArgs, - SourceRange TypeIdParens, Expr *ArraySize, + SourceRange TypeIdParens, Optional ArraySize, InitializationStyle InitializationStyle, Expr *Initializer, QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, SourceRange DirectInitRange); @@ -2037,15 +2123,15 @@ public: bool isArray() const { return CXXNewExprBits.IsArray; } - Expr *getArraySize() { - return isArray() - ? cast(getTrailingObjects()[arraySizeOffset()]) - : nullptr; + Optional getArraySize() { + if (!isArray()) + return None; + return cast_or_null(getTrailingObjects()[arraySizeOffset()]); } - const Expr *getArraySize() const { - return isArray() - ? cast(getTrailingObjects()[arraySizeOffset()]) - : nullptr; + Optional getArraySize() const { + if (!isArray()) + return None; + return cast_or_null(getTrailingObjects()[arraySizeOffset()]); } unsigned getNumPlacementArgs() const { @@ -2163,6 +2249,10 @@ public: // Iterators child_range children() { return child_range(raw_arg_begin(), raw_arg_end()); } + + const_child_range children() const { + return const_child_range(const_cast(this)->children()); + } }; /// Represents a \c delete expression for memory deallocation and @@ -2229,6 +2319,10 @@ public: // Iterators child_range children() { return child_range(&Argument, &Argument + 1); } + + const_child_range children() const { + return const_child_range(&Argument, &Argument + 1); + } }; /// Stores the type being destroyed by a pseudo-destructor expression. @@ -2417,6 +2511,10 @@ public: // Iterators child_range children() { return child_range(&Base, &Base + 1); } + + const_child_range children() const { + return const_child_range(&Base, &Base + 1); + } }; /// A type trait used in the implementation of various C++11 and @@ -2501,6 +2599,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// An Embarcadero array type trait, as used in the implementation of @@ -2568,6 +2670,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// An expression trait intrinsic. @@ -2628,6 +2734,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// A reference to an overloaded function set, either an @@ -2920,6 +3030,10 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == UnresolvedLookupExprClass; } @@ -3074,6 +3188,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// Represents an expression -- generally a full-expression -- that @@ -3143,6 +3261,10 @@ public: // Iterators child_range children() { return child_range(&SubExpr, &SubExpr + 1); } + + const_child_range children() const { + return const_child_range(&SubExpr, &SubExpr + 1); + } }; /// Describes an explicit type conversion that uses functional @@ -3272,6 +3394,12 @@ public: auto **begin = reinterpret_cast(arg_begin()); return child_range(begin, begin + arg_size()); } + + const_child_range children() const { + auto **begin = reinterpret_cast( + const_cast(this)->arg_begin()); + return const_child_range(begin, begin + arg_size()); + } }; /// Represents a C++ member access expression where the actual @@ -3518,6 +3646,12 @@ public: return child_range(child_iterator(), child_iterator()); return child_range(&Base, &Base + 1); } + + const_child_range children() const { + if (isImplicitAccess()) + return const_child_range(const_child_iterator(), const_child_iterator()); + return const_child_range(&Base, &Base + 1); + } }; /// Represents a C++ member access expression for which lookup @@ -3681,6 +3815,12 @@ public: return child_range(child_iterator(), child_iterator()); return child_range(&Base, &Base + 1); } + + const_child_range children() const { + if (isImplicitAccess()) + return const_child_range(const_child_iterator(), const_child_iterator()); + return const_child_range(&Base, &Base + 1); + } }; DeclAccessPair *OverloadExpr::getTrailingResults() { @@ -3750,6 +3890,10 @@ public: // Iterators child_range children() { return child_range(&Operand, &Operand + 1); } + + const_child_range children() const { + return const_child_range(&Operand, &Operand + 1); + } }; /// Represents a C++11 pack expansion that produces a sequence of @@ -3830,6 +3974,10 @@ public: child_range children() { return child_range(&Pattern, &Pattern + 1); } + + const_child_range children() const { + return const_child_range(&Pattern, &Pattern + 1); + } }; /// Represents an expression that computes the length of a parameter @@ -3951,6 +4099,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// Represents a reference to a non-type template parameter @@ -3997,6 +4149,10 @@ public: // Iterators child_range children() { return child_range(&Replacement, &Replacement + 1); } + + const_child_range children() const { + return const_child_range(&Replacement, &Replacement + 1); + } }; /// Represents a reference to a non-type template parameter pack that @@ -4059,10 +4215,14 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; -/// Represents a reference to a function parameter pack that has been -/// substituted but not yet expanded. +/// Represents a reference to a function parameter pack or init-capture pack +/// that has been substituted but not yet expanded. /// /// When a pack expansion contains multiple parameter packs at different levels, /// this node is used to represent a function parameter pack at an outer level @@ -4077,13 +4237,13 @@ public: /// \endcode class FunctionParmPackExpr final : public Expr, - private llvm::TrailingObjects { + private llvm::TrailingObjects { friend class ASTReader; friend class ASTStmtReader; friend TrailingObjects; /// The function parameter pack which was referenced. - ParmVarDecl *ParamPack; + VarDecl *ParamPack; /// The location of the function parameter pack reference. SourceLocation NameLoc; @@ -4091,35 +4251,35 @@ class FunctionParmPackExpr final /// The number of expansions of this pack. unsigned NumParameters; - FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack, + FunctionParmPackExpr(QualType T, VarDecl *ParamPack, SourceLocation NameLoc, unsigned NumParams, - ParmVarDecl *const *Params); + VarDecl *const *Params); public: static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T, - ParmVarDecl *ParamPack, + VarDecl *ParamPack, SourceLocation NameLoc, - ArrayRef Params); + ArrayRef Params); static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context, unsigned NumParams); /// Get the parameter pack which this expression refers to. - ParmVarDecl *getParameterPack() const { return ParamPack; } + VarDecl *getParameterPack() const { return ParamPack; } /// Get the location of the parameter pack. SourceLocation getParameterPackLocation() const { return NameLoc; } /// Iterators over the parameters which the parameter pack expanded /// into. - using iterator = ParmVarDecl * const *; - iterator begin() const { return getTrailingObjects(); } + using iterator = VarDecl * const *; + iterator begin() const { return getTrailingObjects(); } iterator end() const { return begin() + NumParameters; } /// Get the number of parameters in this parameter pack. unsigned getNumExpansions() const { return NumParameters; } /// Get an expansion of the parameter pack by index. - ParmVarDecl *getExpansion(unsigned I) const { return begin()[I]; } + VarDecl *getExpansion(unsigned I) const { return begin()[I]; } SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; } SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; } @@ -4131,6 +4291,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// Represents a prvalue temporary that is written into memory so that @@ -4253,6 +4417,15 @@ public: auto ES = State.get(); return child_range(&ES->Temporary, &ES->Temporary + 1); } + + const_child_range children() const { + if (State.is()) + return const_child_range(State.getAddrOfPtr1(), + State.getAddrOfPtr1() + 1); + + auto ES = State.get(); + return const_child_range(&ES->Temporary, &ES->Temporary + 1); + } }; /// Represents a folding of a pack over an operator. @@ -4270,18 +4443,21 @@ class CXXFoldExpr : public Expr { SourceLocation LParenLoc; SourceLocation EllipsisLoc; SourceLocation RParenLoc; + // When 0, the number of expansions is not known. Otherwise, this is one more + // than the number of expansions. + unsigned NumExpansions; Stmt *SubExprs[2]; BinaryOperatorKind Opcode; public: CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS, - SourceLocation RParenLoc) + SourceLocation RParenLoc, Optional NumExpansions) : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary, /*Dependent*/ true, true, true, /*ContainsUnexpandedParameterPack*/ false), LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc), - Opcode(Opcode) { + NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) { SubExprs[0] = LHS; SubExprs[1] = RHS; } @@ -4308,6 +4484,12 @@ public: SourceLocation getEllipsisLoc() const { return EllipsisLoc; } BinaryOperatorKind getOperator() const { return Opcode; } + Optional getNumExpansions() const { + if (NumExpansions) + return NumExpansions - 1; + return None; + } + SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; } SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } @@ -4318,6 +4500,10 @@ public: // Iterators child_range children() { return child_range(SubExprs, SubExprs + 2); } + + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + 2); + } }; /// Represents an expression that might suspend coroutine execution; @@ -4409,6 +4595,10 @@ public: return child_range(SubExprs, SubExprs + SubExpr::Count); } + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + SubExpr::Count); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == CoawaitExprClass || T->getStmtClass() == CoyieldExprClass; @@ -4493,6 +4683,10 @@ public: child_range children() { return child_range(SubExprs, SubExprs + 2); } + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + 2); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == DependentCoawaitExprClass; } @@ -4522,6 +4716,35 @@ public: } }; +/// Represents a C++2a __builtin_bit_cast(T, v) expression. Used to implement +/// std::bit_cast. These can sometimes be evaluated as part of a constant +/// expression, but otherwise CodeGen to a simple memcpy in general. +class BuiltinBitCastExpr final + : public ExplicitCastExpr, + private llvm::TrailingObjects { + friend class ASTStmtReader; + friend class CastExpr; + friend class TrailingObjects; + + SourceLocation KWLoc; + SourceLocation RParenLoc; + +public: + BuiltinBitCastExpr(QualType T, ExprValueKind VK, CastKind CK, Expr *SrcExpr, + TypeSourceInfo *DstType, SourceLocation KWLoc, + SourceLocation RParenLoc) + : ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0, + DstType), + KWLoc(KWLoc), RParenLoc(RParenLoc) {} + + SourceLocation getBeginLoc() const LLVM_READONLY { return KWLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == BuiltinBitCastExprClass; + } +}; + } // namespace clang #endif // LLVM_CLANG_AST_EXPRCXX_H diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index c7b305f3304e..dbb2b2ff7099 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -1,9 +1,8 @@ //===- ExprObjC.h - Classes for representing ObjC expressions ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -73,6 +72,10 @@ public: // Iterators child_range children() { return child_range(&String, &String+1); } + const_child_range children() const { + return const_child_range(&String, &String + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCStringLiteralClass; } @@ -105,6 +108,10 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCBoolLiteralExprClass; } @@ -139,6 +146,12 @@ public: return BoxingMethod; } + // Indicates whether this boxed expression can be emitted as a compile-time + // constant. + bool isExpressibleAsConstantInitializer() const { + return !BoxingMethod && SubExpr; + } + SourceLocation getAtLoc() const { return Range.getBegin(); } SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } @@ -151,6 +164,10 @@ public: // Iterators child_range children() { return child_range(&SubExpr, &SubExpr+1); } + const_child_range children() const { + return const_child_range(&SubExpr, &SubExpr + 1); + } + using const_arg_iterator = ConstExprIterator; const_arg_iterator arg_begin() const { @@ -229,6 +246,11 @@ public: reinterpret_cast(getElements()) + NumElements); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCArrayLiteralClass; } @@ -256,12 +278,6 @@ struct ObjCDictionaryElement { } // namespace clang -namespace llvm { - -template <> struct isPodLike : std::true_type {}; - -} // namespace llvm - namespace clang { /// Internal struct for storing Key/value pair. @@ -375,6 +391,11 @@ public: NumElements * 2); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCDictionaryLiteralClass; } @@ -420,6 +441,10 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCEncodeExprClass; } @@ -458,6 +483,10 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCSelectorExprClass; } @@ -504,6 +533,10 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCProtocolExprClass; } @@ -567,6 +600,10 @@ public: // Iterators child_range children() { return child_range(&Base, &Base+1); } + const_child_range children() const { + return const_child_range(&Base, &Base + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIvarRefExprClass; } @@ -758,6 +795,11 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCPropertyRefExprClass; } @@ -867,6 +909,10 @@ public: return child_range(SubExprs, SubExprs+END_EXPR); } + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + END_EXPR); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCSubscriptRefExprClass; } @@ -1187,6 +1233,13 @@ public: /// sent to. ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; } + /// \return the return type of the message being sent. + /// This is not always the type of the message expression itself because + /// of references (the expression would not have a reference type). + /// It is also not always the declared return type of the method because + /// of `instancetype` (in that case it's an expression type). + QualType getCallReturnType(ASTContext &Ctx) const; + /// Source range of the receiver. SourceRange getReceiverRange() const; @@ -1402,6 +1455,8 @@ public: // Iterators child_range children(); + const_child_range children() const; + using arg_iterator = ExprIterator; using const_arg_iterator = ConstExprIterator; @@ -1488,6 +1543,10 @@ public: // Iterators child_range children() { return child_range(&Base, &Base+1); } + const_child_range children() const { + return const_child_range(&Base, &Base + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIsaExprClass; } @@ -1549,6 +1608,10 @@ public: child_range children() { return child_range(&Operand, &Operand+1); } + const_child_range children() const { + return const_child_range(&Operand, &Operand + 1); + } + // Source locations are determined by the subexpression. SourceLocation getBeginLoc() const LLVM_READONLY { return Operand->getBeginLoc(); @@ -1661,6 +1724,10 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAvailabilityCheckExprClass; } diff --git a/include/clang/AST/ExprOpenMP.h b/include/clang/AST/ExprOpenMP.h index d88eebf5e54f..5607d2d1dc58 100644 --- a/include/clang/AST/ExprOpenMP.h +++ b/include/clang/AST/ExprOpenMP.h @@ -1,9 +1,8 @@ //===--- ExprOpenMP.h - Classes for representing expressions ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -123,6 +122,10 @@ public: child_range children() { return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]); } + + const_child_range children() const { + return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]); + } }; } // end namespace clang diff --git a/include/clang/AST/ExternalASTMerger.h b/include/clang/AST/ExternalASTMerger.h index 7b01fa8cbced..d89189da04f0 100644 --- a/include/clang/AST/ExternalASTMerger.h +++ b/include/clang/AST/ExternalASTMerger.h @@ -1,9 +1,8 @@ //===--- ExternalASTMerger.h - Merging External AST Interface ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index 525d4c78b362..304633668bd1 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -1,9 +1,8 @@ //===- ExternalASTSource.h - Abstract External AST Interface ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/FormatString.h b/include/clang/AST/FormatString.h index 4a89c797b648..643fb822f7f4 100644 --- a/include/clang/AST/FormatString.h +++ b/include/clang/AST/FormatString.h @@ -1,9 +1,8 @@ //= FormatString.h - Analysis of printf/fprintf format strings --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -68,6 +67,7 @@ public: None, AsChar, // 'hh' AsShort, // 'h' + AsShortLong, // 'hl' (OpenCL float/int vector element) AsLong, // 'l' AsLongLong, // 'll' AsQuad, // 'q' (BSD, deprecated, for 64-bit integer types) @@ -437,7 +437,8 @@ public: bool usesPositionalArg() const { return UsesPositionalArg; } - bool hasValidLengthModifier(const TargetInfo &Target) const; + bool hasValidLengthModifier(const TargetInfo &Target, + const LangOptions &LO) const; bool hasStandardLengthModifier() const; diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h index a3c0cab3799f..86fd0f6aa907 100644 --- a/include/clang/AST/GlobalDecl.h +++ b/include/clang/AST/GlobalDecl.h @@ -1,9 +1,8 @@ //===- GlobalDecl.h - Global declaration holder -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -28,6 +27,12 @@ namespace clang { +enum class DynamicInitKind : unsigned { + NoStub = 0, + Initializer, + AtExit, +}; + /// GlobalDecl - represents a global declaration. This can either be a /// CXXConstructorDecl and the constructor type (Base, Complete). /// a CXXDestructorDecl and the destructor type (Base, Complete) or @@ -56,6 +61,8 @@ public: GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); } GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {} GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {} + GlobalDecl(const VarDecl *D, DynamicInitKind StubKind) + : Value(D, unsigned(StubKind)) {} GlobalDecl getCanonicalDecl() const { GlobalDecl CanonGD; @@ -78,6 +85,13 @@ public: return static_cast(Value.getInt()); } + DynamicInitKind getDynamicInitKind() const { + assert(isa(getDecl()) && + cast(getDecl())->hasGlobalStorage() && + "Decl is not a global variable!"); + return static_cast(Value.getInt()); + } + unsigned getMultiVersionIndex() const { assert(isa(getDecl()) && !isa(getDecl()) && @@ -105,6 +119,20 @@ public: return Result; } + GlobalDecl getWithCtorType(CXXCtorType Type) { + assert(isa(getDecl())); + GlobalDecl Result(*this); + Result.Value.setInt(Type); + return Result; + } + + GlobalDecl getWithDtorType(CXXDtorType Type) { + assert(isa(getDecl())); + GlobalDecl Result(*this); + Result.Value.setInt(Type); + return Result; + } + GlobalDecl getWithMultiVersionIndex(unsigned Index) { assert(isa(getDecl()) && !isa(getDecl()) && @@ -140,13 +168,6 @@ namespace llvm { } }; - // GlobalDecl isn't *technically* a POD type. However, its copy constructor, - // copy assignment operator, and destructor are all trivial. - template <> - struct isPodLike { - static const bool value = true; - }; - } // namespace llvm #endif // LLVM_CLANG_AST_GLOBALDECL_H diff --git a/include/clang/AST/JSONNodeDumper.h b/include/clang/AST/JSONNodeDumper.h new file mode 100644 index 000000000000..238e43aad78b --- /dev/null +++ b/include/clang/AST/JSONNodeDumper.h @@ -0,0 +1,425 @@ +//===--- JSONNodeDumper.h - Printing of AST nodes to JSON -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements AST dumping of components of individual AST nodes to +// a JSON. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_JSONNODEDUMPER_H +#define LLVM_CLANG_AST_JSONNODEDUMPER_H + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTNodeTraverser.h" +#include "clang/AST/ASTDumperUtils.h" +#include "clang/AST/AttrVisitor.h" +#include "clang/AST/CommentCommandTraits.h" +#include "clang/AST/CommentVisitor.h" +#include "clang/AST/ExprCXX.h" +#include "llvm/Support/JSON.h" + +namespace clang { + +class NodeStreamer { + bool FirstChild = true; + bool TopLevel = true; + llvm::SmallVector, 32> Pending; + +protected: + llvm::json::OStream JOS; + +public: + /// Add a child of the current node. Calls DoAddChild without arguments + template void AddChild(Fn DoAddChild) { + return AddChild("", DoAddChild); + } + + /// Add a child of the current node with an optional label. + /// Calls DoAddChild without arguments. + template void AddChild(StringRef Label, Fn DoAddChild) { + // If we're at the top level, there's nothing interesting to do; just + // run the dumper. + if (TopLevel) { + TopLevel = false; + JOS.objectBegin(); + + DoAddChild(); + + while (!Pending.empty()) { + Pending.back()(true); + Pending.pop_back(); + } + + JOS.objectEnd(); + TopLevel = true; + return; + } + + // We need to capture an owning-string in the lambda because the lambda + // is invoked in a deferred manner. + std::string LabelStr = !Label.empty() ? Label : "inner"; + bool WasFirstChild = FirstChild; + auto DumpWithIndent = [=](bool IsLastChild) { + if (WasFirstChild) { + JOS.attributeBegin(LabelStr); + JOS.arrayBegin(); + } + + FirstChild = true; + unsigned Depth = Pending.size(); + JOS.objectBegin(); + + DoAddChild(); + + // If any children are left, they're the last at their nesting level. + // Dump those ones out now. + while (Depth < Pending.size()) { + Pending.back()(true); + this->Pending.pop_back(); + } + + JOS.objectEnd(); + + if (IsLastChild) { + JOS.arrayEnd(); + JOS.attributeEnd(); + } + }; + + if (FirstChild) { + Pending.push_back(std::move(DumpWithIndent)); + } else { + Pending.back()(false); + Pending.back() = std::move(DumpWithIndent); + } + FirstChild = false; + } + + NodeStreamer(raw_ostream &OS) : JOS(OS, 2) {} +}; + +// Dumps AST nodes in JSON format. There is no implied stability for the +// content or format of the dump between major releases of Clang, other than it +// being valid JSON output. Further, there is no requirement that the +// information dumped is a complete representation of the AST, only that the +// information presented is correct. +class JSONNodeDumper + : public ConstAttrVisitor, + public comments::ConstCommentVisitor, + public ConstTemplateArgumentVisitor, + public ConstStmtVisitor, + public TypeVisitor, + public ConstDeclVisitor, + public NodeStreamer { + friend class JSONDumper; + + const SourceManager &SM; + ASTContext& Ctx; + PrintingPolicy PrintPolicy; + const comments::CommandTraits *Traits; + StringRef LastLocFilename; + unsigned LastLocLine, LastLocPresumedLine; + + using InnerAttrVisitor = ConstAttrVisitor; + using InnerCommentVisitor = + comments::ConstCommentVisitor; + using InnerTemplateArgVisitor = ConstTemplateArgumentVisitor; + using InnerStmtVisitor = ConstStmtVisitor; + using InnerTypeVisitor = TypeVisitor; + using InnerDeclVisitor = ConstDeclVisitor; + + void attributeOnlyIfTrue(StringRef Key, bool Value) { + if (Value) + JOS.attribute(Key, Value); + } + + // Writes the attributes of a SourceLocation object without. + void writeBareSourceLocation(SourceLocation Loc, bool IsSpelling); + + // Writes the attributes of a SourceLocation to JSON based on its presumed + // spelling location. If the given location represents a macro invocation, + // this outputs two sub-objects: one for the spelling and one for the + // expansion location. + void writeSourceLocation(SourceLocation Loc); + void writeSourceRange(SourceRange R); + std::string createPointerRepresentation(const void *Ptr); + llvm::json::Object createQualType(QualType QT, bool Desugar = true); + llvm::json::Object createBareDeclRef(const Decl *D); + void writeBareDeclRef(const Decl *D); + llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD); + llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier &BS); + std::string createAccessSpecifier(AccessSpecifier AS); + llvm::json::Array createCastPath(const CastExpr *C); + + void writePreviousDeclImpl(...) {} + + template void writePreviousDeclImpl(const Mergeable *D) { + const T *First = D->getFirstDecl(); + if (First != D) + JOS.attribute("firstRedecl", createPointerRepresentation(First)); + } + + template void writePreviousDeclImpl(const Redeclarable *D) { + const T *Prev = D->getPreviousDecl(); + if (Prev) + JOS.attribute("previousDecl", createPointerRepresentation(Prev)); + } + void addPreviousDeclaration(const Decl *D); + + StringRef getCommentCommandName(unsigned CommandID) const; + +public: + JSONNodeDumper(raw_ostream &OS, const SourceManager &SrcMgr, ASTContext &Ctx, + const PrintingPolicy &PrintPolicy, + const comments::CommandTraits *Traits) + : NodeStreamer(OS), SM(SrcMgr), Ctx(Ctx), PrintPolicy(PrintPolicy), + Traits(Traits), LastLocLine(0), LastLocPresumedLine(0) {} + + void Visit(const Attr *A); + void Visit(const Stmt *Node); + void Visit(const Type *T); + void Visit(QualType T); + void Visit(const Decl *D); + + void Visit(const comments::Comment *C, const comments::FullComment *FC); + void Visit(const TemplateArgument &TA, SourceRange R = {}, + const Decl *From = nullptr, StringRef Label = {}); + void Visit(const CXXCtorInitializer *Init); + void Visit(const OMPClause *C); + void Visit(const BlockDecl::Capture &C); + void Visit(const GenericSelectionExpr::ConstAssociation &A); + + void VisitTypedefType(const TypedefType *TT); + void VisitFunctionType(const FunctionType *T); + void VisitFunctionProtoType(const FunctionProtoType *T); + void VisitRValueReferenceType(const ReferenceType *RT); + void VisitArrayType(const ArrayType *AT); + void VisitConstantArrayType(const ConstantArrayType *CAT); + void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *VT); + void VisitVectorType(const VectorType *VT); + void VisitUnresolvedUsingType(const UnresolvedUsingType *UUT); + void VisitUnaryTransformType(const UnaryTransformType *UTT); + void VisitTagType(const TagType *TT); + void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT); + void VisitAutoType(const AutoType *AT); + void VisitTemplateSpecializationType(const TemplateSpecializationType *TST); + void VisitInjectedClassNameType(const InjectedClassNameType *ICNT); + void VisitObjCInterfaceType(const ObjCInterfaceType *OIT); + void VisitPackExpansionType(const PackExpansionType *PET); + void VisitElaboratedType(const ElaboratedType *ET); + void VisitMacroQualifiedType(const MacroQualifiedType *MQT); + void VisitMemberPointerType(const MemberPointerType *MPT); + + void VisitNamedDecl(const NamedDecl *ND); + void VisitTypedefDecl(const TypedefDecl *TD); + void VisitTypeAliasDecl(const TypeAliasDecl *TAD); + void VisitNamespaceDecl(const NamespaceDecl *ND); + void VisitUsingDirectiveDecl(const UsingDirectiveDecl *UDD); + void VisitNamespaceAliasDecl(const NamespaceAliasDecl *NAD); + void VisitUsingDecl(const UsingDecl *UD); + void VisitUsingShadowDecl(const UsingShadowDecl *USD); + void VisitVarDecl(const VarDecl *VD); + void VisitFieldDecl(const FieldDecl *FD); + void VisitFunctionDecl(const FunctionDecl *FD); + void VisitEnumDecl(const EnumDecl *ED); + void VisitEnumConstantDecl(const EnumConstantDecl *ECD); + void VisitRecordDecl(const RecordDecl *RD); + void VisitCXXRecordDecl(const CXXRecordDecl *RD); + void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D); + void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); + void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); + void VisitLinkageSpecDecl(const LinkageSpecDecl *LSD); + void VisitAccessSpecDecl(const AccessSpecDecl *ASD); + void VisitFriendDecl(const FriendDecl *FD); + + void VisitObjCIvarDecl(const ObjCIvarDecl *D); + void VisitObjCMethodDecl(const ObjCMethodDecl *D); + void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D); + void VisitObjCCategoryDecl(const ObjCCategoryDecl *D); + void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D); + void VisitObjCProtocolDecl(const ObjCProtocolDecl *D); + void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D); + void VisitObjCImplementationDecl(const ObjCImplementationDecl *D); + void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D); + void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); + void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); + void VisitBlockDecl(const BlockDecl *D); + + void VisitDeclRefExpr(const DeclRefExpr *DRE); + void VisitPredefinedExpr(const PredefinedExpr *PE); + void VisitUnaryOperator(const UnaryOperator *UO); + void VisitBinaryOperator(const BinaryOperator *BO); + void VisitCompoundAssignOperator(const CompoundAssignOperator *CAO); + void VisitMemberExpr(const MemberExpr *ME); + void VisitCXXNewExpr(const CXXNewExpr *NE); + void VisitCXXDeleteExpr(const CXXDeleteExpr *DE); + void VisitCXXThisExpr(const CXXThisExpr *TE); + void VisitCastExpr(const CastExpr *CE); + void VisitImplicitCastExpr(const ImplicitCastExpr *ICE); + void VisitCallExpr(const CallExpr *CE); + void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *TTE); + void VisitSizeOfPackExpr(const SizeOfPackExpr *SOPE); + void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *ULE); + void VisitAddrLabelExpr(const AddrLabelExpr *ALE); + void VisitCXXTypeidExpr(const CXXTypeidExpr *CTE); + void VisitConstantExpr(const ConstantExpr *CE); + void VisitInitListExpr(const InitListExpr *ILE); + void VisitGenericSelectionExpr(const GenericSelectionExpr *GSE); + void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *UCE); + void VisitCXXConstructExpr(const CXXConstructExpr *CE); + void VisitExprWithCleanups(const ExprWithCleanups *EWC); + void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE); + void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *MTE); + void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *ME); + + void VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE); + void VisitObjCMessageExpr(const ObjCMessageExpr *OME); + void VisitObjCBoxedExpr(const ObjCBoxedExpr *OBE); + void VisitObjCSelectorExpr(const ObjCSelectorExpr *OSE); + void VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE); + void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE); + void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *OSRE); + void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE); + void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *OBLE); + + void VisitIntegerLiteral(const IntegerLiteral *IL); + void VisitCharacterLiteral(const CharacterLiteral *CL); + void VisitFixedPointLiteral(const FixedPointLiteral *FPL); + void VisitFloatingLiteral(const FloatingLiteral *FL); + void VisitStringLiteral(const StringLiteral *SL); + void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *BLE); + + void VisitIfStmt(const IfStmt *IS); + void VisitSwitchStmt(const SwitchStmt *SS); + void VisitCaseStmt(const CaseStmt *CS); + void VisitLabelStmt(const LabelStmt *LS); + void VisitGotoStmt(const GotoStmt *GS); + void VisitWhileStmt(const WhileStmt *WS); + void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS); + + void VisitNullTemplateArgument(const TemplateArgument &TA); + void VisitTypeTemplateArgument(const TemplateArgument &TA); + void VisitDeclarationTemplateArgument(const TemplateArgument &TA); + void VisitNullPtrTemplateArgument(const TemplateArgument &TA); + void VisitIntegralTemplateArgument(const TemplateArgument &TA); + void VisitTemplateTemplateArgument(const TemplateArgument &TA); + void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA); + void VisitExpressionTemplateArgument(const TemplateArgument &TA); + void VisitPackTemplateArgument(const TemplateArgument &TA); + + void visitTextComment(const comments::TextComment *C, + const comments::FullComment *); + void visitInlineCommandComment(const comments::InlineCommandComment *C, + const comments::FullComment *); + void visitHTMLStartTagComment(const comments::HTMLStartTagComment *C, + const comments::FullComment *); + void visitHTMLEndTagComment(const comments::HTMLEndTagComment *C, + const comments::FullComment *); + void visitBlockCommandComment(const comments::BlockCommandComment *C, + const comments::FullComment *); + void visitParamCommandComment(const comments::ParamCommandComment *C, + const comments::FullComment *FC); + void visitTParamCommandComment(const comments::TParamCommandComment *C, + const comments::FullComment *FC); + void visitVerbatimBlockComment(const comments::VerbatimBlockComment *C, + const comments::FullComment *); + void + visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C, + const comments::FullComment *); + void visitVerbatimLineComment(const comments::VerbatimLineComment *C, + const comments::FullComment *); +}; + +class JSONDumper : public ASTNodeTraverser { + JSONNodeDumper NodeDumper; + + template + void writeTemplateDeclSpecialization(const SpecializationDecl *SD, + bool DumpExplicitInst, + bool DumpRefOnly) { + bool DumpedAny = false; + for (const auto *RedeclWithBadType : SD->redecls()) { + // FIXME: The redecls() range sometimes has elements of a less-specific + // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives + // us TagDecls, and should give CXXRecordDecls). + const auto *Redecl = dyn_cast(RedeclWithBadType); + if (!Redecl) { + // Found the injected-class-name for a class template. This will be + // dumped as part of its surrounding class so we don't need to dump it + // here. + assert(isa(RedeclWithBadType) && + "expected an injected-class-name"); + continue; + } + + switch (Redecl->getTemplateSpecializationKind()) { + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + if (!DumpExplicitInst) + break; + LLVM_FALLTHROUGH; + case TSK_Undeclared: + case TSK_ImplicitInstantiation: + if (DumpRefOnly) + NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(Redecl); }); + else + Visit(Redecl); + DumpedAny = true; + break; + case TSK_ExplicitSpecialization: + break; + } + } + + // Ensure we dump at least one decl for each specialization. + if (!DumpedAny) + NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(SD); }); + } + + template + void writeTemplateDecl(const TemplateDecl *TD, bool DumpExplicitInst) { + // FIXME: it would be nice to dump template parameters and specializations + // to their own named arrays rather than shoving them into the "inner" + // array. However, template declarations are currently being handled at the + // wrong "level" of the traversal hierarchy and so it is difficult to + // achieve without losing information elsewhere. + + dumpTemplateParameters(TD->getTemplateParameters()); + + Visit(TD->getTemplatedDecl()); + + for (const auto *Child : TD->specializations()) + writeTemplateDeclSpecialization(Child, DumpExplicitInst, + !TD->isCanonicalDecl()); + } + +public: + JSONDumper(raw_ostream &OS, const SourceManager &SrcMgr, ASTContext &Ctx, + const PrintingPolicy &PrintPolicy, + const comments::CommandTraits *Traits) + : NodeDumper(OS, SrcMgr, Ctx, PrintPolicy, Traits) {} + + JSONNodeDumper &doGetNodeDelegate() { return NodeDumper; } + + void VisitFunctionTemplateDecl(const FunctionTemplateDecl *FTD) { + writeTemplateDecl(FTD, true); + } + void VisitClassTemplateDecl(const ClassTemplateDecl *CTD) { + writeTemplateDecl(CTD, false); + } + void VisitVarTemplateDecl(const VarTemplateDecl *VTD) { + writeTemplateDecl(VTD, false); + } +}; + +} // namespace clang + +#endif // LLVM_CLANG_AST_JSONNODEDUMPER_H diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h index f246bc423bfb..8e2806545dd6 100644 --- a/include/clang/AST/LambdaCapture.h +++ b/include/clang/AST/LambdaCapture.h @@ -1,9 +1,8 @@ //===--- LambdaCapture.h - Types for C++ Lambda Captures --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h b/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h index 47dac4362c8e..e42f0449f6db 100644 --- a/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h +++ b/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h @@ -1,9 +1,8 @@ //===--- LexicallyOrderedRecursiveASTVisitor.h - ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/LocInfoType.h b/include/clang/AST/LocInfoType.h index 802d9134ebde..1073174bcf91 100644 --- a/include/clang/AST/LocInfoType.h +++ b/include/clang/AST/LocInfoType.h @@ -1,9 +1,8 @@ //===--- LocInfoType.h - Parsed Type with Location Information---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h index 309ed5a1a5d2..b1fbe936136a 100644 --- a/include/clang/AST/Mangle.h +++ b/include/clang/AST/Mangle.h @@ -1,9 +1,8 @@ //===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -244,6 +243,19 @@ public: static MicrosoftMangleContext *create(ASTContext &Context, DiagnosticsEngine &Diags); }; + +class ASTNameGenerator { +public: + explicit ASTNameGenerator(ASTContext &Ctx); + ~ASTNameGenerator(); + bool writeName(const Decl *D, raw_ostream &OS); + std::string getName(const Decl *D); + std::vector getAllManglings(const Decl *D); + +private: + class Implementation; + std::unique_ptr Impl; +}; } #endif diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h index ff2148e3516d..f1ca6a05dbaf 100644 --- a/include/clang/AST/MangleNumberingContext.h +++ b/include/clang/AST/MangleNumberingContext.h @@ -1,9 +1,8 @@ //=== MangleNumberingContext.h - Context for mangling numbers ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h index f9340c64f3eb..21f0c5458d81 100644 --- a/include/clang/AST/NSAPI.h +++ b/include/clang/AST/NSAPI.h @@ -1,9 +1,8 @@ //===--- NSAPI.h - NSFoundation APIs ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h index 8befe9ae4258..c6fae6f465ff 100644 --- a/include/clang/AST/NestedNameSpecifier.h +++ b/include/clang/AST/NestedNameSpecifier.h @@ -1,9 +1,8 @@ //===- NestedNameSpecifier.h - C++ nested name specifiers -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/NonTrivialTypeVisitor.h b/include/clang/AST/NonTrivialTypeVisitor.h index bab373dbb298..aafcedb9d10b 100644 --- a/include/clang/AST/NonTrivialTypeVisitor.h +++ b/include/clang/AST/NonTrivialTypeVisitor.h @@ -1,9 +1,8 @@ //===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types *- C++ --*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ODRHash.h b/include/clang/AST/ODRHash.h index feaa83844a1a..cd4a6f37f5db 100644 --- a/include/clang/AST/ODRHash.h +++ b/include/clang/AST/ODRHash.h @@ -1,9 +1,8 @@ //===-- ODRHash.h - Hashing to diagnose ODR failures ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/AST/OSLog.h b/include/clang/AST/OSLog.h index 2b21855e7a6e..c24e79ce6da0 100644 --- a/include/clang/AST/OSLog.h +++ b/include/clang/AST/OSLog.h @@ -1,9 +1,8 @@ //= 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h index bdcdf74b2630..eadcc62a3457 100644 --- a/include/clang/AST/OpenMPClause.h +++ b/include/clang/AST/OpenMPClause.h @@ -1,9 +1,8 @@ //===- OpenMPClause.h - Classes for OpenMP clauses --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -91,6 +90,15 @@ public: return const_child_range(Children.begin(), Children.end()); } + /// Get the iterator range for the expressions used in the clauses. Used + /// expressions include only the children that must be evaluated at the + /// runtime before entering the construct. + child_range used_children(); + const_child_range used_children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + static bool classof(const OMPClause *) { return true; } }; @@ -157,6 +165,20 @@ public: static const OMPClauseWithPostUpdate *get(const OMPClause *C); }; +/// This structure contains most locations needed for by an OMPVarListClause. +struct OMPVarListLocTy { + /// Starting location of the clause (the clause keyword). + SourceLocation StartLoc; + /// Location of '('. + SourceLocation LParenLoc; + /// Ending location of the clause. + SourceLocation EndLoc; + OMPVarListLocTy() = default; + OMPVarListLocTy(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : StartLoc(StartLoc), LParenLoc(LParenLoc), EndLoc(EndLoc) {} +}; + /// This represents clauses with the list of variables like 'private', /// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the /// '#pragma omp ...' directives. @@ -230,6 +252,166 @@ public: } }; +/// This represents 'allocator' clause in the '#pragma omp ...' +/// directive. +/// +/// \code +/// #pragma omp allocate(a) allocator(omp_default_mem_alloc) +/// \endcode +/// In this example directive '#pragma omp allocate' has simple 'allocator' +/// clause with the allocator 'omp_default_mem_alloc'. +class OMPAllocatorClause : public OMPClause { + friend class OMPClauseReader; + + /// Location of '('. + SourceLocation LParenLoc; + + /// Expression with the allocator. + Stmt *Allocator = nullptr; + + /// Set allocator. + void setAllocator(Expr *A) { Allocator = A; } + +public: + /// Build 'allocator' clause with the given allocator. + /// + /// \param A Allocator. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_allocator, StartLoc, EndLoc), LParenLoc(LParenLoc), + Allocator(A) {} + + /// Build an empty clause. + OMPAllocatorClause() + : OMPClause(OMPC_allocator, SourceLocation(), SourceLocation()) {} + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// Returns allocator. + Expr *getAllocator() const { return cast_or_null(Allocator); } + + child_range children() { return child_range(&Allocator, &Allocator + 1); } + + const_child_range children() const { + return const_child_range(&Allocator, &Allocator + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_allocator; + } +}; + +/// This represents clause 'allocate' in the '#pragma omp ...' directives. +/// +/// \code +/// #pragma omp parallel private(a) allocate(omp_default_mem_alloc :a) +/// \endcode +/// In this example directive '#pragma omp parallel' has clause 'private' +/// and clause 'allocate' for the variable 'a'. +class OMPAllocateClause final + : public OMPVarListClause, + private llvm::TrailingObjects { + friend class OMPClauseReader; + friend OMPVarListClause; + friend TrailingObjects; + + /// Allocator specified in the clause, or 'nullptr' if the default one is + /// used. + Expr *Allocator = nullptr; + /// Position of the ':' delimiter in the clause; + SourceLocation ColonLoc; + + /// Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param Allocator Allocator expression. + /// \param ColonLoc Location of ':' delimiter. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc, + Expr *Allocator, SourceLocation ColonLoc, + SourceLocation EndLoc, unsigned N) + : OMPVarListClause(OMPC_allocate, StartLoc, LParenLoc, + EndLoc, N), + Allocator(Allocator), ColonLoc(ColonLoc) {} + + /// Build an empty clause. + /// + /// \param N Number of variables. + explicit OMPAllocateClause(unsigned N) + : OMPVarListClause(OMPC_allocate, SourceLocation(), + SourceLocation(), SourceLocation(), + N) {} + + /// Sets location of ':' symbol in clause. + void setColonLoc(SourceLocation CL) { ColonLoc = CL; } + + void setAllocator(Expr *A) { Allocator = A; } + +public: + /// Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param Allocator Allocator expression. + /// \param ColonLoc Location of ':' delimiter. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the variables. + static OMPAllocateClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, Expr *Allocator, + SourceLocation ColonLoc, + SourceLocation EndLoc, ArrayRef VL); + + /// Returns the allocator expression or nullptr, if no allocator is specified. + Expr *getAllocator() const { return Allocator; } + + /// Returns the location of the ':' delimiter. + SourceLocation getColonLoc() const { return ColonLoc; } + + /// Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + static OMPAllocateClause *CreateEmpty(const ASTContext &C, unsigned N); + + child_range children() { + return child_range(reinterpret_cast(varlist_begin()), + reinterpret_cast(varlist_end())); + } + + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_allocate; + } +}; + /// This represents 'if' clause in the '#pragma omp ...' directive. /// /// \code @@ -315,6 +497,16 @@ public: child_range children() { return child_range(&Condition, &Condition + 1); } + const_child_range children() const { + return const_child_range(&Condition, &Condition + 1); + } + + child_range used_children(); + const_child_range used_children() const { + auto Children = const_cast(this)->used_children(); + return const_child_range(Children.begin(), Children.end()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_if; } @@ -366,6 +558,17 @@ public: child_range children() { return child_range(&Condition, &Condition + 1); } + const_child_range children() const { + return const_child_range(&Condition, &Condition + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_final; } @@ -427,6 +630,17 @@ public: child_range children() { return child_range(&NumThreads, &NumThreads + 1); } + const_child_range children() const { + return const_child_range(&NumThreads, &NumThreads + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_num_threads; } @@ -482,6 +696,17 @@ public: child_range children() { return child_range(&Safelen, &Safelen + 1); } + const_child_range children() const { + return const_child_range(&Safelen, &Safelen + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_safelen; } @@ -536,6 +761,17 @@ public: child_range children() { return child_range(&Simdlen, &Simdlen + 1); } + const_child_range children() const { + return const_child_range(&Simdlen, &Simdlen + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_simdlen; } @@ -591,6 +827,17 @@ public: child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); } + const_child_range children() const { + return const_child_range(&NumForLoops, &NumForLoops + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_collapse; } @@ -659,6 +906,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_default; } @@ -729,6 +987,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_proc_bind; } @@ -760,6 +1029,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_unified_address; } @@ -791,6 +1071,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_unified_shared_memory; } @@ -822,6 +1113,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_reverse_offload; } @@ -854,6 +1156,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_dynamic_allocators; } @@ -933,6 +1246,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_atomic_default_mem_order; } @@ -1114,6 +1438,18 @@ public: reinterpret_cast(&ChunkSize) + 1); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_schedule; } @@ -1199,6 +1535,17 @@ public: child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); } + const_child_range children() const { + return const_child_range(&NumForLoops, &NumForLoops + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_ordered; } @@ -1227,6 +1574,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_nowait; } @@ -1255,6 +1613,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_untied; } @@ -1284,6 +1653,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_mergeable; } @@ -1311,6 +1691,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_read; } @@ -1339,6 +1730,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_write; } @@ -1368,6 +1770,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_update; } @@ -1397,6 +1810,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_capture; } @@ -1426,6 +1850,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_seq_cst; } @@ -1519,6 +1954,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_private; } @@ -1646,6 +2093,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_firstprivate; } @@ -1845,6 +2304,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_lastprivate; } @@ -1905,6 +2376,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_shared; } @@ -2127,6 +2610,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_reduction; } @@ -2347,6 +2842,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_task_reduction; } @@ -2590,6 +3097,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_in_reduction; } @@ -2829,6 +3348,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_linear; } @@ -2916,6 +3447,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_aligned; } @@ -3080,6 +3623,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_copyin; } @@ -3231,6 +3786,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_copyprivate; } @@ -3296,6 +3863,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_flush; } @@ -3415,6 +3994,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_depend; } @@ -3478,6 +4069,17 @@ public: child_range children() { return child_range(&Device, &Device + 1); } + const_child_range children() const { + return const_child_range(&Device, &Device + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_device; } @@ -3506,6 +4108,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_threads; } @@ -3533,6 +4146,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_simd; } @@ -3596,6 +4220,24 @@ protected: getUniqueDeclarationsTotalNumber(ArrayRef Declarations); }; +/// This structure contains all sizes needed for by an +/// OMPMappableExprListClause. +struct OMPMappableExprListSizeTy { + /// Number of expressions listed. + unsigned NumVars; + /// Number of unique base declarations. + unsigned NumUniqueDeclarations; + /// Number of component lists. + unsigned NumComponentLists; + /// Total number of expression components. + unsigned NumComponents; + OMPMappableExprListSizeTy() = default; + OMPMappableExprListSizeTy(unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : NumVars(NumVars), NumUniqueDeclarations(NumUniqueDeclarations), + NumComponentLists(NumComponentLists), NumComponents(NumComponents) {} +}; + /// This represents clauses with a list of expressions that are mappable. /// Examples of these clauses are 'map' in /// '#pragma omp target [enter|exit] [data]...' directives, and 'to' and 'from @@ -3614,28 +4256,44 @@ class OMPMappableExprListClause : public OMPVarListClause, /// Total number of components in this clause. unsigned NumComponents; + /// C++ nested name specifier for the associated user-defined mapper. + NestedNameSpecifierLoc MapperQualifierLoc; + + /// The associated user-defined mapper identifier information. + DeclarationNameInfo MapperIdInfo; + protected: /// Build a clause for \a NumUniqueDeclarations declarations, \a /// NumComponentLists total component lists, and \a NumComponents total /// components. /// /// \param K Kind of the clause. - /// \param StartLoc Starting location of the clause (the clause keyword). - /// \param LParenLoc Location of '('. - /// \param EndLoc Ending location of the clause. - /// \param NumVars Number of expressions listed in the clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of component lists in this clause - one - /// list for each expression in the clause. - /// \param NumComponents Total number of expression components in the clause. - OMPMappableExprListClause(OpenMPClauseKind K, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, - unsigned NumVars, unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPVarListClause(K, StartLoc, LParenLoc, EndLoc, NumVars), - NumUniqueDeclarations(NumUniqueDeclarations), - NumComponentLists(NumComponentLists), NumComponents(NumComponents) {} + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + /// \param MapperQualifierLocPtr C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperIdInfoPtr The identifier of associated user-defined mapper. + OMPMappableExprListClause( + OpenMPClauseKind K, const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes, + NestedNameSpecifierLoc *MapperQualifierLocPtr = nullptr, + DeclarationNameInfo *MapperIdInfoPtr = nullptr) + : OMPVarListClause(K, Locs.StartLoc, Locs.LParenLoc, Locs.EndLoc, + Sizes.NumVars), + NumUniqueDeclarations(Sizes.NumUniqueDeclarations), + NumComponentLists(Sizes.NumComponentLists), + NumComponents(Sizes.NumComponents) { + if (MapperQualifierLocPtr) + MapperQualifierLoc = *MapperQualifierLocPtr; + if (MapperIdInfoPtr) + MapperIdInfo = *MapperIdInfoPtr; + } /// Get the unique declarations that are in the trailing objects of the /// class. @@ -3816,6 +4474,42 @@ protected: } } + /// Set the nested name specifier of associated user-defined mapper. + void setMapperQualifierLoc(NestedNameSpecifierLoc NNSL) { + MapperQualifierLoc = NNSL; + } + + /// Set the name of associated user-defined mapper. + void setMapperIdInfo(DeclarationNameInfo MapperId) { + MapperIdInfo = MapperId; + } + + /// Get the user-defined mapper references that are in the trailing objects of + /// the class. + MutableArrayRef getUDMapperRefs() { + return llvm::makeMutableArrayRef( + static_cast(this)->template getTrailingObjects() + + OMPVarListClause::varlist_size(), + OMPVarListClause::varlist_size()); + } + + /// Get the user-defined mappers references that are in the trailing objects + /// of the class. + ArrayRef getUDMapperRefs() const { + return llvm::makeArrayRef( + static_cast(this)->template getTrailingObjects() + + OMPVarListClause::varlist_size(), + OMPVarListClause::varlist_size()); + } + + /// Set the user-defined mappers that are in the trailing objects of the + /// class. + void setUDMapperRefs(ArrayRef DMDs) { + assert(DMDs.size() == OMPVarListClause::varlist_size() && + "Unexpected number of user-defined mappers."); + std::copy(DMDs.begin(), DMDs.end(), getUDMapperRefs().begin()); + } + public: /// Return the number of unique base declarations in this clause. unsigned getUniqueDeclarationsNum() const { return NumUniqueDeclarations; } @@ -3827,6 +4521,14 @@ public: /// clause. unsigned getTotalComponentsNum() const { return NumComponents; } + /// Gets the nested name specifier for associated user-defined mapper. + NestedNameSpecifierLoc getMapperQualifierLoc() const { + return MapperQualifierLoc; + } + + /// Gets the name info for associated user-defined mapper. + const DeclarationNameInfo &getMapperIdInfo() const { return MapperIdInfo; } + /// Iterator that browse the components by lists. It also allows /// browsing components of a single declaration. class const_component_lists_iterator @@ -4030,6 +4732,27 @@ public: auto A = getComponentsRef(); return const_all_components_range(A.begin(), A.end()); } + + using mapperlist_iterator = MutableArrayRef::iterator; + using mapperlist_const_iterator = ArrayRef::iterator; + using mapperlist_range = llvm::iterator_range; + using mapperlist_const_range = + llvm::iterator_range; + + mapperlist_iterator mapperlist_begin() { return getUDMapperRefs().begin(); } + mapperlist_iterator mapperlist_end() { return getUDMapperRefs().end(); } + mapperlist_const_iterator mapperlist_begin() const { + return getUDMapperRefs().begin(); + } + mapperlist_const_iterator mapperlist_end() const { + return getUDMapperRefs().end(); + } + mapperlist_range mapperlists() { + return mapperlist_range(mapperlist_begin(), mapperlist_end()); + } + mapperlist_const_range mapperlists() const { + return mapperlist_const_range(mapperlist_begin(), mapperlist_end()); + } }; /// This represents clause 'map' in the '#pragma omp ...' @@ -4052,7 +4775,9 @@ class OMPMapClause final : public OMPMappableExprListClause, /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. size_t numTrailingObjects(OverloadToken) const { - return varlist_size(); + // There are varlist_size() of expressions, and varlist_size() of + // user-defined mappers. + return 2 * varlist_size(); } size_t numTrailingObjects(OverloadToken) const { return getUniqueDeclarationsNum(); @@ -4069,9 +4794,9 @@ public: private: /// Map-type-modifiers for the 'map' clause. OpenMPMapModifierKind MapTypeModifiers[NumberOfModifiers] = { - OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown - }; - + OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, + OMPC_MAP_MODIFIER_unknown}; + /// Location of map-type-modifiers for the 'map' clause. SourceLocation MapTypeModifiersLoc[NumberOfModifiers]; @@ -4093,50 +4818,49 @@ private: /// /// \param MapModifiers Map-type-modifiers. /// \param MapModifiersLoc Locations of map-type-modifiers. + /// \param MapperQualifierLoc C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperIdInfo The identifier of associated user-defined mapper. /// \param MapType Map type. /// \param MapTypeIsImplicit Map type is inferred implicitly. /// \param MapLoc Location of the map type. - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of 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. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. explicit OMPMapClause(ArrayRef MapModifiers, ArrayRef MapModifiersLoc, + NestedNameSpecifierLoc MapperQualifierLoc, + DeclarationNameInfo MapperIdInfo, OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, - SourceLocation MapLoc, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, - unsigned NumVars, unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPMappableExprListClause(OMPC_map, StartLoc, LParenLoc, EndLoc, - NumVars, NumUniqueDeclarations, - NumComponentLists, NumComponents), - MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), - MapLoc(MapLoc) { - assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() - && "Unexpected number of map type modifiers."); - llvm::copy(MapModifiers, std::begin(MapTypeModifiers)); + SourceLocation MapLoc, const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_map, Locs, Sizes, &MapperQualifierLoc, + &MapperIdInfo), + MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) { + assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() && + "Unexpected number of map type modifiers."); + llvm::copy(MapModifiers, std::begin(MapTypeModifiers)); - assert(llvm::array_lengthof(MapTypeModifiersLoc) == - MapModifiersLoc.size() && - "Unexpected number of map type modifier locations."); - llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc)); + assert(llvm::array_lengthof(MapTypeModifiersLoc) == + MapModifiersLoc.size() && + "Unexpected number of map type modifier locations."); + llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc)); } /// Build an empty 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. - explicit OMPMapClause(unsigned NumVars, unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPMappableExprListClause( - OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(), - NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {} + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPMapClause(const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_map, OMPVarListLocTy(), Sizes) {} /// Set map-type-modifier for the clause. /// @@ -4175,41 +4899,44 @@ public: /// Creates clause with a list of variables \a VL. /// /// \param C AST context. - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. /// \param Vars The original expression used in the clause. /// \param Declarations Declarations used in the clause. /// \param ComponentLists Component lists used in the clause. + /// \param UDMapperRefs References to user-defined mappers associated with + /// expressions used in the clause. /// \param MapModifiers Map-type-modifiers. /// \param MapModifiersLoc Location of map-type-modifiers. + /// \param UDMQualifierLoc C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperId The identifier of associated user-defined mapper. /// \param Type Map type. /// \param TypeIsImplicit Map type is inferred implicitly. /// \param TypeLoc Location of the map type. - static OMPMapClause *Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, - ArrayRef Vars, - ArrayRef Declarations, - MappableExprComponentListsRef ComponentLists, - ArrayRef MapModifiers, - ArrayRef MapModifiersLoc, - OpenMPMapClauseKind Type, bool TypeIsImplicit, - SourceLocation TypeLoc); + static OMPMapClause * + Create(const ASTContext &C, const OMPVarListLocTy &Locs, + ArrayRef Vars, ArrayRef Declarations, + MappableExprComponentListsRef ComponentLists, + ArrayRef UDMapperRefs, + ArrayRef MapModifiers, + ArrayRef MapModifiersLoc, + NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId, + OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc); /// Creates an empty clause with the place for \a NumVars original /// expressions, \a NumUniqueDeclarations declarations, \NumComponentLists /// lists, and \a NumComponents expression components. /// /// \param C AST context. - /// \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 OMPMapClause *CreateEmpty(const ASTContext &C, unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents); + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + static OMPMapClause *CreateEmpty(const ASTContext &C, + const OMPMappableExprListSizeTy &Sizes); /// Fetches mapping kind for the clause. OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; } @@ -4233,7 +4960,7 @@ public: /// Fetches the map-type-modifier location at 'Cnt' index of array of /// modifiers' locations. /// - /// \param Cnt index for map-type-modifier location. + /// \param Cnt index for map-type-modifier location. SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY { assert(Cnt < NumberOfModifiers && "Requested modifier location exceeds total number of modifiers."); @@ -4244,7 +4971,7 @@ public: ArrayRef getMapTypeModifiers() const LLVM_READONLY { return llvm::makeArrayRef(MapTypeModifiers); } - + /// Fetches ArrayRef of location of map-type-modifiers. ArrayRef getMapTypeModifiersLoc() const LLVM_READONLY { return llvm::makeArrayRef(MapTypeModifiersLoc); @@ -4262,6 +4989,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_map; } @@ -4326,6 +5065,17 @@ public: child_range children() { return child_range(&NumTeams, &NumTeams + 1); } + const_child_range children() const { + return const_child_range(&NumTeams, &NumTeams + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_num_teams; } @@ -4391,6 +5141,17 @@ public: child_range children() { return child_range(&ThreadLimit, &ThreadLimit + 1); } + const_child_range children() const { + return const_child_range(&ThreadLimit, &ThreadLimit + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_thread_limit; } @@ -4448,6 +5209,17 @@ public: child_range children() { return child_range(&Priority, &Priority + 1); } + const_child_range children() const { + return const_child_range(&Priority, &Priority + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_priority; } @@ -4499,6 +5271,17 @@ public: child_range children() { return child_range(&Grainsize, &Grainsize + 1); } + const_child_range children() const { + return const_child_range(&Grainsize, &Grainsize + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_grainsize; } @@ -4527,6 +5310,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_nogroup; } @@ -4578,6 +5372,17 @@ public: child_range children() { return child_range(&NumTasks, &NumTasks + 1); } + const_child_range children() const { + return const_child_range(&NumTasks, &NumTasks + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_num_tasks; } @@ -4628,6 +5433,17 @@ public: child_range children() { return child_range(&Hint, &Hint + 1); } + const_child_range children() const { + return const_child_range(&Hint, &Hint + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_hint; } @@ -4735,6 +5551,18 @@ public: reinterpret_cast(&ChunkSize) + 1); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_dist_schedule; } @@ -4836,6 +5664,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_defaultmap; } @@ -4860,38 +5699,40 @@ class OMPToClause final : public OMPMappableExprListClause, /// Build clause with number of variables \a NumVars. /// - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of 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. - explicit OMPToClause(SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPMappableExprListClause(OMPC_to, StartLoc, LParenLoc, EndLoc, NumVars, - NumUniqueDeclarations, NumComponentLists, - NumComponents) {} + /// \param MapperQualifierLoc C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperIdInfo The identifier of associated user-defined mapper. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPToClause(NestedNameSpecifierLoc MapperQualifierLoc, + DeclarationNameInfo MapperIdInfo, + const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_to, Locs, Sizes, &MapperQualifierLoc, + &MapperIdInfo) {} /// Build an empty 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. - explicit OMPToClause(unsigned NumVars, unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPMappableExprListClause( - OMPC_to, SourceLocation(), SourceLocation(), SourceLocation(), - NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {} + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPToClause(const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_to, OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. size_t numTrailingObjects(OverloadToken) const { - return varlist_size(); + // There are varlist_size() of expressions, and varlist_size() of + // user-defined mappers. + return 2 * varlist_size(); } size_t numTrailingObjects(OverloadToken) const { return getUniqueDeclarationsNum(); @@ -4904,36 +5745,53 @@ public: /// Creates clause with a list of variables \a Vars. /// /// \param C AST context. - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. /// \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 OMPToClause *Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, + /// \param UDMapperRefs References to user-defined mappers associated with + /// expressions used in the clause. + /// \param UDMQualifierLoc C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperId The identifier of associated user-defined mapper. + static OMPToClause *Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef Vars, ArrayRef Declarations, - MappableExprComponentListsRef ComponentLists); + MappableExprComponentListsRef ComponentLists, + ArrayRef UDMapperRefs, + NestedNameSpecifierLoc UDMQualifierLoc, + DeclarationNameInfo MapperId); /// Creates an empty clause with the place for \a NumVars variables. /// /// \param C AST context. - /// \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 OMPToClause *CreateEmpty(const ASTContext &C, unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents); + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + static OMPToClause *CreateEmpty(const ASTContext &C, + const OMPMappableExprListSizeTy &Sizes); child_range children() { return child_range(reinterpret_cast(varlist_begin()), reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_to; } @@ -4959,38 +5817,40 @@ class OMPFromClause final /// Build clause with number of variables \a NumVars. /// - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of 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. - explicit OMPFromClause(SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPMappableExprListClause(OMPC_from, StartLoc, LParenLoc, EndLoc, - NumVars, NumUniqueDeclarations, - NumComponentLists, NumComponents) {} + /// \param MapperQualifierLoc C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperIdInfo The identifier of associated user-defined mapper. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPFromClause(NestedNameSpecifierLoc MapperQualifierLoc, + DeclarationNameInfo MapperIdInfo, + const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_from, Locs, Sizes, &MapperQualifierLoc, + &MapperIdInfo) {} /// Build an empty 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. - explicit OMPFromClause(unsigned NumVars, unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPMappableExprListClause( - OMPC_from, SourceLocation(), SourceLocation(), SourceLocation(), - NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {} + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPFromClause(const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_from, OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. size_t numTrailingObjects(OverloadToken) const { - return varlist_size(); + // There are varlist_size() of expressions, and varlist_size() of + // user-defined mappers. + return 2 * varlist_size(); } size_t numTrailingObjects(OverloadToken) const { return getUniqueDeclarationsNum(); @@ -5003,36 +5863,53 @@ public: /// Creates clause with a list of variables \a Vars. /// /// \param C AST context. - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. /// \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 OMPFromClause *Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, + /// \param UDMapperRefs References to user-defined mappers associated with + /// expressions used in the clause. + /// \param UDMQualifierLoc C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperId The identifier of associated user-defined mapper. + static OMPFromClause *Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef Vars, ArrayRef Declarations, - MappableExprComponentListsRef ComponentLists); + MappableExprComponentListsRef ComponentLists, + ArrayRef UDMapperRefs, + NestedNameSpecifierLoc UDMQualifierLoc, + DeclarationNameInfo MapperId); /// Creates an empty clause with the place for \a NumVars variables. /// /// \param C AST context. - /// \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 OMPFromClause *CreateEmpty(const ASTContext &C, unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents); + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + static OMPFromClause *CreateEmpty(const ASTContext &C, + const OMPMappableExprListSizeTy &Sizes); child_range children() { return child_range(reinterpret_cast(varlist_begin()), reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_from; } @@ -5058,38 +5935,28 @@ class OMPUseDevicePtrClause final /// Build clause with number of variables \a NumVars. /// - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of 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. - 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) {} + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_use_device_ptr, Locs, Sizes) {} /// Build an empty 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. - explicit OMPUseDevicePtrClause(unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents) - : OMPMappableExprListClause(OMPC_use_device_ptr, SourceLocation(), - SourceLocation(), SourceLocation(), NumVars, - NumUniqueDeclarations, NumComponentLists, - NumComponents) {} + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPUseDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_use_device_ptr, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -5135,34 +6002,30 @@ public: /// Creates clause with a list of variables \a Vars. /// /// \param C AST context. - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. /// \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 Vars, - ArrayRef PrivateVars, ArrayRef Inits, - ArrayRef Declarations, + Create(const ASTContext &C, const OMPVarListLocTy &Locs, + ArrayRef Vars, ArrayRef PrivateVars, + ArrayRef Inits, ArrayRef Declarations, MappableExprComponentListsRef ComponentLists); /// Creates an empty clause with the place for \a NumVars variables. /// /// \param C AST context. - /// \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 NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents); + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + static OMPUseDevicePtrClause * + CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes); using private_copies_iterator = MutableArrayRef::iterator; using private_copies_const_iterator = ArrayRef::iterator; @@ -5198,6 +6061,18 @@ public: reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_use_device_ptr; } @@ -5223,38 +6098,28 @@ class OMPIsDevicePtrClause final /// Build clause with number of variables \a NumVars. /// - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of 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. - 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) {} + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPIsDevicePtrClause(const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_is_device_ptr, Locs, Sizes) {} /// Build an empty 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. - explicit OMPIsDevicePtrClause(unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents) - : OMPMappableExprListClause(OMPC_is_device_ptr, SourceLocation(), - SourceLocation(), SourceLocation(), NumVars, - NumUniqueDeclarations, NumComponentLists, - NumComponents) {} + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPIsDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_is_device_ptr, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -5272,37 +6137,45 @@ public: /// Creates clause with a list of variables \a Vars. /// /// \param C AST context. - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. /// \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 Vars, - ArrayRef Declarations, + Create(const ASTContext &C, const OMPVarListLocTy &Locs, + ArrayRef Vars, ArrayRef Declarations, MappableExprComponentListsRef ComponentLists); /// Creates an empty clause with the place for \a NumVars variables. /// /// \param C AST context. - /// \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 NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents); + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + static OMPIsDevicePtrClause * + CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes); child_range children() { return child_range(reinterpret_cast(varlist_begin()), reinterpret_cast(varlist_end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_is_device_ptr; } diff --git a/include/clang/AST/OperationKinds.def b/include/clang/AST/OperationKinds.def index cd19091e31d6..9af92c1ae7ff 100644 --- a/include/clang/AST/OperationKinds.def +++ b/include/clang/AST/OperationKinds.def @@ -1,9 +1,8 @@ //===--- OperationKinds.def - Operations Database ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -67,6 +66,10 @@ CAST_OPERATION(BitCast) /// bool b; reinterpret_cast(b) = 'a'; CAST_OPERATION(LValueBitCast) +/// CK_LValueToRValueBitCast - A conversion that causes us to reinterpret an +/// lvalue as an rvalue of a different type. Created by __builtin_bit_cast. +CAST_OPERATION(LValueToRValueBitCast) + /// CK_LValueToRValue - A conversion which causes the extraction of /// an r-value from the operand gl-value. The result of an r-value /// conversion is always unqualified. @@ -201,6 +204,14 @@ CAST_OPERATION(IntegralToFloating) /// (_Accum) 0.5r CAST_OPERATION(FixedPointCast) +/// CK_FixedPointToIntegral - Fixed point to integral. +/// (int) 2.0k +CAST_OPERATION(FixedPointToIntegral) + +/// CK_IntegralToFixedPoint - Integral to a fixed point. +/// (_Accum) 2 +CAST_OPERATION(IntegralToFixedPoint) + /// CK_FixedPointToBoolean - Fixed point to boolean. /// (bool) 0.5r CAST_OPERATION(FixedPointToBoolean) diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h index ac512d721e34..679e0fdd4056 100644 --- a/include/clang/AST/OperationKinds.h +++ b/include/clang/AST/OperationKinds.h @@ -1,9 +1,8 @@ //===- OperationKinds.h - Operation enums -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h index c1c76ceaaf69..1e65d7efd272 100644 --- a/include/clang/AST/ParentMap.h +++ b/include/clang/AST/ParentMap.h @@ -1,9 +1,8 @@ //===--- ParentMap.h - Mappings from Stmts to their Parents -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/PrettyDeclStackTrace.h b/include/clang/AST/PrettyDeclStackTrace.h index 8eb519eae26d..899bbcb3be45 100644 --- a/include/clang/AST/PrettyDeclStackTrace.h +++ b/include/clang/AST/PrettyDeclStackTrace.h @@ -1,9 +1,8 @@ //===- PrettyDeclStackTrace.h - Stack trace for decl processing -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index 3c877f5ea19c..0cd62ba373dc 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -1,9 +1,8 @@ //===--- PrettyPrinter.h - Classes for aiding with AST printing -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/QualTypeNames.h b/include/clang/AST/QualTypeNames.h index 422ed9e4c8fc..8313e0441be5 100644 --- a/include/clang/AST/QualTypeNames.h +++ b/include/clang/AST/QualTypeNames.h @@ -1,7 +1,8 @@ //===--- QualTypeNames.h - Generate Complete QualType Names ----*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // ===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h index d17c9df67e41..5dc8694e77e9 100644 --- a/include/clang/AST/RawCommentList.h +++ b/include/clang/AST/RawCommentList.h @@ -1,9 +1,8 @@ //===--- RawCommentList.h - Classes for processing raw comments -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index a546c200ffe0..b259791af509 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -1,9 +1,8 @@ //===- RecordLayout.h - Layout information for a struct/union ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 44aba6355758..698fba2f4ed1 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1,9 +1,8 @@ //===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -1066,6 +1065,9 @@ DEF_TRAVERSE_TYPE(AttributedType, DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); }) +DEF_TRAVERSE_TYPE(MacroQualifiedType, + { TRY_TO(TraverseType(T->getUnderlyingType())); }) + DEF_TRAVERSE_TYPE(ElaboratedType, { if (T->getQualifier()) { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); @@ -1309,6 +1311,9 @@ DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {}) DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); }) +DEF_TRAVERSE_TYPELOC(MacroQualifiedType, + { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); }) + DEF_TRAVERSE_TYPELOC(AttributedType, { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); }) @@ -1459,9 +1464,9 @@ DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, { TRY_TO(TraverseDecl(D->getSpecialization())); if (D->hasExplicitTemplateArgs()) { - const TemplateArgumentListInfo &args = D->templateArgs(); - TRY_TO(TraverseTemplateArgumentLocsHelper(args.getArgumentArray(), - args.size())); + TRY_TO(TraverseTemplateArgumentLocsHelper( + D->getTemplateArgsAsWritten()->getTemplateArgs(), + D->getTemplateArgsAsWritten()->NumTemplateArgs)); } }) @@ -1590,7 +1595,7 @@ DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, { TRY_TO(TraverseStmt(I)); } }) - + DEF_TRAVERSE_DECL(OMPRequiresDecl, { for (auto *C : D->clauselists()) { TRY_TO(TraverseOMPClause(C)); @@ -1605,8 +1610,22 @@ DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, { return true; }) +DEF_TRAVERSE_DECL(OMPDeclareMapperDecl, { + for (auto *C : D->clauselists()) + TRY_TO(TraverseOMPClause(C)); + TRY_TO(TraverseType(D->getType())); + return true; +}) + DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); }) +DEF_TRAVERSE_DECL(OMPAllocateDecl, { + for (auto *I : D->varlists()) + TRY_TO(TraverseStmt(I)); + for (auto *C : D->clauselists()) + TRY_TO(TraverseOMPClause(C)); +}) + // A helper method for TemplateDecl's children. template bool RecursiveASTVisitor::TraverseTemplateParameterListHelper( @@ -1781,6 +1800,11 @@ DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, { TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); }) +DEF_TRAVERSE_DECL(ConceptDecl, { + TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); + TRY_TO(TraverseStmt(D->getConstraintExpr())); +}) + DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, { // A dependent using declaration which was marked with 'typename'. // template class A : public B { using typename B::foo; }; @@ -2263,6 +2287,10 @@ DEF_TRAVERSE_STMT(CXXStaticCastExpr, { TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) +DEF_TRAVERSE_STMT(BuiltinBitCastExpr, { + TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); +}) + template bool RecursiveASTVisitor::TraverseSynOrSemInitListExpr( InitListExpr *S, DataRecursionQueue *Queue) { @@ -2301,10 +2329,10 @@ bool RecursiveASTVisitor::TraverseInitListExpr( // generic associations). DEF_TRAVERSE_STMT(GenericSelectionExpr, { TRY_TO(TraverseStmt(S->getControllingExpr())); - for (unsigned i = 0; i != S->getNumAssocs(); ++i) { - if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i)) - TRY_TO(TraverseTypeLoc(TS->getTypeLoc())); - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAssocExpr(i)); + for (const GenericSelectionExpr::Association &Assoc : S->associations()) { + if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo()) + TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr()); } ShouldVisitChildren = false; }) @@ -2410,6 +2438,10 @@ DEF_TRAVERSE_STMT(LambdaExpr, { TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); FunctionProtoTypeLoc Proto = TL.getAsAdjusted(); + for (Decl *D : S->getExplicitTemplateParameters()) { + // Visit explicit template parameters. + TRY_TO(TraverseDecl(D)); + } if (S->hasExplicitParameters()) { // Visit parameters. for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) @@ -2527,6 +2559,8 @@ DEF_TRAVERSE_STMT(PredefinedExpr, {}) DEF_TRAVERSE_STMT(ShuffleVectorExpr, {}) DEF_TRAVERSE_STMT(ConvertVectorExpr, {}) DEF_TRAVERSE_STMT(StmtExpr, {}) +DEF_TRAVERSE_STMT(SourceLocExpr, {}) + DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); if (S->hasExplicitTemplateArgs()) { @@ -2813,6 +2847,20 @@ bool RecursiveASTVisitor::VisitOMPClauseWithPostUpdate( return true; } +template +bool RecursiveASTVisitor::VisitOMPAllocatorClause( + OMPAllocatorClause *C) { + TRY_TO(TraverseStmt(C->getAllocator())); + return true; +} + +template +bool RecursiveASTVisitor::VisitOMPAllocateClause(OMPAllocateClause *C) { + TRY_TO(TraverseStmt(C->getAllocator())); + TRY_TO(VisitOMPClauseList(C)); + return true; +} + template bool RecursiveASTVisitor::VisitOMPIfClause(OMPIfClause *C) { TRY_TO(VisitOMPClauseWithPreInit(C)); diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h index c2bd6e6fd136..0975773dd2cb 100644 --- a/include/clang/AST/Redeclarable.h +++ b/include/clang/AST/Redeclarable.h @@ -1,9 +1,8 @@ //===- Redeclarable.h - Base for Decls that can be redeclared --*- C++ -*-====// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -362,6 +361,13 @@ public: decl_type &operator*() { return *Ptr; } const decl_type &operator*() const { return *Ptr; } + friend bool operator==(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS) { + return LHS.Ptr == RHS.Ptr; + } + friend bool operator!=(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS) { + return LHS.Ptr != RHS.Ptr; + } + private: friend struct llvm::DenseMapInfo>; diff --git a/include/clang/AST/SelectorLocationsKind.h b/include/clang/AST/SelectorLocationsKind.h index 6ca2dba47558..6e9923de6742 100644 --- a/include/clang/AST/SelectorLocationsKind.h +++ b/include/clang/AST/SelectorLocationsKind.h @@ -1,9 +1,8 @@ //===--- SelectorLocationsKind.h - Kind of selector locations ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index ff5baa21adff..403b88ac3a3c 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -1,9 +1,8 @@ //===- Stmt.h - Classes for representing statements -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -47,6 +46,7 @@ class Attr; class CapturedDecl; class Decl; class Expr; +class AddrLabelExpr; class LabelDecl; class ODRHash; class PrinterHelper; @@ -92,12 +92,20 @@ protected: //===--- Statement bitfields classes ---===// class StmtBitfields { + friend class ASTStmtReader; + friend class ASTStmtWriter; friend class Stmt; /// The statement class. unsigned sClass : 8; + + /// This bit is set only for the Stmts that are the structured-block of + /// OpenMP executable directives. Directives that have a structured block + /// are called "non-standalone" directives. + /// I.e. those returned by OMPExecutableDirective::getStructuredBlock(). + unsigned IsOMPStructuredBlock : 1; }; - enum { NumStmtBits = 8 }; + enum { NumStmtBits = 9 }; class NullStmtBitfields { friend class ASTStmtReader; @@ -314,6 +322,33 @@ protected: }; enum { NumExprBits = NumStmtBits + 9 }; + class ConstantExprBitfields { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend class ConstantExpr; + + unsigned : NumExprBits; + + /// The kind of result that is trail-allocated. + unsigned ResultKind : 2; + + /// Kind of Result as defined by APValue::Kind + unsigned APValueKind : 4; + + /// When ResultKind == RSK_Int64. whether the trail-allocated integer is + /// signed. + unsigned IsUnsigned : 1; + + /// When ResultKind == RSK_Int64. the BitWidth of the trail-allocated + /// integer. 7 bits because it is the minimal number of bit to represent a + /// value from 0 to 64 (the size of the trail-allocated number). + unsigned BitWidth : 7; + + /// When ResultKind == RSK_APValue. Wether the ASTContext will cleanup the + /// destructor on the trail-allocated APValue. + unsigned HasCleanup : 1; + }; + class PredefinedExprBitfields { friend class ASTStmtReader; friend class PredefinedExpr; @@ -343,19 +378,12 @@ protected: unsigned HasFoundDecl : 1; unsigned HadMultipleCandidates : 1; unsigned RefersToEnclosingVariableOrCapture : 1; + unsigned NonOdrUseReason : 2; /// The location of the declaration name itself. SourceLocation Loc; }; - enum APFloatSemantics { - IEEEhalf, - IEEEsingle, - IEEEdouble, - x87DoubleExtended, - IEEEquad, - PPCDoubleDouble - }; class FloatingLiteralBitfields { friend class FloatingLiteral; @@ -445,6 +473,7 @@ protected: enum { NumCallExprBits = 32 }; class MemberExprBitfields { + friend class ASTStmtReader; friend class MemberExpr; unsigned : NumExprBits; @@ -469,6 +498,11 @@ protected: /// was resolved from an overloaded set having size greater than 1. unsigned HadMultipleCandidates : 1; + /// Value of type NonOdrUseReason indicating why this MemberExpr does + /// not constitute an odr-use of the named declaration. Meaningful only + /// when naming a static member. + unsigned NonOdrUseReason : 2; + /// This is the location of the -> or . in the expression. SourceLocation OperatorLoc; }; @@ -521,6 +555,16 @@ protected: unsigned NumExprs; }; + class GenericSelectionExprBitfields { + friend class ASTStmtReader; + friend class GenericSelectionExpr; + + unsigned : NumExprBits; + + /// The location of the "_Generic". + SourceLocation GenericLoc; + }; + class PseudoObjectExprBitfields { friend class ASTStmtReader; // deserialization friend class PseudoObjectExpr; @@ -533,6 +577,17 @@ protected: unsigned ResultIndex : 32 - 8 - NumExprBits; }; + class SourceLocExprBitfields { + friend class ASTStmtReader; + friend class SourceLocExpr; + + unsigned : NumExprBits; + + /// The kind of source location builtin represented by the SourceLocExpr. + /// Ex. __builtin_LINE, __builtin_FUNCTION, ect. + unsigned Kind : 2; + }; + //===--- C++ Expression bitfields classes ---===// class CXXOperatorCallExprBitfields { @@ -902,6 +957,7 @@ protected: // Expressions ExprBitfields ExprBits; + ConstantExprBitfields ConstantExprBits; PredefinedExprBitfields PredefinedExprBits; DeclRefExprBitfields DeclRefExprBits; FloatingLiteralBitfields FloatingLiteralBits; @@ -916,7 +972,9 @@ protected: BinaryOperatorBitfields BinaryOperatorBits; InitListExprBitfields InitListExprBits; ParenListExprBitfields ParenListExprBits; + GenericSelectionExprBitfields GenericSelectionExprBits; PseudoObjectExprBitfields PseudoObjectExprBits; + SourceLocExprBitfields SourceLocExprBits; // C++ Expressions CXXOperatorCallExprBitfields CXXOperatorCallExprBits; @@ -976,37 +1034,30 @@ public: struct EmptyShell {}; protected: - /// Iterator for iterating over Stmt * arrays that contain only Expr * + /// Iterator for iterating over Stmt * arrays that contain only T *. /// /// This is needed because AST nodes use Stmt* arrays to store /// references to children (to be compatible with StmtIterator). - struct ExprIterator - : llvm::iterator_adaptor_base { - ExprIterator() : iterator_adaptor_base(nullptr) {} - ExprIterator(Stmt **I) : iterator_adaptor_base(I) {} + template + struct CastIterator + : llvm::iterator_adaptor_base, StmtPtr *, + std::random_access_iterator_tag, TPtr> { + using Base = typename CastIterator::iterator_adaptor_base; - reference operator*() const { - assert((*I)->getStmtClass() >= firstExprConstant && - (*I)->getStmtClass() <= lastExprConstant); - return *reinterpret_cast(I); + CastIterator() : Base(nullptr) {} + CastIterator(StmtPtr *I) : Base(I) {} + + typename Base::value_type operator*() const { + return cast_or_null(*this->I); } }; - /// Const iterator for iterating over Stmt * arrays that contain only Expr * - struct ConstExprIterator - : llvm::iterator_adaptor_base { - ConstExprIterator() : iterator_adaptor_base(nullptr) {} - ConstExprIterator(const Stmt *const *I) : iterator_adaptor_base(I) {} + /// Const iterator for iterating over Stmt * arrays that contain only T *. + template + using ConstCastIterator = CastIterator; - reference operator*() const { - assert((*I)->getStmtClass() >= firstExprConstant && - (*I)->getStmtClass() <= lastExprConstant); - return *reinterpret_cast(I); - } - }; + using ExprIterator = CastIterator; + using ConstExprIterator = ConstCastIterator; private: /// Whether statistic collection is enabled. @@ -1017,12 +1068,19 @@ protected: explicit Stmt(StmtClass SC, EmptyShell) : Stmt(SC) {} public: + Stmt() = delete; + Stmt(const Stmt &) = delete; + Stmt(Stmt &&) = delete; + Stmt &operator=(const Stmt &) = delete; + Stmt &operator=(Stmt &&) = delete; + Stmt(StmtClass SC) { static_assert(sizeof(*this) <= 8, "changing bitfields changed sizeof(Stmt)"); static_assert(sizeof(*this) % alignof(void *) == 0, "Insufficient alignment!"); StmtBits.sClass = SC; + StmtBits.IsOMPStructuredBlock = false; if (StatisticsEnabled) Stmt::addStmtClass(SC); } @@ -1032,6 +1090,11 @@ public: const char *getStmtClassName() const; + bool isOMPStructuredBlock() const { return StmtBits.IsOMPStructuredBlock; } + void setIsOMPStructuredBlock(bool IsOMPStructuredBlock) { + StmtBits.IsOMPStructuredBlock = IsOMPStructuredBlock; + } + /// SourceLocation tokens are not useful in isolation - they are low level /// value objects created/interpreted by SourceManager. We assume AST /// clients will have a pointer to the respective SourceManager. @@ -1065,17 +1128,14 @@ public: StringRef NewlineSymbol = "\n", const ASTContext *Context = nullptr) const; + /// Pretty-prints in JSON format. + void printJson(raw_ostream &Out, PrinterHelper *Helper, + const PrintingPolicy &Policy, bool AddQuotes) const; + /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only /// works on systems with GraphViz (Mac OS X) or dot+gv installed. void viewAST() const; - /// 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(this)->IgnoreImplicit(); - } - /// Skip no-op (attributed, compound) container stmts and skip captured /// stmt at the top, if \a IgnoreCaptured is true. Stmt *IgnoreContainers(bool IgnoreCaptured = false); @@ -1178,6 +1238,11 @@ public: child_iterator(DG.end(), DG.end())); } + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children); + } + using decl_iterator = DeclGroupRef::iterator; using const_decl_iterator = DeclGroupRef::const_iterator; using decl_range = llvm::iterator_range; @@ -1235,6 +1300,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// CompoundStmt - This represents a group of statements like { stmt stmt }. @@ -1280,11 +1349,6 @@ public: return !body_empty() ? body_begin()[size() - 1] : nullptr; } - void setLastStmt(Stmt *S) { - assert(!body_empty() && "setLastStmt"); - body_begin()[size() - 1] = S; - } - using const_body_iterator = Stmt *const *; using body_const_range = llvm::iterator_range; @@ -1327,6 +1391,26 @@ public: return const_reverse_body_iterator(body_begin()); } + // Get the Stmt that StmtExpr would consider to be the result of this + // compound statement. This is used by StmtExpr to properly emulate the GCC + // compound expression extension, which ignores trailing NullStmts when + // getting the result of the expression. + // i.e. ({ 5;;; }) + // ^^ ignored + // If we don't find something that isn't a NullStmt, just return the last + // Stmt. + Stmt *getStmtExprResult() { + for (auto *B : llvm::reverse(body())) { + if (!isa(B)) + return B; + } + return body_back(); + } + + const Stmt *getStmtExprResult() const { + return const_cast(this)->getStmtExprResult(); + } + SourceLocation getBeginLoc() const { return CompoundStmtBits.LBraceLoc; } SourceLocation getEndLoc() const { return RBraceLoc; } @@ -1539,6 +1623,12 @@ public: getTrailingObjects() + numTrailingObjects(OverloadToken())); } + + const_child_range children() const { + return const_child_range(getTrailingObjects(), + getTrailingObjects() + + numTrailingObjects(OverloadToken())); + } }; class DefaultStmt : public SwitchCase { @@ -1570,6 +1660,10 @@ public: // Iterators child_range children() { return child_range(&SubStmt, &SubStmt + 1); } + + const_child_range children() const { + return const_child_range(&SubStmt, &SubStmt + 1); + } }; SourceLocation SwitchCase::getEndLoc() const { @@ -1588,21 +1682,44 @@ Stmt *SwitchCase::getSubStmt() { llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!"); } +/// Represents a statement that could possibly have a value and type. This +/// covers expression-statements, as well as labels and attributed statements. +/// +/// Value statements have a special meaning when they are the last non-null +/// statement in a GNU statement expression, where they determine the value +/// of the statement expression. +class ValueStmt : public Stmt { +protected: + using Stmt::Stmt; + +public: + const Expr *getExprStmt() const; + Expr *getExprStmt() { + const ValueStmt *ConstThis = this; + return const_cast(ConstThis->getExprStmt()); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() >= firstValueStmtConstant && + T->getStmtClass() <= lastValueStmtConstant; + } +}; + /// LabelStmt - Represents a label, which has a substatement. For example: /// foo: return; -class LabelStmt : public Stmt { +class LabelStmt : public ValueStmt { LabelDecl *TheDecl; Stmt *SubStmt; public: /// Build a label statement. LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt) - : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) { + : ValueStmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) { setIdentLoc(IL); } /// Build an empty label statement. - explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) {} + explicit LabelStmt(EmptyShell Empty) : ValueStmt(LabelStmtClass, Empty) {} SourceLocation getIdentLoc() const { return LabelStmtBits.IdentLoc; } void setIdentLoc(SourceLocation L) { LabelStmtBits.IdentLoc = L; } @@ -1621,6 +1738,10 @@ public: child_range children() { return child_range(&SubStmt, &SubStmt + 1); } + const_child_range children() const { + return const_child_range(&SubStmt, &SubStmt + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == LabelStmtClass; } @@ -1631,7 +1752,7 @@ public: /// Represents an attribute applied to a statement. For example: /// [[omp::for(...)]] for (...) { ... } class AttributedStmt final - : public Stmt, + : public ValueStmt, private llvm::TrailingObjects { friend class ASTStmtReader; friend TrailingObjects; @@ -1640,14 +1761,14 @@ class AttributedStmt final AttributedStmt(SourceLocation Loc, ArrayRef Attrs, Stmt *SubStmt) - : Stmt(AttributedStmtClass), SubStmt(SubStmt) { + : ValueStmt(AttributedStmtClass), SubStmt(SubStmt) { AttributedStmtBits.NumAttrs = Attrs.size(); AttributedStmtBits.AttrLoc = Loc; std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr()); } explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs) - : Stmt(AttributedStmtClass, Empty) { + : ValueStmt(AttributedStmtClass, Empty) { AttributedStmtBits.NumAttrs = NumAttrs; AttributedStmtBits.AttrLoc = SourceLocation{}; std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr); @@ -1678,6 +1799,10 @@ public: child_range children() { return child_range(&SubStmt, &SubStmt + 1); } + const_child_range children() const { + return const_child_range(&SubStmt, &SubStmt + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == AttributedStmtClass; } @@ -1877,6 +2002,12 @@ public: numTrailingObjects(OverloadToken())); } + const_child_range children() const { + return const_child_range(getTrailingObjects(), + getTrailingObjects() + + numTrailingObjects(OverloadToken())); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == IfStmtClass; } @@ -2054,6 +2185,12 @@ public: numTrailingObjects(OverloadToken())); } + const_child_range children() const { + return const_child_range(getTrailingObjects(), + getTrailingObjects() + + numTrailingObjects(OverloadToken())); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == SwitchStmtClass; } @@ -2179,6 +2316,12 @@ public: getTrailingObjects() + numTrailingObjects(OverloadToken())); } + + const_child_range children() const { + return const_child_range(getTrailingObjects(), + getTrailingObjects() + + numTrailingObjects(OverloadToken())); + } }; /// DoStmt - This represents a 'do/while' stmt. @@ -2229,6 +2372,10 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); } + + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); + } }; /// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of @@ -2298,6 +2445,10 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); } + + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); + } }; /// GotoStmt - This represents a direct goto. @@ -2333,6 +2484,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// IndirectGotoStmt - This represents an indirect goto. @@ -2378,6 +2533,10 @@ public: // Iterators child_range children() { return child_range(&Target, &Target + 1); } + + const_child_range children() const { + return const_child_range(&Target, &Target + 1); + } }; /// ContinueStmt - This represents a continue. @@ -2404,6 +2563,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// BreakStmt - This represents a break. @@ -2430,6 +2593,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// ReturnStmt - This represents a return, optionally of an expression: @@ -2514,6 +2681,12 @@ public: return child_range(&RetExpr, &RetExpr + 1); return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + if (RetExpr) + return const_child_range(&RetExpr, &RetExpr + 1); + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt. @@ -2669,6 +2842,10 @@ public: child_range children() { return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs); } + + const_child_range children() const { + return const_child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs); + } }; /// This represents a GCC inline-assembly statement extension. @@ -2682,13 +2859,15 @@ class GCCAsmStmt : public AsmStmt { StringLiteral **Constraints = nullptr; StringLiteral **Clobbers = nullptr; IdentifierInfo **Names = nullptr; + unsigned NumLabels = 0; public: GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, unsigned numoutputs, unsigned numinputs, IdentifierInfo **names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, - StringLiteral **clobbers, SourceLocation rparenloc); + StringLiteral **clobbers, unsigned numlabels, + SourceLocation rparenloc); /// Build an empty inline-assembly statement. explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty) {} @@ -2813,6 +2992,51 @@ public: return const_cast(this)->getInputExpr(i); } + //===--- Labels ---===// + + bool isAsmGoto() const { + return NumLabels > 0; + } + + unsigned getNumLabels() const { + return NumLabels; + } + + IdentifierInfo *getLabelIdentifier(unsigned i) const { + return Names[i + NumInputs]; + } + + AddrLabelExpr *getLabelExpr(unsigned i) const; + StringRef getLabelName(unsigned i) const; + using labels_iterator = CastIterator; + using const_labels_iterator = ConstCastIterator; + using labels_range = llvm::iterator_range; + using labels_const_range = llvm::iterator_range; + + labels_iterator begin_labels() { + return &Exprs[0] + NumInputs; + } + + labels_iterator end_labels() { + return &Exprs[0] + NumInputs + NumLabels; + } + + labels_range labels() { + return labels_range(begin_labels(), end_labels()); + } + + const_labels_iterator begin_labels() const { + return &Exprs[0] + NumInputs; + } + + const_labels_iterator end_labels() const { + return &Exprs[0] + NumInputs + NumLabels; + } + + labels_const_range labels() const { + return labels_const_range(begin_labels(), end_labels()); + } + private: void setOutputsAndInputsAndClobbers(const ASTContext &C, IdentifierInfo **Names, @@ -2820,6 +3044,7 @@ private: Stmt **Exprs, unsigned NumOutputs, unsigned NumInputs, + unsigned NumLabels, StringLiteral **Clobbers, unsigned NumClobbers); @@ -2945,6 +3170,10 @@ public: child_range children() { return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]); } + + const_child_range children() const { + return const_child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]); + } }; class SEHExceptStmt : public Stmt { @@ -2982,6 +3211,10 @@ public: return child_range(Children, Children+2); } + const_child_range children() const { + return const_child_range(Children, Children + 2); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == SEHExceptStmtClass; } @@ -3013,6 +3246,10 @@ public: return child_range(&Block,&Block+1); } + const_child_range children() const { + return const_child_range(&Block, &Block + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == SEHFinallyStmtClass; } @@ -3061,6 +3298,10 @@ public: return child_range(Children, Children+2); } + const_child_range children() const { + return const_child_range(Children, Children + 2); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == SEHTryStmtClass; } @@ -3091,6 +3332,10 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// This captures a statement into a function. For example, the following @@ -3311,6 +3556,8 @@ public: } child_range children(); + + const_child_range children() const; }; } // namespace clang diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h index d3a3cf783c66..4d1f3e8ef255 100644 --- a/include/clang/AST/StmtCXX.h +++ b/include/clang/AST/StmtCXX.h @@ -1,9 +1,8 @@ //===--- StmtCXX.h - Classes for representing C++ statements ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -57,6 +56,10 @@ public: child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); } + const_child_range children() const { + return const_child_range(&HandlerBlock, &HandlerBlock + 1); + } + friend class ASTStmtReader; }; @@ -115,6 +118,10 @@ public: child_range children() { return child_range(getStmts(), getStmts() + getNumHandlers() + 1); } + + const_child_range children() const { + return const_child_range(getStmts(), getStmts() + getNumHandlers() + 1); + } }; /// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for @@ -209,6 +216,10 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[END]); } + + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[END]); + } }; /// Representation of a Microsoft __if_exists or __if_not_exists @@ -291,6 +302,10 @@ public: return child_range(&SubStmt, &SubStmt+1); } + const_child_range children() const { + return const_child_range(&SubStmt, &SubStmt + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == MSDependentExistsStmtClass; } @@ -416,6 +431,12 @@ public: getStoredStmts() + SubStmt::FirstParamMove + NumParams); } + const_child_range children() const { + return const_child_range(getStoredStmts(), getStoredStmts() + + SubStmt::FirstParamMove + + NumParams); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == CoroutineBodyStmtClass; } @@ -480,6 +501,13 @@ public: return child_range(SubStmts, SubStmts + SubStmt::Count); } + const_child_range children() const { + if (!getOperand()) + return const_child_range(SubStmts + SubStmt::PromiseCall, + SubStmts + SubStmt::Count); + return const_child_range(SubStmts, SubStmts + SubStmt::Count); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == CoreturnStmtClass; } diff --git a/include/clang/AST/StmtDataCollectors.td b/include/clang/AST/StmtDataCollectors.td index 90ca08027330..a46d2714eb4b 100644 --- a/include/clang/AST/StmtDataCollectors.td +++ b/include/clang/AST/StmtDataCollectors.td @@ -189,8 +189,8 @@ class CXXFoldExpr { } class GenericSelectionExpr { code Code = [{ - for (unsigned i = 0; i < S->getNumAssocs(); ++i) { - addData(S->getAssocType(i)); + for (const GenericSelectionExpr::ConstAssociation &Assoc : S->associations()) { + addData(Assoc.getType()); } }]; } diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h index 02c77b242c7c..ee1e8cfa1912 100644 --- a/include/clang/AST/StmtGraphTraits.h +++ b/include/clang/AST/StmtGraphTraits.h @@ -1,9 +1,8 @@ //===- StmtGraphTraits.h - Graph Traits for the class Stmt ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h index 806edaa38821..911205347aad 100644 --- a/include/clang/AST/StmtIterator.h +++ b/include/clang/AST/StmtIterator.h @@ -1,9 +1,8 @@ //===- StmtIterator.h - Iterators for Statements ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h index f0c0a9aeb6ac..948ef2421cb9 100644 --- a/include/clang/AST/StmtObjC.h +++ b/include/clang/AST/StmtObjC.h @@ -1,9 +1,8 @@ //===--- StmtObjC.h - Classes for representing ObjC statements --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -68,6 +67,10 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[END_EXPR]); } + + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[END_EXPR]); + } }; /// Represents Objective-C's \@catch statement. @@ -114,6 +117,10 @@ public: } child_range children() { return child_range(&Body, &Body + 1); } + + const_child_range children() const { + return const_child_range(&Body, &Body + 1); + } }; /// Represents Objective-C's \@finally statement @@ -148,6 +155,10 @@ public: child_range children() { return child_range(&AtFinallyStmt, &AtFinallyStmt+1); } + + const_child_range children() const { + return const_child_range(&AtFinallyStmt, &AtFinallyStmt + 1); + } }; /// Represents Objective-C's \@try ... \@catch ... \@finally statement. @@ -249,6 +260,10 @@ public: return child_range(getStmts(), getStmts() + 1 + NumCatchStmts + HasFinally); } + + const_child_range children() const { + return const_child_range(const_cast(this)->children()); + } }; /// Represents Objective-C's \@synchronized statement. @@ -307,6 +322,10 @@ public: child_range children() { return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR); } + + const_child_range children() const { + return const_child_range(&SubStmts[0], &SubStmts[0] + END_EXPR); + } }; /// Represents Objective-C's \@throw statement. @@ -339,6 +358,10 @@ public: } child_range children() { return child_range(&Throw, &Throw+1); } + + const_child_range children() const { + return const_child_range(&Throw, &Throw + 1); + } }; /// Represents Objective-C's \@autoreleasepool Statement @@ -370,6 +393,10 @@ public: } child_range children() { return child_range(&SubStmt, &SubStmt + 1); } + + const_child_range children() const { + return const_child_range(&SubStmt, &SubStmt + 1); + } }; } // end namespace clang diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index d1eedd62b372..e37f5b1e0004 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -1,9 +1,8 @@ //===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file @@ -88,6 +87,63 @@ protected: } public: + /// Iterates over expressions/statements used in the construct. + class used_clauses_child_iterator + : public llvm::iterator_adaptor_base< + used_clauses_child_iterator, ArrayRef::iterator, + std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> { + ArrayRef::iterator End; + OMPClause::child_iterator ChildI, ChildEnd; + + void MoveToNext() { + if (ChildI != ChildEnd) + return; + while (this->I != End) { + ++this->I; + if (this->I != End) { + ChildI = (*this->I)->used_children().begin(); + ChildEnd = (*this->I)->used_children().end(); + if (ChildI != ChildEnd) + return; + } + } + } + + public: + explicit used_clauses_child_iterator(ArrayRef Clauses) + : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()), + End(Clauses.end()) { + if (this->I != End) { + ChildI = (*this->I)->used_children().begin(); + ChildEnd = (*this->I)->used_children().end(); + MoveToNext(); + } + } + Stmt *operator*() const { return *ChildI; } + Stmt *operator->() const { return **this; } + + used_clauses_child_iterator &operator++() { + ++ChildI; + if (ChildI != ChildEnd) + return *this; + if (this->I != End) { + ++this->I; + if (this->I != End) { + ChildI = (*this->I)->used_children().begin(); + ChildEnd = (*this->I)->used_children().end(); + } + } + MoveToNext(); + return *this; + } + }; + + static llvm::iterator_range + used_clauses_children(ArrayRef Clauses) { + return {used_clauses_child_iterator(Clauses), + used_clauses_child_iterator(llvm::makeArrayRef(Clauses.end(), 0))}; + } + /// Iterates over a filtered subrange of clauses applied to a /// directive. /// @@ -257,11 +313,35 @@ public: return child_range(ChildStorage, ChildStorage + 1); } + const_child_range children() const { + if (!hasAssociatedStmt()) + return const_child_range(const_child_iterator(), const_child_iterator()); + Stmt **ChildStorage = reinterpret_cast( + const_cast(this)->getClauses().end()); + return const_child_range(ChildStorage, ChildStorage + 1); + } + ArrayRef clauses() { return getClauses(); } ArrayRef clauses() const { return const_cast(this)->getClauses(); } + + /// Returns whether or not this is a Standalone directive. + /// + /// Stand-alone directives are executable directives + /// that have no associated user code. + bool isStandaloneDirective() const; + + /// Returns the AST node representing OpenMP structured-block of this + /// OpenMP executable directive, + /// Prerequisite: Executable Directive must not be Standalone directive. + const Stmt *getStructuredBlock() const; + + Stmt *getStructuredBlock() { + return const_cast( + const_cast(this)->getStructuredBlock()); + } }; /// This represents '#pragma omp parallel' directive. diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h index ea40e0497307..d3be93d228cc 100644 --- a/include/clang/AST/StmtVisitor.h +++ b/include/clang/AST/StmtVisitor.h @@ -1,9 +1,8 @@ //===- StmtVisitor.h - Visitor for Stmt subclasses --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/TemplateArgumentVisitor.h b/include/clang/AST/TemplateArgumentVisitor.h index e1cc392a1705..190aa97adf45 100644 --- a/include/clang/AST/TemplateArgumentVisitor.h +++ b/include/clang/AST/TemplateArgumentVisitor.h @@ -1,9 +1,8 @@ //===- TemplateArgumentVisitor.h - Visitor for TArg subclasses --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index e3a773b4e490..058a5bc0a067 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -1,9 +1,8 @@ //===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h index 48272597d4d1..4cc6f5e6ce82 100644 --- a/include/clang/AST/TemplateName.h +++ b/include/clang/AST/TemplateName.h @@ -1,9 +1,8 @@ //===- TemplateName.h - C++ Template Name Representation --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -32,6 +31,8 @@ class NamedDecl; class NestedNameSpecifier; enum OverloadedOperatorKind : int; class OverloadedTemplateStorage; +class AssumedTemplateStorage; +class PartialDiagnostic; struct PrintingPolicy; class QualifiedTemplateName; class SubstTemplateTemplateParmPackStorage; @@ -46,6 +47,7 @@ class UncommonTemplateNameStorage { protected: enum Kind { Overloaded, + Assumed, // defined in DeclarationName.h SubstTemplateTemplateParm, SubstTemplateTemplateParmPack }; @@ -78,6 +80,12 @@ public: : nullptr; } + AssumedTemplateStorage *getAsAssumedTemplateName() { + return Bits.Kind == Assumed + ? reinterpret_cast(this) + : nullptr; + } + SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() { return Bits.Kind == SubstTemplateTemplateParm ? reinterpret_cast(this) @@ -194,6 +202,10 @@ public: /// A set of overloaded template declarations. OverloadedTemplate, + /// An unqualified-id that has been assumed to name a function template + /// that will be found by ADL. + AssumedTemplate, + /// A qualified template name, where the qualification is kept /// to describe the source code as written. QualifiedTemplate, @@ -215,6 +227,7 @@ public: TemplateName() = default; explicit TemplateName(TemplateDecl *Template); explicit TemplateName(OverloadedTemplateStorage *Storage); + explicit TemplateName(AssumedTemplateStorage *Storage); explicit TemplateName(SubstTemplateTemplateParmStorage *Storage); explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage); explicit TemplateName(QualifiedTemplateName *Qual); @@ -236,7 +249,7 @@ public: TemplateDecl *getAsTemplateDecl() const; /// Retrieve the underlying, overloaded function template - // declarations that this template name refers to, if known. + /// declarations that this template name refers to, if known. /// /// \returns The set of overloaded function templates that this template /// name refers to, if known. If the template name does not refer to a @@ -244,6 +257,10 @@ public: /// refers to a single template, returns NULL. OverloadedTemplateStorage *getAsOverloadedTemplate() const; + /// Retrieve information on a name that has been assumed to be a + /// template-name in order to permit a call via ADL. + AssumedTemplateStorage *getAsAssumedTemplateName() const; + /// Retrieve the substituted template template parameter, if /// known. /// @@ -320,6 +337,8 @@ public: /// into a diagnostic with <<. const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, TemplateName N); +const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + TemplateName N); /// A structure for storing the information associated with a /// substituted template template parameter. diff --git a/include/clang/AST/TextNodeDumper.h b/include/clang/AST/TextNodeDumper.h index 794066376300..4c2d0710963b 100644 --- a/include/clang/AST/TextNodeDumper.h +++ b/include/clang/AST/TextNodeDumper.h @@ -1,9 +1,8 @@ //===--- TextNodeDumper.h - Printing of AST nodes -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,6 +18,7 @@ #include "clang/AST/AttrVisitor.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/CommentVisitor.h" +#include "clang/AST/DeclVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TemplateArgumentVisitor.h" @@ -129,7 +129,8 @@ class TextNodeDumper public ConstAttrVisitor, public ConstTemplateArgumentVisitor, public ConstStmtVisitor, - public TypeVisitor { + public TypeVisitor, + public ConstDeclVisitor { raw_ostream &OS; const bool ShowColors; @@ -145,6 +146,8 @@ class TextNodeDumper const comments::CommandTraits *Traits; + const ASTContext *Context; + const char *getCommandName(unsigned CommandID); public: @@ -173,6 +176,8 @@ public: void Visit(const BlockDecl::Capture &C); + void Visit(const GenericSelectionExpr::ConstAssociation &A); + void dumpPointer(const void *Ptr); void dumpLocation(SourceLocation Loc); void dumpSourceRange(SourceRange R); @@ -225,6 +230,7 @@ public: void VisitLabelStmt(const LabelStmt *Node); void VisitGotoStmt(const GotoStmt *Node); void VisitCaseStmt(const CaseStmt *Node); + void VisitConstantExpr(const ConstantExpr *Node); void VisitCallExpr(const CallExpr *Node); void VisitCastExpr(const CastExpr *Node); void VisitImplicitCastExpr(const ImplicitCastExpr *Node); @@ -236,6 +242,7 @@ public: void VisitFloatingLiteral(const FloatingLiteral *Node); void VisitStringLiteral(const StringLiteral *Str); void VisitInitListExpr(const InitListExpr *ILE); + void VisitGenericSelectionExpr(const GenericSelectionExpr *E); void VisitUnaryOperator(const UnaryOperator *Node); void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node); void VisitMemberExpr(const MemberExpr *Node); @@ -289,8 +296,58 @@ public: void VisitObjCInterfaceType(const ObjCInterfaceType *T); void VisitPackExpansionType(const PackExpansionType *T); -private: - void dumpCXXTemporary(const CXXTemporary *Temporary); + void VisitLabelDecl(const LabelDecl *D); + void VisitTypedefDecl(const TypedefDecl *D); + void VisitEnumDecl(const EnumDecl *D); + void VisitRecordDecl(const RecordDecl *D); + void VisitEnumConstantDecl(const EnumConstantDecl *D); + void VisitIndirectFieldDecl(const IndirectFieldDecl *D); + void VisitFunctionDecl(const FunctionDecl *D); + void VisitFieldDecl(const FieldDecl *D); + void VisitVarDecl(const VarDecl *D); + void VisitBindingDecl(const BindingDecl *D); + void VisitCapturedDecl(const CapturedDecl *D); + void VisitImportDecl(const ImportDecl *D); + void VisitPragmaCommentDecl(const PragmaCommentDecl *D); + void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D); + void VisitOMPExecutableDirective(const OMPExecutableDirective *D); + void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D); + void VisitOMPRequiresDecl(const OMPRequiresDecl *D); + void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D); + void VisitNamespaceDecl(const NamespaceDecl *D); + void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D); + void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D); + void VisitTypeAliasDecl(const TypeAliasDecl *D); + void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D); + void VisitCXXRecordDecl(const CXXRecordDecl *D); + void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); + void VisitClassTemplateDecl(const ClassTemplateDecl *D); + void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D); + void VisitVarTemplateDecl(const VarTemplateDecl *D); + void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D); + void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); + void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); + void VisitUsingDecl(const UsingDecl *D); + void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D); + void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D); + void VisitUsingShadowDecl(const UsingShadowDecl *D); + void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl *D); + void VisitLinkageSpecDecl(const LinkageSpecDecl *D); + void VisitAccessSpecDecl(const AccessSpecDecl *D); + void VisitFriendDecl(const FriendDecl *D); + void VisitObjCIvarDecl(const ObjCIvarDecl *D); + void VisitObjCMethodDecl(const ObjCMethodDecl *D); + void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D); + void VisitObjCCategoryDecl(const ObjCCategoryDecl *D); + void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D); + void VisitObjCProtocolDecl(const ObjCProtocolDecl *D); + void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D); + void VisitObjCImplementationDecl(const ObjCImplementationDecl *D); + void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D); + void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); + void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); + void VisitBlockDecl(const BlockDecl *D); + void VisitConceptDecl(const ConceptDecl *D); }; } // namespace clang diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index d4c97b1b5efc..584655fe789e 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -1,9 +1,8 @@ //===- Type.h - C Language Family Type Representation -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -95,9 +94,6 @@ namespace llvm { enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; }; - template <> - struct isPodLike { static const bool value = true; }; - } // namespace llvm namespace clang { @@ -321,6 +317,11 @@ public: qs.removeObjCLifetime(); return qs; } + Qualifiers withoutAddressSpace() const { + Qualifiers qs = *this; + qs.removeAddressSpace(); + return qs; + } bool hasObjCLifetime() const { return Mask & LifetimeMask; } ObjCLifetime getObjCLifetime() const { @@ -459,21 +460,25 @@ public: Mask |= qs.Mask; } - /// Returns true if this address space is a superset of the other one. + /// Returns true if address space A is equal to or a superset of B. /// OpenCL v2.0 defines conversion rules (OpenCLC v2.0 s6.5.5) and notion of /// overlapping address spaces. /// CL1.1 or CL1.2: /// every address space is a superset of itself. /// CL2.0 adds: /// __generic is a superset of any address space except for __constant. + static bool isAddressSpaceSupersetOf(LangAS A, LangAS B) { + // Address spaces must match exactly. + return A == B || + // Otherwise in OpenCLC v2.0 s6.5.5: every address space except + // for __constant can be used as __generic. + (A == LangAS::opencl_generic && B != LangAS::opencl_constant); + } + + /// Returns true if the address space in these qualifiers is equal to or + /// a superset of the address space in the argument qualifiers. bool isAddressSpaceSupersetOf(Qualifiers other) const { - return - // Address spaces must match exactly. - getAddressSpace() == other.getAddressSpace() || - // Otherwise in OpenCLC v2.0 s6.5.5: every address space except - // for __constant can be used as __generic. - (getAddressSpace() == LangAS::opencl_generic && - other.getAddressSpace() != LangAS::opencl_constant); + return isAddressSpaceSupersetOf(getAddressSpace(), other.getAddressSpace()); } /// Determines if these qualifiers compatibly include another set. @@ -1153,6 +1158,22 @@ public: return isDestructedTypeImpl(*this); } + /// Check if this is or contains a C union that is non-trivial to + /// default-initialize, which is a union that has a member that is non-trivial + /// to default-initialize. If this returns true, + /// isNonTrivialToPrimitiveDefaultInitialize returns PDIK_Struct. + bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const; + + /// Check if this is or contains a C union that is non-trivial to destruct, + /// which is a union that has a member that is non-trivial to destruct. If + /// this returns true, isDestructedType returns DK_nontrivial_c_struct. + bool hasNonTrivialToPrimitiveDestructCUnion() const; + + /// Check if this is or contains a C union that is non-trivial to copy, which + /// is a union that has a member that is non-trivial to copy. If this returns + /// true, isNonTrivialToPrimitiveCopy returns PCK_Struct. + bool hasNonTrivialToPrimitiveCopyCUnion() const; + /// Determine whether expressions of the given type are forbidden /// from being lvalues in C. /// @@ -1225,6 +1246,11 @@ private: const ASTContext &C); static QualType IgnoreParens(QualType T); static DestructionKind isDestructedTypeImpl(QualType type); + + /// Check if \param RD is or contains a non-trivial C union. + static bool hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD); + static bool hasNonTrivialToPrimitiveDestructCUnion(const RecordDecl *RD); + static bool hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD); }; } // namespace clang @@ -1404,7 +1430,7 @@ enum class AutoTypeKeyword { /// /// Types, once created, are immutable. /// -class Type : public ExtQualsTypeCommonBase { +class alignas(8) Type : public ExtQualsTypeCommonBase { public: enum TypeClass { #define TYPE(Class, Base) Class, @@ -1806,7 +1832,9 @@ public: friend class ASTWriter; Type(const Type &) = delete; + Type(Type &&) = delete; Type &operator=(const Type &) = delete; + Type &operator=(Type &&) = delete; TypeClass getTypeClass() const { return static_cast(TypeBits.TC); } @@ -1953,6 +1981,7 @@ public: bool isLValueReferenceType() const; bool isRValueReferenceType() const; bool isFunctionPointerType() const; + bool isFunctionReferenceType() const; bool isMemberPointerType() const; bool isMemberFunctionPointerType() const; bool isMemberDataPointerType() const; @@ -1986,7 +2015,7 @@ public: bool isObjCQualifiedClassType() const; // Class bool isObjCObjectOrInterfaceType() const; bool isObjCIdType() const; // id - + bool isDecltypeType() const; /// Was this type written with the special inert-in-ARC __unsafe_unretained /// qualifier? /// @@ -2269,6 +2298,9 @@ public: /// ISO/IEC JTC1 SC22 WG14 N1169. bool isFixedPointType() const; + /// Return true if this is a fixed point or integer type. + bool isFixedPointOrIntegerType() const; + /// Return true if this is a saturated fixed point type according to /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. bool isSaturatedFixedPointType() const; @@ -3843,6 +3875,7 @@ private: case EST_MSAny: case EST_BasicNoexcept: case EST_Unparsed: + case EST_NoThrow: return {0, 0, 0}; case EST_Dynamic: @@ -3902,7 +3935,7 @@ public: EPI.Variadic = isVariadic(); EPI.HasTrailingReturn = hasTrailingReturn(); EPI.ExceptionSpec.Type = getExceptionSpecType(); - EPI.TypeQuals = getTypeQuals(); + EPI.TypeQuals = getMethodQuals(); EPI.RefQualifier = getRefQualifier(); if (EPI.ExceptionSpec.Type == EST_Dynamic) { EPI.ExceptionSpec.Exceptions = exceptions(); @@ -4012,7 +4045,7 @@ public: /// Whether this function prototype has a trailing return type. bool hasTrailingReturn() const { return FunctionTypeBits.HasTrailingReturn; } - Qualifiers getTypeQuals() const { + Qualifiers getMethodQuals() const { if (hasExtQualifiers()) return *getTrailingObjects(); else @@ -4172,6 +4205,41 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } }; +/// Sugar type that represents a type that was qualified by a qualifier written +/// as a macro invocation. +class MacroQualifiedType : public Type { + friend class ASTContext; // ASTContext creates these. + + QualType UnderlyingTy; + const IdentifierInfo *MacroII; + + MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy, + const IdentifierInfo *MacroII) + : Type(MacroQualified, CanonTy, UnderlyingTy->isDependentType(), + UnderlyingTy->isInstantiationDependentType(), + UnderlyingTy->isVariablyModifiedType(), + UnderlyingTy->containsUnexpandedParameterPack()), + UnderlyingTy(UnderlyingTy), MacroII(MacroII) { + assert(isa(UnderlyingTy) && + "Expected a macro qualified type to only wrap attributed types."); + } + +public: + const IdentifierInfo *getMacroIdentifier() const { return MacroII; } + QualType getUnderlyingType() const { return UnderlyingTy; } + + /// Return this attributed type's modified type with no qualifiers attached to + /// it. + QualType getModifiedType() const; + + bool isSugared() const { return true; } + QualType desugar() const; + + static bool classof(const Type *T) { + return T->getTypeClass() == MacroQualified; + } +}; + /// Represents a `typeof` (or __typeof__) expression (a GCC extension). class TypeOfExprType : public Type { Expr *TOExpr; @@ -4750,9 +4818,9 @@ class AutoType : public DeducedType, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, - bool IsDeducedAsDependent) + bool IsDeducedAsDependent, bool IsDeducedAsPack) : DeducedType(Auto, DeducedAsType, IsDeducedAsDependent, - IsDeducedAsDependent, /*ContainsPack=*/false) { + IsDeducedAsDependent, IsDeducedAsPack) { AutoTypeBits.Keyword = (unsigned)Keyword; } @@ -4766,14 +4834,16 @@ public: } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getDeducedType(), getKeyword(), isDependentType()); + Profile(ID, getDeducedType(), getKeyword(), isDependentType(), + containsUnexpandedParameterPack()); } static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced, - AutoTypeKeyword Keyword, bool IsDependent) { + AutoTypeKeyword Keyword, bool IsDependent, bool IsPack) { ID.AddPointer(Deduced.getAsOpaquePtr()); ID.AddInteger((unsigned)Keyword); ID.AddBoolean(IsDependent); + ID.AddBoolean(IsPack); } static bool classof(const Type *T) { @@ -6194,6 +6264,24 @@ inline Qualifiers::GC QualType::getObjCGCAttr() const { return getQualifiers().getObjCGCAttr(); } +inline bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion() const { + if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) + return hasNonTrivialToPrimitiveDefaultInitializeCUnion(RD); + return false; +} + +inline bool QualType::hasNonTrivialToPrimitiveDestructCUnion() const { + if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) + return hasNonTrivialToPrimitiveDestructCUnion(RD); + return false; +} + +inline bool QualType::hasNonTrivialToPrimitiveCopyCUnion() const { + if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) + return hasNonTrivialToPrimitiveCopyCUnion(RD); + return false; +} + inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) { if (const auto *PT = t.getAs()) { if (const auto *FT = PT->getPointeeType()->getAs()) @@ -6324,6 +6412,13 @@ inline bool Type::isFunctionPointerType() const { return false; } +inline bool Type::isFunctionReferenceType() const { + if (const auto *T = getAs()) + return T->getPointeeType()->isFunctionType(); + else + return false; +} + inline bool Type::isMemberPointerType() const { return isa(CanonicalType); } @@ -6441,6 +6536,10 @@ inline bool Type::isObjCBuiltinType() const { return isObjCIdType() || isObjCClassType() || isObjCSelType(); } +inline bool Type::isDecltypeType() const { + return isa(this); +} + #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ inline bool Type::is##Id##Type() const { \ return isSpecificBuiltinType(BuiltinType::Id); \ @@ -6596,6 +6695,10 @@ inline bool Type::isFixedPointType() const { return false; } +inline bool Type::isFixedPointOrIntegerType() const { + return isFixedPointType() || isIntegerType(); +} + inline bool Type::isSaturatedFixedPointType() const { if (const auto *BT = dyn_cast(CanonicalType)) { return BT->getKind() >= BuiltinType::SatShortAccum && @@ -6785,6 +6888,8 @@ template const T *Type::getAsAdjusted() const { Ty = P->desugar().getTypePtr(); else if (const auto *A = dyn_cast(Ty)) Ty = A->desugar().getTypePtr(); + else if (const auto *M = dyn_cast(Ty)) + Ty = M->desugar().getTypePtr(); else break; } @@ -6841,6 +6946,8 @@ QualType DecayedType::getPointeeType() const { // Get the decimal string representation of a fixed point type, represented // as a scaled integer. +// TODO: At some point, we should change the arguments to instead just accept an +// APFixedPoint instead of APSInt and scale. void FixedPointValueToString(SmallVectorImpl &Str, llvm::APSInt Val, unsigned Scale); diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 1e89e9386719..40d17f991f1f 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -1,9 +1,8 @@ //===- TypeLoc.h - Type Source Info Wrapper ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -174,6 +173,9 @@ public: TypeLoc IgnoreParens() const; + /// Strips MacroDefinitionTypeLocs from a type location. + TypeLoc IgnoreMacroDefinitions() const; + /// Find a type with the location of an explicit type qualifier. /// /// The result, if non-null, will be one of: @@ -1081,6 +1083,39 @@ public: } }; +struct MacroQualifiedLocInfo { + SourceLocation ExpansionLoc; +}; + +class MacroQualifiedTypeLoc + : public ConcreteTypeLoc { +public: + void initializeLocal(ASTContext &Context, SourceLocation Loc) { + setExpansionLoc(Loc); + } + + TypeLoc getInnerLoc() const { return getInnerTypeLoc(); } + + const IdentifierInfo *getMacroIdentifier() const { + return getTypePtr()->getMacroIdentifier(); + } + + SourceLocation getExpansionLoc() const { + return this->getLocalData()->ExpansionLoc; + } + + void setExpansionLoc(SourceLocation Loc) { + this->getLocalData()->ExpansionLoc = Loc; + } + + QualType getInnerType() const { return getTypePtr()->getUnderlyingType(); } + + SourceRange getLocalSourceRange() const { + return getInnerLoc().getLocalSourceRange(); + } +}; + struct ParenLocInfo { SourceLocation LParenLoc; SourceLocation RParenLoc; @@ -2290,6 +2325,8 @@ inline T TypeLoc::getAsAdjusted() const { Cur = ETL.getNamedTypeLoc(); else if (auto ATL = Cur.getAs()) Cur = ATL.getOriginalLoc(); + else if (auto MQL = Cur.getAs()) + Cur = MQL.getInnerLoc(); else break; } diff --git a/include/clang/AST/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def index 4590e489e3f7..c0dfe150d6cc 100644 --- a/include/clang/AST/TypeLocNodes.def +++ b/include/clang/AST/TypeLocNodes.def @@ -1,9 +1,8 @@ //===-- TypeLocNodes.def - Metadata about TypeLoc wrappers ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h index db5775aa146e..ec780884e96c 100644 --- a/include/clang/AST/TypeLocVisitor.h +++ b/include/clang/AST/TypeLocVisitor.h @@ -1,9 +1,8 @@ //===--- TypeLocVisitor.h - Visitor for TypeLoc subclasses ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def index 8638f94bda14..58a5f880cbe6 100644 --- a/include/clang/AST/TypeNodes.def +++ b/include/clang/AST/TypeNodes.def @@ -1,9 +1,8 @@ //===-- TypeNodes.def - Metadata about Type AST nodes -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -83,6 +82,7 @@ TYPE(FunctionNoProto, FunctionType) DEPENDENT_TYPE(UnresolvedUsing, Type) NON_CANONICAL_TYPE(Paren, Type) NON_CANONICAL_TYPE(Typedef, Type) +NON_CANONICAL_TYPE(MacroQualified, Type) NON_CANONICAL_TYPE(Adjusted, Type) NON_CANONICAL_TYPE(Decayed, AdjustedType) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type) diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h index 7ea78071f5cf..6630105136f5 100644 --- a/include/clang/AST/TypeOrdering.h +++ b/include/clang/AST/TypeOrdering.h @@ -1,9 +1,8 @@ //===-------------- TypeOrdering.h - Total ordering for types ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h index 75fa0ec15ce2..8930ec853949 100644 --- a/include/clang/AST/TypeVisitor.h +++ b/include/clang/AST/TypeVisitor.h @@ -1,9 +1,8 @@ //===--- TypeVisitor.h - Visitor for Type subclasses ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h index b62e9f138bb6..cfc0b87eec7e 100644 --- a/include/clang/AST/UnresolvedSet.h +++ b/include/clang/AST/UnresolvedSet.h @@ -1,9 +1,8 @@ //===- UnresolvedSet.h - Unresolved sets of declarations --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/VTTBuilder.h b/include/clang/AST/VTTBuilder.h index 3a8a6a9c15f0..4acbc1f9e96b 100644 --- a/include/clang/AST/VTTBuilder.h +++ b/include/clang/AST/VTTBuilder.h @@ -1,9 +1,8 @@ //===- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h index 4a779db01ff8..43c84292c091 100644 --- a/include/clang/AST/VTableBuilder.h +++ b/include/clang/AST/VTableBuilder.h @@ -1,9 +1,8 @@ //===--- VTableBuilder.h - C++ vtable layout builder --------------*- C++ -*-=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h index 324c02db3fe0..4c8dd87cecbb 100644 --- a/include/clang/ASTMatchers/ASTMatchFinder.h +++ b/include/clang/ASTMatchers/ASTMatchFinder.h @@ -1,9 +1,8 @@ //===--- ASTMatchFinder.h - Structural query framework ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 5cdb964a92c2..063d8217d9aa 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -1,9 +1,8 @@ //===- ASTMatchers.h - Structural query framework ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -57,10 +56,12 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/OpenMPClause.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" +#include "clang/AST/StmtOpenMP.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -1137,6 +1138,17 @@ extern const internal::VariadicDynCastAllOfMatcher extern const internal::VariadicDynCastAllOfMatcher cxxConversionDecl; +/// Matches user-defined and implicitly generated deduction guide. +/// +/// Example matches the deduction guide. +/// \code +/// template +/// class X { X(int) }; +/// X(int) -> X; +/// \endcode +extern const internal::VariadicDynCastAllOfMatcher + cxxDeductionGuideDecl; + /// Matches variable declarations. /// /// Note: this does not match declarations of member variables, which are @@ -2159,6 +2171,10 @@ extern const internal::VariadicDynCastAllOfMatcher extern const internal::VariadicDynCastAllOfMatcher cxxNullPtrLiteralExpr; +/// Matches GNU __builtin_choose_expr. +extern const internal::VariadicDynCastAllOfMatcher + chooseExpr; + /// Matches GNU __null expression. extern const internal::VariadicDynCastAllOfMatcher gnuNullExpr; @@ -2487,6 +2503,9 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType, /// \endcode /// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf)) /// matches \c sizeof(x) +/// +/// If the matcher is use from clang-query, UnaryExprOrTypeTrait parameter +/// should be passed as a quoted string. e.g., ofKind("UETT_SizeOf"). AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) { return Node.getKind() == Kind; } @@ -2887,14 +2906,22 @@ AST_MATCHER_P(NamedDecl, hasUnderlyingDecl, internal::Matcher, InnerMatcher.matches(*UnderlyingDecl, Finder, Builder); } -/// Matches on the implicit object argument of a member call expression. +/// Matches on the implicit object argument of a member call expression, after +/// stripping off any parentheses or implicit casts. /// -/// Example matches y.x() -/// (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))))) +/// Given /// \code -/// class Y { public: void x(); }; -/// void z() { Y y; y.x(); } +/// class Y { public: void m(); }; +/// Y g(); +/// class X : public Y {}; +/// void z(Y y, X x) { y.m(); (g()).m(); x.m(); } /// \endcode +/// cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y"))))) +/// matches `y.m()` and `(g()).m()`. +/// cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X"))))) +/// matches `x.m()`. +/// cxxMemberCallExpr(on(callExpr())) +/// matches `(g()).m()`. /// /// FIXME: Overload to allow directly matching types? AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher, @@ -2922,10 +2949,59 @@ AST_MATCHER_P(ObjCMessageExpr, hasReceiverType, internal::Matcher, return InnerMatcher.matches(TypeDecl, Finder, Builder); } +/// Returns true when the Objective-C method declaration is a class method. +/// +/// Example +/// matcher = objcMethodDecl(isClassMethod()) +/// matches +/// \code +/// @interface I + (void)foo; @end +/// \endcode +/// but not +/// \code +/// @interface I - (void)bar; @end +/// \endcode +AST_MATCHER(ObjCMethodDecl, isClassMethod) { + return Node.isClassMethod(); +} + +/// Returns true when the Objective-C method declaration is an instance method. +/// +/// Example +/// matcher = objcMethodDecl(isInstanceMethod()) +/// matches +/// \code +/// @interface I - (void)bar; @end +/// \endcode +/// but not +/// \code +/// @interface I + (void)foo; @end +/// \endcode +AST_MATCHER(ObjCMethodDecl, isInstanceMethod) { + return Node.isInstanceMethod(); +} + +/// Returns true when the Objective-C message is sent to a class. +/// +/// Example +/// matcher = objcMessageExpr(isClassMessage()) +/// matches +/// \code +/// [NSString stringWithFormat:@"format"]; +/// \endcode +/// but not +/// \code +/// NSString *x = @"hello"; +/// [x containsString:@"h"]; +/// \endcode +AST_MATCHER(ObjCMessageExpr, isClassMessage) { + return Node.isClassMessage(); +} + /// Returns true when the Objective-C message is sent to an instance. /// /// Example -/// matcher = objcMessagaeExpr(isInstanceMessage()) +/// matcher = objcMessageExpr(isInstanceMessage()) /// matches /// \code /// NSString *x = @"hello"; @@ -3254,6 +3330,23 @@ AST_MATCHER_P_OVERLOAD(QualType, references, internal::Matcher, .matches(Node, Finder, Builder); } +/// Matches on the implicit object argument of a member call expression. Unlike +/// `on`, matches the argument directly without stripping away anything. +/// +/// Given +/// \code +/// class Y { public: void m(); }; +/// Y g(); +/// class X : public Y { void g(); }; +/// void z(Y y, X x) { y.m(); x.m(); x.g(); (g()).m(); } +/// \endcode +/// cxxMemberCallExpr(onImplicitObjectArgument(hasType( +/// cxxRecordDecl(hasName("Y"))))) +/// matches `y.m()`, `x.m()` and (g()).m(), but not `x.g()`. +/// cxxMemberCallExpr(on(callExpr())) +/// does not match `(g()).m()`, because the parens are not ignored. +/// +/// FIXME: Overload to allow directly matching types? AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument, internal::Matcher, InnerMatcher) { const Expr *ExprNode = Node.getImplicitObjectArgument(); @@ -3261,8 +3354,22 @@ AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument, InnerMatcher.matches(*ExprNode, Finder, Builder)); } -/// Matches if the expression's type either matches the specified -/// matcher, or is a pointer to a type that matches the InnerMatcher. +/// Matches if the type of the expression's implicit object argument either +/// matches the InnerMatcher, or is a pointer to a type that matches the +/// InnerMatcher. +/// +/// Given +/// \code +/// class Y { public: void m(); }; +/// class X : public Y { void g(); }; +/// void z() { Y y; y.m(); Y *p; p->m(); X x; x.m(); x.g(); } +/// \endcode +/// cxxMemberCallExpr(thisPointerType(hasDeclaration( +/// cxxRecordDecl(hasName("Y"))))) +/// matches `y.m()`, `p->m()` and `x.m()`. +/// cxxMemberCallExpr(thisPointerType(hasDeclaration( +/// cxxRecordDecl(hasName("X"))))) +/// matches `x.g()`. AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, internal::Matcher, InnerMatcher, 0) { return onImplicitObjectArgument( @@ -4439,6 +4546,9 @@ AST_POLYMORPHIC_MATCHER_P(hasSourceExpression, /// \code /// int *p = 0; /// \endcode +/// +/// If the matcher is use from clang-query, CastKind parameter +/// should be passed as a quoted string. e.g., ofKind("CK_NullToPointer"). AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) { return Node.getCastKind() == Kind; } @@ -4964,18 +5074,22 @@ AST_MATCHER_P(MemberExpr, member, return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder); } -/// Matches a member expression where the object expression is -/// matched by a given matcher. +/// Matches a member expression where the object expression is matched by a +/// given matcher. Implicit object expressions are included; that is, it matches +/// use of implicit `this`. /// /// Given /// \code -/// struct X { int m; }; -/// void f(X x) { x.m; m; } +/// struct X { +/// int m; +/// int f(X x) { x.m; return m; } +/// }; /// \endcode -/// memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X"))))))) -/// matches "x.m" and "m" -/// with hasObjectExpression(...) -/// matching "x" and the implicit object expression of "m" which has type X*. +/// memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X"))))) +/// matches `x.m`, but not `m`; however, +/// memberExpr(hasObjectExpression(hasType(pointsTo( +// cxxRecordDecl(hasName("X")))))) +/// matches `m` (aka. `this->m`), but not `x.m`. AST_POLYMORPHIC_MATCHER_P( hasObjectExpression, AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr, @@ -6051,26 +6165,63 @@ AST_MATCHER(CXXConstructorDecl, isDelegatingConstructor) { return Node.isDelegatingConstructor(); } -/// Matches constructor and conversion declarations that are marked with -/// the explicit keyword. +/// Matches constructor, conversion function, and deduction guide declarations +/// that have an explicit specifier if this explicit specifier is resolved to +/// true. /// /// Given /// \code +/// template /// struct S { /// S(int); // #1 /// explicit S(double); // #2 /// operator int(); // #3 /// explicit operator bool(); // #4 +/// explicit(false) S(bool) // # 7 +/// explicit(true) S(char) // # 8 +/// explicit(b) S(S) // # 9 /// }; +/// S(int) -> S // #5 +/// explicit S(double) -> S // #6 /// \endcode -/// cxxConstructorDecl(isExplicit()) will match #2, but not #1. +/// cxxConstructorDecl(isExplicit()) will match #2 and #8, but not #1, #7 or #9. /// cxxConversionDecl(isExplicit()) will match #4, but not #3. -AST_POLYMORPHIC_MATCHER(isExplicit, - AST_POLYMORPHIC_SUPPORTED_TYPES(CXXConstructorDecl, - CXXConversionDecl)) { +/// cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5. +AST_POLYMORPHIC_MATCHER(isExplicit, AST_POLYMORPHIC_SUPPORTED_TYPES( + CXXConstructorDecl, CXXConversionDecl, + CXXDeductionGuideDecl)) { return Node.isExplicit(); } +/// Matches the expression in an explicit specifier if present in the given +/// declaration. +/// +/// Given +/// \code +/// template +/// struct S { +/// S(int); // #1 +/// explicit S(double); // #2 +/// operator int(); // #3 +/// explicit operator bool(); // #4 +/// explicit(false) S(bool) // # 7 +/// explicit(true) S(char) // # 8 +/// explicit(b) S(S) // # 9 +/// }; +/// S(int) -> S // #5 +/// explicit S(double) -> S // #6 +/// \endcode +/// cxxConstructorDecl(hasExplicitSpecifier(constantExpr())) will match #7, #8 and #9, but not #1 or #2. +/// cxxConversionDecl(hasExplicitSpecifier(constantExpr())) will not match #3 or #4. +/// cxxDeductionGuideDecl(hasExplicitSpecifier(constantExpr())) will not match #5 or #6. +AST_MATCHER_P(FunctionDecl, hasExplicitSpecifier, internal::Matcher, + InnerMatcher) { + ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(&Node); + if (!ES.getExpr()) + return false; + return InnerMatcher.matches(*ES.getExpr(), Finder, Builder); +} + /// Matches function and namespace declarations that are marked with /// the inline keyword. /// @@ -6109,6 +6260,29 @@ AST_MATCHER(NamespaceDecl, isAnonymous) { return Node.isAnonymousNamespace(); } +/// Matches declarations in the namespace `std`, but not in nested namespaces. +/// +/// Given +/// \code +/// class vector {}; +/// namespace foo { +/// class vector {}; +/// namespace std { +/// class vector {}; +/// } +/// } +/// namespace std { +/// inline namespace __1 { +/// class vector {}; // #1 +/// namespace experimental { +/// class vector {}; +/// } +/// } +/// } +/// \endcode +/// cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1. +AST_MATCHER(Decl, isInStdNamespace) { return Node.isInStdNamespace(); } + /// If the given case statement does not use the GNU case range /// extension, matches the constant given in the statement. /// @@ -6133,7 +6307,7 @@ AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher, /// __attribute__((device)) void f() { ... } /// \endcode /// decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of -/// f. If the matcher is use from clang-query, attr::Kind parameter should be +/// f. If the matcher is used from clang-query, attr::Kind parameter should be /// passed as a quoted string. e.g., hasAttr("attr::CUDADevice"). AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) { for (const auto *Attr : Node.attrs()) { @@ -6284,8 +6458,8 @@ AST_MATCHER(CXXNewExpr, isArray) { /// cxxNewExpr(hasArraySize(intgerLiteral(equals(10)))) /// matches the expression 'new MyClass[10]'. AST_MATCHER_P(CXXNewExpr, hasArraySize, internal::Matcher, InnerMatcher) { - return Node.isArray() && - InnerMatcher.matches(*Node.getArraySize(), Finder, Builder); + return Node.isArray() && *Node.getArraySize() && + InnerMatcher.matches(**Node.getArraySize(), Finder, Builder); } /// Matches a class declaration that is defined. @@ -6323,6 +6497,203 @@ AST_MATCHER(FunctionDecl, hasTrailingReturn) { return false; } +/// Matches expressions that match InnerMatcher that are possibly wrapped in an +/// elidable constructor. +/// +/// In C++17 copy elidable constructors are no longer being +/// generated in the AST as it is not permitted by the standard. They are +/// however part of the AST in C++14 and earlier. Therefore, to write a matcher +/// that works in all language modes, the matcher has to skip elidable +/// constructor AST nodes if they appear in the AST. This matcher can be used to +/// skip those elidable constructors. +/// +/// Given +/// +/// \code +/// struct H {}; +/// H G(); +/// void f() { +/// H D = G(); +/// } +/// \endcode +/// +/// ``varDecl(hasInitializer(any( +/// ignoringElidableConstructorCall(callExpr()), +/// exprWithCleanups(ignoringElidableConstructorCall(callExpr()))))`` +/// matches ``H D = G()`` +AST_MATCHER_P(Expr, ignoringElidableConstructorCall, + ast_matchers::internal::Matcher, InnerMatcher) { + if (const auto *CtorExpr = dyn_cast(&Node)) { + if (CtorExpr->isElidable()) { + if (const auto *MaterializeTemp = + dyn_cast(CtorExpr->getArg(0))) { + return InnerMatcher.matches(*MaterializeTemp->GetTemporaryExpr(), + Finder, Builder); + } + } + } + return InnerMatcher.matches(Node, Finder, Builder); +} + +//----------------------------------------------------------------------------// +// OpenMP handling. +//----------------------------------------------------------------------------// + +/// Matches any ``#pragma omp`` executable directive. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// #pragma omp taskyield +/// \endcode +/// +/// ``ompExecutableDirective()`` matches ``omp parallel``, +/// ``omp parallel default(none)`` and ``omp taskyield``. +extern const internal::VariadicDynCastAllOfMatcher + ompExecutableDirective; + +/// Matches standalone OpenMP directives, +/// i.e., directives that can't have a structured block. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// {} +/// #pragma omp taskyield +/// \endcode +/// +/// ``ompExecutableDirective(isStandaloneDirective()))`` matches +/// ``omp taskyield``. +AST_MATCHER(OMPExecutableDirective, isStandaloneDirective) { + return Node.isStandaloneDirective(); +} + +/// Matches the Stmt AST node that is marked as being the structured-block +/// of an OpenMP executable directive. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// {} +/// \endcode +/// +/// ``stmt(isOMPStructuredBlock()))`` matches ``{}``. +AST_MATCHER(Stmt, isOMPStructuredBlock) { return Node.isOMPStructuredBlock(); } + +/// Matches the structured-block of the OpenMP executable directive +/// +/// Prerequisite: the executable directive must not be standalone directive. +/// If it is, it will never match. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// ; +/// #pragma omp parallel +/// {} +/// \endcode +/// +/// ``ompExecutableDirective(hasStructuredBlock(nullStmt()))`` will match ``;`` +AST_MATCHER_P(OMPExecutableDirective, hasStructuredBlock, + internal::Matcher, InnerMatcher) { + if (Node.isStandaloneDirective()) + return false; // Standalone directives have no structured blocks. + return InnerMatcher.matches(*Node.getStructuredBlock(), Finder, Builder); +} + +/// Matches any clause in an OpenMP directive. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// \endcode +/// +/// ``ompExecutableDirective(hasAnyClause(anything()))`` matches +/// ``omp parallel default(none)``. +AST_MATCHER_P(OMPExecutableDirective, hasAnyClause, + internal::Matcher, InnerMatcher) { + ArrayRef Clauses = Node.clauses(); + return matchesFirstInPointerRange(InnerMatcher, Clauses.begin(), + Clauses.end(), Finder, Builder); +} + +/// Matches OpenMP ``default`` clause. +/// +/// Given +/// +/// \code +/// #pragma omp parallel default(none) +/// #pragma omp parallel default(shared) +/// #pragma omp parallel +/// \endcode +/// +/// ``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``. +extern const internal::VariadicDynCastAllOfMatcher + ompDefaultClause; + +/// Matches if the OpenMP ``default`` clause has ``none`` kind specified. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// #pragma omp parallel default(shared) +/// \endcode +/// +/// ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``. +AST_MATCHER(OMPDefaultClause, isNoneKind) { + return Node.getDefaultKind() == OMPC_DEFAULT_none; +} + +/// Matches if the OpenMP ``default`` clause has ``shared`` kind specified. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// #pragma omp parallel default(shared) +/// \endcode +/// +/// ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``. +AST_MATCHER(OMPDefaultClause, isSharedKind) { + return Node.getDefaultKind() == OMPC_DEFAULT_shared; +} + +/// Matches if the OpenMP directive is allowed to contain the specified OpenMP +/// clause kind. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel for +/// #pragma omp for +/// \endcode +/// +/// `ompExecutableDirective(isAllowedToContainClause(OMPC_default))`` matches +/// ``omp parallel`` and ``omp parallel for``. +/// +/// If the matcher is use from clang-query, ``OpenMPClauseKind`` parameter +/// should be passed as a quoted string. e.g., +/// ``isAllowedToContainClauseKind("OMPC_default").`` +AST_MATCHER_P(OMPExecutableDirective, isAllowedToContainClauseKind, + OpenMPClauseKind, CKind) { + return isAllowedClauseForDirective(Node.getDirectiveKind(), CKind); +} + +//----------------------------------------------------------------------------// +// End OpenMP handling. +//----------------------------------------------------------------------------// + } // namespace ast_matchers } // namespace clang diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h index 34851a907e0d..b1bb0bfa3218 100644 --- a/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -1,9 +1,8 @@ //===- ASTMatchersInternal.h - Structural query framework -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -951,15 +950,6 @@ const bool IsBaseType::value; /// all nodes, as all nodes have ancestors. class ASTMatchFinder { public: - /// Defines how we descend a level in the AST when we pass - /// through expressions. - enum TraversalKind { - /// Will traverse any child nodes. - TK_AsIs, - - /// Will not traverse implicit casts and parentheses. - TK_IgnoreImplicitCastsAndParentheses - }; /// Defines how bindings are processed on recursive matches. enum BindKind { @@ -990,11 +980,9 @@ public: BoundNodesTreeBuilder *Builder) = 0; template - bool matchesChildOf(const T &Node, - const DynTypedMatcher &Matcher, + bool matchesChildOf(const T &Node, const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, - TraversalKind Traverse, - BindKind Bind) { + ast_type_traits::TraversalKind Traverse, BindKind Bind) { static_assert(std::is_base_of::value || std::is_base_of::value || std::is_base_of::value || @@ -1043,7 +1031,7 @@ protected: virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node, const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, - TraversalKind Traverse, + ast_type_traits::TraversalKind Traverse, BindKind Bind) = 0; virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node, @@ -1291,7 +1279,7 @@ public: bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { return Finder->matchesChildOf(Node, this->InnerMatcher, Builder, - ASTMatchFinder::TK_AsIs, + ast_type_traits::TraversalKind::TK_AsIs, ASTMatchFinder::BK_First); } }; @@ -1314,7 +1302,7 @@ class ForEachMatcher : public WrapperMatcherInterface { BoundNodesTreeBuilder* Builder) const override { return Finder->matchesChildOf( Node, this->InnerMatcher, Builder, - ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, + ast_type_traits::TraversalKind::TK_IgnoreImplicitCastsAndParentheses, ASTMatchFinder::BK_All); } }; @@ -1548,8 +1536,7 @@ inline bool ValueEqualsMatcher::matchesNode( /// given matchers, if SourceT can be dynamically casted into TargetT. /// /// For example: -/// const VariadicDynCastAllOfMatcher< -/// Decl, CXXRecordDecl> record; +/// const VariadicDynCastAllOfMatcher record; /// Creates a functor record(...) that creates a Matcher given /// a variable number of arguments of type Matcher. /// The returned matcher matches if the given Decl can by dynamically diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h index 3080f86699b5..1d96ba6231cf 100644 --- a/include/clang/ASTMatchers/ASTMatchersMacros.h +++ b/include/clang/ASTMatchers/ASTMatchersMacros.h @@ -1,9 +1,8 @@ //===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/include/clang/ASTMatchers/Dynamic/Diagnostics.h index ccd9590f4bb4..7dd304797c4f 100644 --- a/include/clang/ASTMatchers/Dynamic/Diagnostics.h +++ b/include/clang/ASTMatchers/Dynamic/Diagnostics.h @@ -1,9 +1,8 @@ //===--- Diagnostics.h - Helper class for error diagnostics -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h index 136265d32847..15e0aa7ecd27 100644 --- a/include/clang/ASTMatchers/Dynamic/Parser.h +++ b/include/clang/ASTMatchers/Dynamic/Parser.h @@ -1,9 +1,8 @@ //===- Parser.h - Matcher expression parser ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h index ad8628b4b0d9..215206b2f50c 100644 --- a/include/clang/ASTMatchers/Dynamic/Registry.h +++ b/include/clang/ASTMatchers/Dynamic/Registry.h @@ -1,9 +1,8 @@ //===- Registry.h - Matcher registry ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h index 45ac3cadf685..511472a4157c 100644 --- a/include/clang/ASTMatchers/Dynamic/VariantValue.h +++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h @@ -1,8 +1,7 @@ //===--- VariantValue.h - Polymorphic value type -*- C++ -*-===/ -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h index 49da6815ace9..16c0a7af0504 100644 --- a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h +++ b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h @@ -1,9 +1,8 @@ //===- CFGReachabilityAnalysis.h - Basic reachability analysis --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h index 5a70989e5087..dec1ae3b2b4b 100644 --- a/include/clang/Analysis/Analyses/Consumed.h +++ b/include/clang/Analysis/Analyses/Consumed.h @@ -1,9 +1,8 @@ //===- Consumed.h -----------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h index 021e98dcd885..061c98137da2 100644 --- a/include/clang/Analysis/Analyses/Dominators.h +++ b/include/clang/Analysis/Analyses/Dominators.h @@ -1,9 +1,8 @@ //- Dominators.h - Implementation of dominators tree for Clang CFG -*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,6 +18,7 @@ #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/iterator.h" +#include "llvm/Support/GenericIteratedDominanceFrontier.h" #include "llvm/Support/GenericDomTree.h" #include "llvm/Support/GenericDomTreeConstruction.h" #include "llvm/Support/raw_ostream.h" @@ -37,132 +37,319 @@ namespace clang { using DomTreeNode = llvm::DomTreeNodeBase; -/// Concrete subclass of DominatorTreeBase for Clang -/// This class implements the dominators tree functionality given a Clang CFG. -/// -class DominatorTree : public ManagedAnalysis { +/// Dominator tree builder for Clang's CFG based on llvm::DominatorTreeBase. +template +class CFGDominatorTreeImpl : public ManagedAnalysis { virtual void anchor(); public: - llvm::DomTreeBase *DT; + using DominatorTreeBase = llvm::DominatorTreeBase; - DominatorTree() { - DT = new llvm::DomTreeBase(); + CFGDominatorTreeImpl() = default; + + CFGDominatorTreeImpl(CFG *cfg) { + buildDominatorTree(cfg); } - ~DominatorTree() override { delete DT; } + ~CFGDominatorTreeImpl() override = default; - llvm::DomTreeBase& getBase() { return *DT; } + DominatorTreeBase &getBase() { return DT; } - /// This method returns the root CFGBlock of the dominators tree. + CFG *getCFG() { return cfg; } + + /// \returns the root CFGBlock of the dominators tree. CFGBlock *getRoot() const { - return DT->getRoot(); + return DT.getRoot(); } - /// This method returns the root DomTreeNode, which is the wrapper - /// for CFGBlock. - DomTreeNode *getRootNode() const { - return DT->getRootNode(); + /// \returns the root DomTreeNode, which is the wrapper for CFGBlock. + DomTreeNode *getRootNode() { + return DT.getRootNode(); } - /// This method compares two dominator trees. - /// The method returns false if the other dominator tree matches this - /// dominator tree, otherwise returns true. - bool compare(DominatorTree &Other) const { + /// Compares two dominator trees. + /// \returns false if the other dominator tree matches this dominator tree, + /// false otherwise. + bool compare(CFGDominatorTreeImpl &Other) const { DomTreeNode *R = getRootNode(); DomTreeNode *OtherR = Other.getRootNode(); if (!R || !OtherR || R->getBlock() != OtherR->getBlock()) return true; - if (DT->compare(Other.getBase())) + if (DT.compare(Other.getBase())) return true; return false; } - /// This method builds the dominator tree for a given CFG - /// The CFG information is passed via AnalysisDeclContext - void buildDominatorTree(AnalysisDeclContext &AC) { - cfg = AC.getCFG(); - DT->recalculate(*cfg); + /// Builds the dominator tree for a given CFG. + void buildDominatorTree(CFG *cfg) { + assert(cfg); + this->cfg = cfg; + DT.recalculate(*cfg); } - /// This method dumps immediate dominators for each block, - /// mainly used for debug purposes. + /// Dumps immediate dominators for each block. void dump() { - llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n"; + llvm::errs() << "Immediate " << (IsPostDom ? "post " : "") + << "dominance tree (Node#,IDom#):\n"; for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) { - if(DT->getNode(*I)->getIDom()) + + assert(*I && + "LLVM's Dominator tree builder uses nullpointers to signify the " + "virtual root!"); + + DomTreeNode *IDom = DT.getNode(*I)->getIDom(); + if (IDom && IDom->getBlock()) llvm::errs() << "(" << (*I)->getBlockID() << "," - << DT->getNode(*I)->getIDom()->getBlock()->getBlockID() + << IDom->getBlock()->getBlockID() << ")\n"; - else llvm::errs() << "(" << (*I)->getBlockID() - << "," << (*I)->getBlockID() << ")\n"; + else { + bool IsEntryBlock = *I == &(*I)->getParent()->getEntry(); + bool IsExitBlock = *I == &(*I)->getParent()->getExit(); + + bool IsDomTreeRoot = !IDom && !IsPostDom && IsEntryBlock; + bool IsPostDomTreeRoot = + IDom && !IDom->getBlock() && IsPostDom && IsExitBlock; + + assert((IsDomTreeRoot || IsPostDomTreeRoot) && + "If the immediate dominator node is nullptr, the CFG block " + "should be the exit point (since it's the root of the dominator " + "tree), or if the CFG block it refers to is a nullpointer, it " + "must be the entry block (since it's the root of the post " + "dominator tree)"); + + (void)IsDomTreeRoot; + (void)IsPostDomTreeRoot; + + llvm::errs() << "(" << (*I)->getBlockID() + << "," << (*I)->getBlockID() << ")\n"; + } } } - /// This method tests if one CFGBlock dominates the other. - /// The method return true if A dominates B, false otherwise. + /// Tests whether \p A dominates \p B. /// Note a block always dominates itself. bool dominates(const CFGBlock *A, const CFGBlock *B) const { - return DT->dominates(A, B); + return DT.dominates(A, B); } - /// This method tests if one CFGBlock properly dominates the other. - /// The method return true if A properly dominates B, false otherwise. + /// Tests whether \p A properly dominates \p B. + /// \returns false if \p A is the same block as \p B, otherwise whether A + /// dominates B. bool properlyDominates(const CFGBlock *A, const CFGBlock *B) const { - return DT->properlyDominates(A, B); + return DT.properlyDominates(A, B); } - /// This method finds the nearest common dominator CFG block - /// for CFG block A and B. If there is no such block then return NULL. + /// \returns the nearest common dominator CFG block for CFG block \p A and \p + /// B. If there is no such block then return NULL. CFGBlock *findNearestCommonDominator(CFGBlock *A, CFGBlock *B) { - return DT->findNearestCommonDominator(A, B); + return DT.findNearestCommonDominator(A, B); } const CFGBlock *findNearestCommonDominator(const CFGBlock *A, const CFGBlock *B) { - return DT->findNearestCommonDominator(A, B); + return DT.findNearestCommonDominator(A, B); } - /// This method is used to update the dominator - /// tree information when a node's immediate dominator changes. + /// Update the dominator tree information when a node's immediate dominator + /// changes. void changeImmediateDominator(CFGBlock *N, CFGBlock *NewIDom) { - DT->changeImmediateDominator(N, NewIDom); + DT.changeImmediateDominator(N, NewIDom); } - /// This method tests if the given CFGBlock can be reachable from root. - /// Returns true if reachable, false otherwise. + /// Tests whether \p A is reachable from the entry block. bool isReachableFromEntry(const CFGBlock *A) { - return DT->isReachableFromEntry(A); + return DT.isReachableFromEntry(A); } - /// This method releases the memory held by the dominator tree. + /// Releases the memory held by the dominator tree. virtual void releaseMemory() { - DT->releaseMemory(); + DT.releaseMemory(); } - /// This method converts the dominator tree to human readable form. + /// Converts the dominator tree to human readable form. virtual void print(raw_ostream &OS, const llvm::Module* M= nullptr) const { - DT->print(OS); + DT.print(OS); } private: CFG *cfg; + DominatorTreeBase DT; +}; + +using CFGDomTree = CFGDominatorTreeImpl; +using CFGPostDomTree = CFGDominatorTreeImpl; + +template<> void CFGDominatorTreeImpl::anchor(); +template<> void CFGDominatorTreeImpl::anchor(); + +} // end of namespace clang + +namespace llvm { +namespace IDFCalculatorDetail { + +/// Specialize ChildrenGetterTy to skip nullpointer successors. +template +struct ChildrenGetterTy { + using NodeRef = typename GraphTraits::NodeRef; + using ChildrenTy = SmallVector; + + ChildrenTy get(const NodeRef &N) { + using OrderedNodeTy = + typename IDFCalculatorBase::OrderedNodeTy; + + auto Children = children(N); + ChildrenTy Ret{Children.begin(), Children.end()}; + Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end()); + return Ret; + } +}; + +} // end of namespace IDFCalculatorDetail +} // end of namespace llvm + +namespace clang { + +class ControlDependencyCalculator : public ManagedAnalysis { + using IDFCalculator = llvm::IDFCalculatorBase; + using CFGBlockVector = llvm::SmallVector; + using CFGBlockSet = llvm::SmallPtrSet; + + CFGPostDomTree PostDomTree; + IDFCalculator IDFCalc; + + llvm::DenseMap ControlDepenencyMap; + +public: + ControlDependencyCalculator(CFG *cfg) + : PostDomTree(cfg), IDFCalc(PostDomTree.getBase()) {} + + const CFGPostDomTree &getCFGPostDomTree() const { return PostDomTree; } + + // Lazily retrieves the set of control dependencies to \p A. + const CFGBlockVector &getControlDependencies(CFGBlock *A) { + auto It = ControlDepenencyMap.find(A); + if (It == ControlDepenencyMap.end()) { + CFGBlockSet DefiningBlock = {A}; + IDFCalc.setDefiningBlocks(DefiningBlock); + + CFGBlockVector ControlDependencies; + IDFCalc.calculate(ControlDependencies); + + It = ControlDepenencyMap.insert({A, ControlDependencies}).first; + } + + assert(It != ControlDepenencyMap.end()); + return It->second; + } + + /// Whether \p A is control dependent on \p B. + bool isControlDependent(CFGBlock *A, CFGBlock *B) { + return llvm::is_contained(getControlDependencies(A), B); + } + + // Dumps immediate control dependencies for each block. + LLVM_DUMP_METHOD void dump() { + CFG *cfg = PostDomTree.getCFG(); + llvm::errs() << "Control dependencies (Node#,Dependency#):\n"; + for (CFGBlock *BB : *cfg) { + + assert(BB && + "LLVM's Dominator tree builder uses nullpointers to signify the " + "virtual root!"); + + for (CFGBlock *isControlDependency : getControlDependencies(BB)) + llvm::errs() << "(" << BB->getBlockID() + << "," + << isControlDependency->getBlockID() + << ")\n"; + } + } }; } // namespace clang +namespace llvm { + +/// Clang's CFG contains nullpointers for unreachable succesors, e.g. when an +/// if statement's condition is always false, it's 'then' branch is represented +/// with a nullptr. This however will result in a nullpointer derefernece for +/// dominator tree calculation. +/// +/// To circumvent this, let's just crudely specialize the children getters +/// used in LLVM's dominator tree builder. +namespace DomTreeBuilder { + +using ClangCFGDomChildrenGetter = +SemiNCAInfo::ChildrenGetter< + /*Inverse=*/false>; + +template <> +template <> +inline ClangCFGDomChildrenGetter::ResultTy ClangCFGDomChildrenGetter::Get( + clang::CFGBlock *N, std::integral_constant) { + auto RChildren = reverse(children(N)); + ResultTy Ret(RChildren.begin(), RChildren.end()); + Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end()); + return Ret; +} + +using ClangCFGDomReverseChildrenGetter = +SemiNCAInfo::ChildrenGetter< + /*Inverse=*/true>; + +template <> +template <> +inline ClangCFGDomReverseChildrenGetter::ResultTy +ClangCFGDomReverseChildrenGetter::Get( + clang::CFGBlock *N, std::integral_constant) { + auto IChildren = inverse_children(N); + ResultTy Ret(IChildren.begin(), IChildren.end()); + Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end()); + return Ret; +} + +using ClangCFGPostDomChildrenGetter = +SemiNCAInfo::ChildrenGetter< + /*Inverse=*/false>; + +template <> +template <> +inline ClangCFGPostDomChildrenGetter::ResultTy +ClangCFGPostDomChildrenGetter::Get( + clang::CFGBlock *N, std::integral_constant) { + auto RChildren = reverse(children(N)); + ResultTy Ret(RChildren.begin(), RChildren.end()); + Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end()); + return Ret; +} + +using ClangCFGPostDomReverseChildrenGetter = +SemiNCAInfo::ChildrenGetter< + /*Inverse=*/true>; + +template <> +template <> +inline ClangCFGPostDomReverseChildrenGetter::ResultTy +ClangCFGPostDomReverseChildrenGetter::Get( + clang::CFGBlock *N, std::integral_constant) { + auto IChildren = inverse_children(N); + ResultTy Ret(IChildren.begin(), IChildren.end()); + Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end()); + return Ret; +} + +} // end of namespace DomTreeBuilder + //===------------------------------------- /// DominatorTree GraphTraits specialization so the DominatorTree can be /// iterable by generic graph iterators. /// -namespace llvm { - -template <> struct GraphTraits< ::clang::DomTreeNode* > { +template <> struct GraphTraits { using NodeRef = ::clang::DomTreeNode *; using ChildIteratorType = ::clang::DomTreeNode::iterator; @@ -182,17 +369,17 @@ template <> struct GraphTraits< ::clang::DomTreeNode* > { } }; -template <> struct GraphTraits< ::clang::DominatorTree* > - : public GraphTraits< ::clang::DomTreeNode* > { - static NodeRef getEntryNode(::clang::DominatorTree *DT) { +template <> struct GraphTraits + : public GraphTraits { + static NodeRef getEntryNode(clang::CFGDomTree *DT) { return DT->getRootNode(); } - static nodes_iterator nodes_begin(::clang::DominatorTree *N) { + static nodes_iterator nodes_begin(clang::CFGDomTree *N) { return nodes_iterator(df_begin(getEntryNode(N))); } - static nodes_iterator nodes_end(::clang::DominatorTree *N) { + static nodes_iterator nodes_end(clang::CFGDomTree *N) { return nodes_iterator(df_end(getEntryNode(N))); } }; diff --git a/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h b/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h index edc6e00f1d00..9397c5df78ab 100644 --- a/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h +++ b/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h @@ -1,9 +1,8 @@ //===---------- ExprMutationAnalyzer.h ------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h index 114597661a67..a46c35ee5b30 100644 --- a/include/clang/Analysis/Analyses/LiveVariables.h +++ b/include/clang/Analysis/Analyses/LiveVariables.h @@ -1,9 +1,8 @@ //===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/PostOrderCFGView.h b/include/clang/Analysis/Analyses/PostOrderCFGView.h index 7df3dc66c311..08fda0982df4 100644 --- a/include/clang/Analysis/Analyses/PostOrderCFGView.h +++ b/include/clang/Analysis/Analyses/PostOrderCFGView.h @@ -1,9 +1,8 @@ //===- PostOrderCFGView.h - Post order view of CFG blocks -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/ReachableCode.h b/include/clang/Analysis/Analyses/ReachableCode.h index d79f1b03df7b..514b9458d331 100644 --- a/include/clang/Analysis/Analyses/ReachableCode.h +++ b/include/clang/Analysis/Analyses/ReachableCode.h @@ -1,9 +1,8 @@ //===- ReachableCode.h -----------------------------------------*- C++ --*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h index c72db6f2b24b..18659aa4e5bb 100644 --- a/include/clang/Analysis/Analyses/ThreadSafety.h +++ b/include/clang/Analysis/Analyses/ThreadSafety.h @@ -1,9 +1,8 @@ //===- ThreadSafety.h -------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -120,18 +119,22 @@ public: /// \param Kind -- the capability's name parameter (role, mutex, etc). /// \param Expected -- the kind of lock expected. /// \param Received -- the kind of lock received. - /// \param Loc -- The SourceLocation of the Unlock. + /// \param LocLocked -- The SourceLocation of the Lock. + /// \param LocUnlock -- The SourceLocation of the Unlock. virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName, LockKind Expected, LockKind Received, - SourceLocation Loc) {} + SourceLocation LocLocked, + SourceLocation LocUnlock) {} /// Warn about lock function calls for locks which are already held. /// \param Kind -- the capability's name parameter (role, mutex, etc). /// \param LockName -- A StringRef name for the lock expression, to be printed /// in the error message. - /// \param Loc -- The location of the second lock expression. + /// \param LocLocked -- The location of the first lock expression. + /// \param LocDoubleLock -- The location of the second lock expression. virtual void handleDoubleLock(StringRef Kind, Name LockName, - SourceLocation Loc) {} + SourceLocation LocLocked, + SourceLocation LocDoubleLock) {} /// Warn about situations where a mutex is sometimes held and sometimes not. /// The three situations are: diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index 422a1db7f6fd..4a58fe870944 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -1,9 +1,8 @@ //===- ThreadSafetyCommon.h -------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h index 2508af1af107..8d938c1b23c0 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h @@ -1,9 +1,8 @@ //===- ThreadSafetyLogical.h -----------------------------------*- C++ --*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // This file defines a representation for logical expressions with SExpr leaves diff --git a/include/clang/Analysis/Analyses/ThreadSafetyOps.def b/include/clang/Analysis/Analyses/ThreadSafetyOps.def index 0d2458b0c893..fc4881a7f0fd 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyOps.def +++ b/include/clang/Analysis/Analyses/ThreadSafetyOps.def @@ -1,9 +1,8 @@ //===- ThreadSafetyTIL.h ---------------------------------------*- C++ --*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h index c106a9a42731..c26d2ed99dd2 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h @@ -1,9 +1,8 @@ //===- ThreadSafetyTIL.h ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT in the llvm repository for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -1605,7 +1604,7 @@ public: /// Return the index of BB, or Predecessors.size if BB is not a predecessor. unsigned findPredecessorIndex(const BasicBlock *BB) const { - auto I = std::find(Predecessors.cbegin(), Predecessors.cend(), BB); + auto I = llvm::find(Predecessors, BB); return std::distance(Predecessors.cbegin(), I); } diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h index 32aadf526587..e81c00d3dddb 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h @@ -1,9 +1,8 @@ //===- ThreadSafetyTraverse.h -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h index 16583939d542..e3b6e61d3026 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h @@ -1,9 +1,8 @@ //===- ThreadSafetyUtil.h ---------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h index 79d89e0633fd..479be1fec048 100644 --- a/include/clang/Analysis/Analyses/UninitializedValues.h +++ b/include/clang/Analysis/Analyses/UninitializedValues.h @@ -1,9 +1,8 @@ //=- UninitializedValues.h - Finding uses of uninitialized values -*- C++ -*-=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/AnalysisDeclContext.h b/include/clang/Analysis/AnalysisDeclContext.h index 490d2ce346be..1961d571e9e1 100644 --- a/include/clang/Analysis/AnalysisDeclContext.h +++ b/include/clang/Analysis/AnalysisDeclContext.h @@ -1,9 +1,8 @@ // AnalysisDeclContext.h - Analysis context for Path Sens analysis -*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -275,11 +274,17 @@ public: virtual void Profile(llvm::FoldingSetNodeID &ID) = 0; void dumpStack( - raw_ostream &OS, StringRef Indent = {}, const char *NL = "\n", - const char *Sep = "", + raw_ostream &Out, const char *NL = "\n", std::function printMoreInfoPerContext = [](const LocationContext *) {}) const; - void dumpStack() const; + + void printJson( + raw_ostream &Out, const char *NL = "\n", unsigned int Space = 0, + bool IsDot = false, + std::function printMoreInfoPerContext = + [](const LocationContext *) {}) const; + + void dump() const; public: static void ProfileCommon(llvm::FoldingSetNodeID &ID, @@ -460,6 +465,7 @@ public: bool addCXXNewAllocator = true, bool addRichCXXConstructors = true, bool markElidedCXXConstructors = true, + bool addVirtualBaseBranches = true, CodeInjector *injector = nullptr); AnalysisDeclContext *getContext(const Decl *D); diff --git a/include/clang/Analysis/AnalysisDiagnostic.h b/include/clang/Analysis/AnalysisDiagnostic.h index 087ffdcde90c..fd5f2ffe6483 100644 --- a/include/clang/Analysis/AnalysisDiagnostic.h +++ b/include/clang/Analysis/AnalysisDiagnostic.h @@ -1,9 +1,8 @@ //===--- DiagnosticAnalysis.h - Diagnostics for libanalysis -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Analysis/AnyCall.h b/include/clang/Analysis/AnyCall.h new file mode 100644 index 000000000000..97a94d299e64 --- /dev/null +++ b/include/clang/Analysis/AnyCall.h @@ -0,0 +1,209 @@ +//=== AnyCall.h - Abstraction over different callables --------*- C++ -*--// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// A utility class for performing generic operations over different callables. +// +//===----------------------------------------------------------------------===// +// +#ifndef LLVM_CLANG_ANALYSIS_ANY_CALL_H +#define LLVM_CLANG_ANALYSIS_ANY_CALL_H + +#include "clang/AST/Decl.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprObjC.h" + +namespace clang { + +/// An instance of this class corresponds to a call. +/// It might be a syntactically-concrete call, done as a part of evaluating an +/// expression, or it may be an abstract callee with no associated expression. +class AnyCall { +public: + enum Kind { + /// A function, function pointer, or a C++ method call + Function, + + /// A call to an Objective-C method + ObjCMethod, + + /// A call to an Objective-C block + Block, + + /// An implicit C++ destructor call (called implicitly + /// or by operator 'delete') + Destructor, + + /// An implicit or explicit C++ constructor call + Constructor, + + /// A C++ allocation function call (operator `new`), via C++ new-expression + Allocator, + + /// A C++ deallocation function call (operator `delete`), via C++ + /// delete-expression + Deallocator + }; + +private: + /// Either expression or declaration (but not both at the same time) + /// can be null. + + /// Call expression, is null when is not known (then declaration is non-null), + /// or for implicit destructor calls (when no expression exists.) + const Expr *E = nullptr; + + /// Corresponds to a statically known declaration of the called function, + /// or null if it is not known (e.g. for a function pointer). + const Decl *D = nullptr; + Kind K; + +public: + AnyCall(const CallExpr *CE) : E(CE) { + D = CE->getCalleeDecl(); + K = (CE->getCallee()->getType()->getAs()) ? Block + : Function; + if (D && ((K == Function && !isa(D)) || + (K == Block && !isa(D)))) + D = nullptr; + } + + AnyCall(const ObjCMessageExpr *ME) + : E(ME), D(ME->getMethodDecl()), K(ObjCMethod) {} + + AnyCall(const CXXNewExpr *NE) + : E(NE), D(NE->getOperatorNew()), K(Allocator) {} + + AnyCall(const CXXDeleteExpr *NE) + : E(NE), D(NE->getOperatorDelete()), K(Deallocator) {} + + AnyCall(const CXXConstructExpr *NE) + : E(NE), D(NE->getConstructor()), K(Constructor) {} + + AnyCall(const CXXDestructorDecl *D) : E(nullptr), D(D), K(Destructor) {} + + AnyCall(const CXXConstructorDecl *D) : E(nullptr), D(D), K(Constructor) {} + + AnyCall(const ObjCMethodDecl *D) : E(nullptr), D(D), K(ObjCMethod) {} + + AnyCall(const FunctionDecl *D) : E(nullptr), D(D) { + if (isa(D)) { + K = Constructor; + } else if (isa (D)) { + K = Destructor; + } else { + K = Function; + } + + } + + /// If {@code E} is a generic call (to ObjC method /function/block/etc), + /// return a constructed {@code AnyCall} object. Return None otherwise. + static Optional forExpr(const Expr *E) { + if (const auto *ME = dyn_cast(E)) { + return AnyCall(ME); + } else if (const auto *CE = dyn_cast(E)) { + return AnyCall(CE); + } else if (const auto *CXNE = dyn_cast(E)) { + return AnyCall(CXNE); + } else if (const auto *CXDE = dyn_cast(E)) { + return AnyCall(CXDE); + } else if (const auto *CXCE = dyn_cast(E)) { + return AnyCall(CXCE); + } else { + return None; + } + } + + /// If {@code D} is a callable (Objective-C method or a function), return + /// a constructed {@code AnyCall} object. Return None otherwise. + // FIXME: block support. + static Optional forDecl(const Decl *D) { + if (const auto *FD = dyn_cast(D)) { + return AnyCall(FD); + } else if (const auto *MD = dyn_cast(D)) { + return AnyCall(MD); + } + return None; + } + + /// \returns formal parameters for direct calls (including virtual calls) + ArrayRef parameters() const { + if (!D) + return None; + + if (const auto *FD = dyn_cast(D)) { + return FD->parameters(); + } else if (const auto *MD = dyn_cast(D)) { + return MD->parameters(); + } else if (const auto *BD = dyn_cast(D)) { + return BD->parameters(); + } else { + return None; + } + } + + using param_const_iterator = ArrayRef::const_iterator; + param_const_iterator param_begin() const { return parameters().begin(); } + param_const_iterator param_end() const { return parameters().end(); } + size_t param_size() const { return parameters().size(); } + bool param_empty() const { return parameters().empty(); } + + QualType getReturnType(ASTContext &Ctx) const { + switch (K) { + case Function: + if (E) + return cast(E)->getCallReturnType(Ctx); + return cast(D)->getReturnType(); + case ObjCMethod: + if (E) + return cast(E)->getCallReturnType(Ctx); + return cast(D)->getReturnType(); + case Block: + // FIXME: BlockDecl does not know its return type, + // hence the asymmetry with the function and method cases above. + return cast(E)->getCallReturnType(Ctx); + case Destructor: + case Constructor: + case Allocator: + case Deallocator: + return cast(D)->getReturnType(); + } + llvm_unreachable("Unknown AnyCall::Kind"); + } + + /// \returns Function identifier if it is a named declaration, + /// {@code nullptr} otherwise. + const IdentifierInfo *getIdentifier() const { + if (const auto *ND = dyn_cast_or_null(D)) + return ND->getIdentifier(); + return nullptr; + } + + const Decl *getDecl() const { + return D; + } + + const Expr *getExpr() const { + return E; + } + + Kind getKind() const { + return K; + } + + void dump() const { + if (E) + E->dump(); + if (D) + D->dump(); + } +}; + +} + +#endif // LLVM_CLANG_ANALYSIS_ANY_CALL_H diff --git a/include/clang/Analysis/BodyFarm.h b/include/clang/Analysis/BodyFarm.h index ff0859bc662d..72607f8839f5 100644 --- a/include/clang/Analysis/BodyFarm.h +++ b/include/clang/Analysis/BodyFarm.h @@ -1,9 +1,8 @@ //== BodyFarm.h - Factory for conjuring up fake bodies -------------*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index bf81d8358a54..277b2292e5ea 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -1,9 +1,8 @@ //===- CFG.h - Classes for representing and building CFGs -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -495,33 +494,51 @@ private: /// Represents CFGBlock terminator statement. /// -/// TemporaryDtorsBranch bit is set to true if the terminator marks a branch -/// in control flow of destructors of temporaries. In this case terminator -/// statement is the same statement that branches control flow in evaluation -/// of matching full expression. class CFGTerminator { - llvm::PointerIntPair Data; +public: + enum Kind { + /// A branch that corresponds to a statement in the code, + /// such as an if-statement. + StmtBranch, + /// A branch in control flow of destructors of temporaries. In this case + /// terminator statement is the same statement that branches control flow + /// in evaluation of matching full expression. + TemporaryDtorsBranch, + /// A shortcut around virtual base initializers. It gets taken when + /// virtual base classes have already been initialized by the constructor + /// of the most derived class while we're in the base class. + VirtualBaseBranch, + + /// Number of different kinds, for sanity checks. We subtract 1 so that + /// to keep receiving compiler warnings when we don't cover all enum values + /// in a switch. + NumKindsMinusOne = VirtualBaseBranch + }; + +private: + static constexpr int KindBits = 2; + static_assert((1 << KindBits) > NumKindsMinusOne, + "Not enough room for kind!"); + llvm::PointerIntPair Data; public: - CFGTerminator() = default; - CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false) - : Data(S, TemporaryDtorsBranch) {} + CFGTerminator() { assert(!isValid()); } + CFGTerminator(Stmt *S, Kind K = StmtBranch) : Data(S, K) {} + bool isValid() const { return Data.getOpaqueValue() != nullptr; } Stmt *getStmt() { return Data.getPointer(); } const Stmt *getStmt() const { return Data.getPointer(); } + Kind getKind() const { return static_cast(Data.getInt()); } - bool isTemporaryDtorsBranch() const { return Data.getInt(); } - - operator Stmt *() { return getStmt(); } - operator const Stmt *() const { return getStmt(); } - - Stmt *operator->() { return getStmt(); } - const Stmt *operator->() const { return getStmt(); } - - Stmt &operator*() { return *getStmt(); } - const Stmt &operator*() const { return *getStmt(); } - - explicit operator bool() const { return getStmt(); } + bool isStmtBranch() const { + return getKind() == StmtBranch; + } + bool isTemporaryDtorsBranch() const { + return getKind() == TemporaryDtorsBranch; + } + bool isVirtualBaseBranch() const { + return getKind() == VirtualBaseBranch; + } }; /// Represents a single basic block in a source-level CFG. @@ -542,11 +559,12 @@ public: /// Successors: the order in the set of successors is NOT arbitrary. We /// currently have the following orderings based on the terminator: /// -/// Terminator Successor Ordering -/// ----------------------------------------------------- -/// if Then Block; Else Block -/// ? operator LHS expression; RHS expression -/// &&, || expression that uses result of && or ||, RHS +/// Terminator | Successor Ordering +/// ------------------|------------------------------------ +/// if | Then Block; Else Block +/// ? operator | LHS expression; RHS expression +/// logical and/or | expression that consumes the op, RHS +/// vbase inits | already handled by the most derived class; not yet /// /// But note that any of that may be NULL in case of optimized-out edges. class CFGBlock { @@ -837,8 +855,18 @@ public: void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; } void setHasNoReturnElement() { HasNoReturnElement = true; } - CFGTerminator getTerminator() { return Terminator; } - const CFGTerminator getTerminator() const { return Terminator; } + CFGTerminator getTerminator() const { return Terminator; } + + Stmt *getTerminatorStmt() { return Terminator.getStmt(); } + const Stmt *getTerminatorStmt() const { return Terminator.getStmt(); } + + /// \returns the last (\c rbegin()) condition, e.g. observe the following code + /// snippet: + /// if (A && B && C) + /// A block would be created for \c A, \c B, and \c C. For the latter, + /// \c getTerminatorStmt() would retrieve the entire condition, rather than + /// C itself, while this method would only return C. + const Expr *getLastCondition() const; Stmt *getTerminatorCondition(bool StripParens = true); @@ -862,7 +890,11 @@ public: void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const; void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO, bool ShowColors) const; + void printTerminator(raw_ostream &OS, const LangOptions &LO) const; + void printTerminatorJson(raw_ostream &Out, const LangOptions &LO, + bool AddQuotes) const; + void printAsOperand(raw_ostream &OS, bool /*PrintType*/) { OS << "BB#" << getBlockID(); } @@ -1027,6 +1059,7 @@ public: bool AddCXXDefaultInitExprInCtors = false; bool AddRichCXXConstructors = false; bool MarkElidedCXXConstructors = false; + bool AddVirtualBaseBranches = false; BuildOptions() = default; @@ -1173,6 +1206,12 @@ public: /// implementation needs such an interface. unsigned size() const { return NumBlockIDs; } + /// Returns true if the CFG has no branches. Usually it boils down to the CFG + /// having exactly three blocks (entry, the actual code, exit), but sometimes + /// more blocks appear due to having control flow that can be fully + /// resolved in compile time. + bool isLinear() const; + //===--------------------------------------------------------------------===// // CFG Debugging: Pretty-Printing and Visualization. //===--------------------------------------------------------------------===// @@ -1246,6 +1285,9 @@ template <> struct GraphTraits< ::clang::CFGBlock *> { static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); } }; +template <> struct GraphTraits + : GraphTraits {}; + template <> struct GraphTraits< const ::clang::CFGBlock *> { using NodeRef = const ::clang::CFGBlock *; using ChildIteratorType = ::clang::CFGBlock::const_succ_iterator; @@ -1255,6 +1297,9 @@ template <> struct GraphTraits< const ::clang::CFGBlock *> { static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); } }; +template <> struct GraphTraits + : GraphTraits {}; + template <> struct GraphTraits> { using NodeRef = ::clang::CFGBlock *; using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator; @@ -1267,6 +1312,9 @@ template <> struct GraphTraits> { static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); } }; +template <> struct GraphTraits> + : GraphTraits {}; + template <> struct GraphTraits> { using NodeRef = const ::clang::CFGBlock *; using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator; @@ -1279,6 +1327,9 @@ template <> struct GraphTraits> { static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); } }; +template <> struct GraphTraits> + : GraphTraits {}; + // Traits for: CFG template <> struct GraphTraits< ::clang::CFG* > diff --git a/include/clang/Analysis/CFGStmtMap.h b/include/clang/Analysis/CFGStmtMap.h index 78e637daf379..8cf02372ff0f 100644 --- a/include/clang/Analysis/CFGStmtMap.h +++ b/include/clang/Analysis/CFGStmtMap.h @@ -1,9 +1,8 @@ //===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h index e230930b59e0..49c04490fed2 100644 --- a/include/clang/Analysis/CallGraph.h +++ b/include/clang/Analysis/CallGraph.h @@ -1,9 +1,8 @@ //===- CallGraph.h - AST-based Call graph -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/CloneDetection.h b/include/clang/Analysis/CloneDetection.h index fadca137b88d..db827c3a6d6f 100644 --- a/include/clang/Analysis/CloneDetection.h +++ b/include/clang/Analysis/CloneDetection.h @@ -1,9 +1,8 @@ //===--- 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Analysis/CodeInjector.h b/include/clang/Analysis/CodeInjector.h index 2c87cde996f2..a59dc0a94159 100644 --- a/include/clang/Analysis/CodeInjector.h +++ b/include/clang/Analysis/CodeInjector.h @@ -1,9 +1,8 @@ //===-- CodeInjector.h ------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Analysis/ConstructionContext.h b/include/clang/Analysis/ConstructionContext.h index 27c1d5b9f1a5..f1564f9fe740 100644 --- a/include/clang/Analysis/ConstructionContext.h +++ b/include/clang/Analysis/ConstructionContext.h @@ -1,9 +1,8 @@ //===- ConstructionContext.h - CFG constructor information ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/DomainSpecific/CocoaConventions.h b/include/clang/Analysis/DomainSpecific/CocoaConventions.h index 9326d1abbac1..8531d17767ba 100644 --- a/include/clang/Analysis/DomainSpecific/CocoaConventions.h +++ b/include/clang/Analysis/DomainSpecific/CocoaConventions.h @@ -1,9 +1,8 @@ //===- CocoaConventions.h - Special handling of Cocoa conventions -*- C++ -*--// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h index e304d83615d4..80d7cb8e03a1 100644 --- a/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h +++ b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h @@ -1,9 +1,8 @@ //= ObjCNoReturn.h - Handling of Cocoa APIs known not to return --*- C++ -*---// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/FlowSensitive/DataflowValues.h b/include/clang/Analysis/FlowSensitive/DataflowValues.h index f86b2b0bfea1..709753339eb5 100644 --- a/include/clang/Analysis/FlowSensitive/DataflowValues.h +++ b/include/clang/Analysis/FlowSensitive/DataflowValues.h @@ -1,9 +1,8 @@ //===--- DataflowValues.h - Data structure for dataflow values --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index d78174ecd70e..546224bfd58d 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -1,9 +1,8 @@ //==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -43,12 +42,11 @@ public: virtual ~ProgramPointTag(); virtual StringRef getTagDescription() const = 0; -protected: /// Used to implement 'isKind' in subclasses. - const void *getTagKind() { return TagKind; } + const void *getTagKind() const { return TagKind; } private: - const void *TagKind; + const void *const TagKind; }; class SimpleProgramPointTag : public ProgramPointTag { @@ -215,7 +213,7 @@ public: ID.AddPointer(getTag()); } - void print(StringRef CR, llvm::raw_ostream &Out) const; + void printJson(llvm::raw_ostream &Out, const char *NL = "\n") const; LLVM_DUMP_METHOD void dump() const; @@ -259,7 +257,7 @@ public: } const Stmt *getTerminator() const { - return getBlock()->getTerminator(); + return getBlock()->getTerminatorStmt(); } private: @@ -778,9 +776,6 @@ static bool isEqual(const clang::ProgramPoint &L, }; -template <> -struct isPodLike { static const bool value = true; }; - } // end namespace llvm #endif diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/Analysis/RetainSummaryManager.h similarity index 87% rename from include/clang/StaticAnalyzer/Core/RetainSummaryManager.h rename to include/clang/Analysis/RetainSummaryManager.h index 4fcaa794c17b..6acefb563d8c 100644 --- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h +++ b/include/clang/Analysis/RetainSummaryManager.h @@ -1,9 +1,8 @@ //=== RetainSummaryManager.h - Summaries for reference counting ---*- C++ -*--// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -13,25 +12,21 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_ANALYZER_CORE_RETAINSUMMARYMANAGER -#define LLVM_CLANG_ANALYZER_CORE_RETAINSUMMARYMANAGER +#ifndef LLVM_CLANG_ANALYSIS_RETAINSUMMARY_MANAGER_H +#define LLVM_CLANG_ANALYSIS_RETAINSUMMARY_MANAGER_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/ImmutableMap.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ParentMap.h" +#include "clang/Analysis/AnyCall.h" #include "clang/Analysis/SelectorExtras.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "llvm/ADT/STLExtras.h" -//===----------------------------------------------------------------------===// -// Adapters for FoldingSet. -//===----------------------------------------------------------------------===// - using namespace clang; -using namespace ento; namespace clang { namespace ento { @@ -208,40 +203,6 @@ public: } }; -/// Encapsulates the retain count semantics on the arguments, return value, -/// and receiver (if any) of a function/method call. -/// -/// Note that construction of these objects is not highly efficient. That -/// is okay for clients where creating these objects isn't really a bottleneck. -/// The purpose of the API is to provide something simple. The actual -/// static analyzer checker that implements retain/release typestate -/// tracking uses something more efficient. -class CallEffects { - llvm::SmallVector Args; - RetEffect Ret; - ArgEffect Receiver; - - CallEffects(const RetEffect &R, - ArgEffect Receiver = ArgEffect(DoNothing, ObjKind::AnyObj)) - : Ret(R), Receiver(Receiver) {} - -public: - /// Returns the argument effects for a call. - ArrayRef getArgs() const { return Args; } - - /// Returns the effects on the receiver. - ArgEffect getReceiver() const { return Receiver; } - - /// Returns the effect on the return value. - RetEffect getReturnValue() const { return Ret; } - - /// Return the CallEfect for a given Objective-C method. - static CallEffects getEffect(const ObjCMethodDecl *MD); - - /// Return the CallEfect for a given C/C++ function. - static CallEffects getEffect(const FunctionDecl *FD); -}; - /// A key identifying a summary. class ObjCSummaryKey { IdentifierInfo* II; @@ -263,9 +224,13 @@ public: } // end namespace ento } // end namespace clang +using namespace ento; namespace llvm { +//===----------------------------------------------------------------------===// +// Adapters for FoldingSet. +//===----------------------------------------------------------------------===// template <> struct FoldingSetTrait { static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) { ID.AddInteger((unsigned) X.getKind()); @@ -380,6 +345,8 @@ public: /// This is only meaningful if the summary applies to CXXMethodDecl*. ArgEffect getThisEffect() const { return This; } + ArgEffect getDefaultEffect() const { return DefaultArgEffect; } + /// Set the effect of the method on "this". void setThisEffect(ArgEffect e) { This = e; } @@ -654,19 +621,15 @@ class RetainSummaryManager { RetainSummaryTemplate &Template); public: - RetainSummaryManager(ASTContext &ctx, - bool usesARC, - bool trackObjCAndCFObjects, + RetainSummaryManager(ASTContext &ctx, bool trackObjCAndCFObjects, bool trackOSObjects) - : Ctx(ctx), - ARCEnabled(usesARC), - TrackObjCAndCFObjects(trackObjCAndCFObjects), - TrackOSObjects(trackOSObjects), - AF(BPAlloc), - ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC) - : RetEffect::MakeOwned(ObjKind::ObjC)), - ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC) - : RetEffect::MakeOwnedWhenTrackedReceiver()) { + : Ctx(ctx), ARCEnabled((bool)Ctx.getLangOpts().ObjCAutoRefCount), + TrackObjCAndCFObjects(trackObjCAndCFObjects), + TrackOSObjects(trackOSObjects), AF(BPAlloc), + ObjCAllocRetE(ARCEnabled ? RetEffect::MakeNotOwned(ObjKind::ObjC) + : RetEffect::MakeOwned(ObjKind::ObjC)), + ObjCInitRetE(ARCEnabled ? RetEffect::MakeNotOwned(ObjKind::ObjC) + : RetEffect::MakeOwnedWhenTrackedReceiver()) { InitializeClassMethodSummaries(); InitializeMethodSummaries(); } @@ -678,6 +641,9 @@ public: // Function returns the first argument. Identity, + // Function returns "this" argument. + IdentityThis, + // Function either returns zero, or the input parameter. IdentityOrZero }; @@ -685,10 +651,24 @@ public: Optional canEval(const CallExpr *CE, const FunctionDecl *FD, bool &hasTrustedImplementationAnnotation); - bool isTrustedReferenceCountImplementation(const FunctionDecl *FD); + /// \return Whether the type corresponds to a known smart pointer + /// implementation (that is, everything about it is inlineable). + static bool isKnownSmartPointer(QualType QT); - const RetainSummary *getSummary(const CallEvent &Call, - QualType ReceiverType=QualType()); + bool isTrustedReferenceCountImplementation(const Decl *FD); + + const RetainSummary *getSummary(AnyCall C, + bool HasNonZeroCallbackArg=false, + bool IsReceiverUnconsumedSelf=false, + QualType ReceiverType={}); + + RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; } + +private: + + /// getMethodSummary - This version of getMethodSummary is used to query + /// the summary for the current method being analyzed. + const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD); const RetainSummary *getFunctionSummary(const FunctionDecl *FD); @@ -698,32 +678,9 @@ public: ObjCMethodSummariesTy &CachedSummaries); const RetainSummary * - getInstanceMethodSummary(const ObjCMethodCall &M, - QualType ReceiverType); + getInstanceMethodSummary(const ObjCMessageExpr *ME, QualType ReceiverType); - const RetainSummary *getClassMethodSummary(const ObjCMethodCall &M) { - assert(!M.isInstanceMessage()); - const ObjCInterfaceDecl *Class = M.getReceiverInterface(); - - return getMethodSummary(M.getSelector(), Class, M.getDecl(), - M.getResultType(), ObjCClassMethodSummaries); - } - - /// getMethodSummary - This version of getMethodSummary is used to query - /// the summary for the current method being analyzed. - const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) { - const ObjCInterfaceDecl *ID = MD->getClassInterface(); - Selector S = MD->getSelector(); - QualType ResultTy = MD->getReturnType(); - - ObjCMethodSummariesTy *CachedSummaries; - if (MD->isInstanceMethod()) - CachedSummaries = &ObjCMethodSummaries; - else - CachedSummaries = &ObjCClassMethodSummaries; - - return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries); - } + const RetainSummary *getClassMethodSummary(const ObjCMessageExpr *ME); const RetainSummary *getStandardMethodSummary(const ObjCMethodDecl *MD, Selector S, QualType RetTy); @@ -738,13 +695,25 @@ public: void updateSummaryFromAnnotations(const RetainSummary *&Summ, const FunctionDecl *FD); + const RetainSummary *updateSummaryForNonZeroCallbackArg(const RetainSummary *S, + AnyCall &C); - void updateSummaryForCall(const RetainSummary *&Summ, - const CallEvent &Call); + /// Special case '[super init];' and '[self init];' + /// + /// Even though calling '[super init]' without assigning the result to self + /// and checking if the parent returns 'nil' is a bad pattern, it is common. + /// Additionally, our Self Init checker already warns about it. To avoid + /// overwhelming the user with messages from both checkers, we model the case + /// of '[super init]' in cases when it is not consumed by another expression + /// as if the call preserves the value of 'self'; essentially, assuming it can + /// never fail and return 'nil'. + /// Note, we don't want to just stop tracking the value since we want the + /// RetainCount checker to report leaks and use-after-free if SelfInit checker + /// is turned off. + void updateSummaryForReceiverUnconsumedSelf(const RetainSummary *&S); - bool isARCEnabled() const { return ARCEnabled; } - - RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; } + /// Set argument types for arguments which are not doing anything. + void updateSummaryForArgumentTypes(const AnyCall &C, const RetainSummary *&RS); /// Determine whether a declaration {@code D} of correspondent type (return /// type for functions/methods) {@code QT} has any of the given attributes, diff --git a/include/clang/Analysis/SelectorExtras.h b/include/clang/Analysis/SelectorExtras.h index 767063e835e4..d26e9159a937 100644 --- a/include/clang/Analysis/SelectorExtras.h +++ b/include/clang/Analysis/SelectorExtras.h @@ -1,9 +1,8 @@ //=== SelectorExtras.h - Helpers for checkers using selectors -----*- C++ -*-=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h index 00a7417e20f9..74092dabbfda 100644 --- a/include/clang/Analysis/Support/BumpVector.h +++ b/include/clang/Analysis/Support/BumpVector.h @@ -1,9 +1,8 @@ //===- BumpVector.h - Vector-like ADT that uses bump allocation -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/ABI.h b/include/clang/Basic/ABI.h index dc0e49cded63..2401ffa20494 100644 --- a/include/clang/Basic/ABI.h +++ b/include/clang/Basic/ABI.h @@ -1,9 +1,8 @@ //===----- ABI.h - ABI related declarations ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/AddressSpaces.h b/include/clang/Basic/AddressSpaces.h index 217fbd763ff2..2cc67474c121 100644 --- a/include/clang/Basic/AddressSpaces.h +++ b/include/clang/Basic/AddressSpaces.h @@ -1,9 +1,8 @@ //===- AddressSpaces.h - Language-specific address spaces -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/AlignedAllocation.h b/include/clang/Basic/AlignedAllocation.h index c995f47a7d74..88410c5cb51f 100644 --- a/include/clang/Basic/AlignedAllocation.h +++ b/include/clang/Basic/AlignedAllocation.h @@ -1,9 +1,8 @@ //===--- AlignedAllocation.h - Aligned Allocation ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/AllDiagnostics.h b/include/clang/Basic/AllDiagnostics.h index 6c7f95658970..cc6aa631534a 100644 --- a/include/clang/Basic/AllDiagnostics.h +++ b/include/clang/Basic/AllDiagnostics.h @@ -1,9 +1,8 @@ //===--- AllDiagnostics.h - Aggregate Diagnostic headers --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 1fe1dd39948a..d39b16e62b7f 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -1,9 +1,8 @@ //==--- Attr.td - attribute definitions -----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -15,8 +14,11 @@ class DocumentationCategory { } def DocCatFunction : DocumentationCategory<"Function Attributes">; def DocCatVariable : DocumentationCategory<"Variable Attributes">; +def DocCatField : DocumentationCategory<"Field Attributes">; def DocCatType : DocumentationCategory<"Type Attributes">; def DocCatStmt : DocumentationCategory<"Statement Attributes">; +def DocCatDecl : DocumentationCategory<"Declaration Attributes">; + // Attributes listed under the Undocumented category do not generate any public // documentation. Ideally, this category should be used for internal-only // attributes which contain no spellings. @@ -103,13 +105,6 @@ def ObjCInstanceMethod : SubsetSubjectisInstanceMethod()}], "Objective-C instance methods">; -def ObjCInterfaceDeclInitMethod : SubsetSubjectgetMethodFamily() == OMF_init && - (isa(S->getDeclContext()) || - (isa(S->getDeclContext()) && - cast(S->getDeclContext())->IsClassExtension()))}], - "init methods of interface or class extension declarations">; - def Struct : SubsetSubjectisUnion()}], "structs">; @@ -190,6 +185,9 @@ class VariadicIdentifierArgument : Argument; // Like VariadicUnsignedArgument except values are ParamIdx. class VariadicParamIdxArgument : Argument; +// A list of identifiers matching parameters or ParamIdx indices. +class VariadicParamOrParamIdxArgument : Argument; + // Like VariadicParamIdxArgument but for a single function parameter index. class ParamIdxArgument : Argument; @@ -287,20 +285,29 @@ class SubjectList subjects, SubjectDiag diag = WarnDiag, string CustomDiag = customDiag; } -class LangOpt { +class LangOpt { string Name = name; - bit Negated = negated; + + // A custom predicate, written as an expression evaluated in a context with + // "LangOpts" bound. + code CustomCode = customCode; } def MicrosoftExt : LangOpt<"MicrosoftExt">; def Borland : LangOpt<"Borland">; def CUDA : LangOpt<"CUDA">; -def COnly : LangOpt<"CPlusPlus", 1>; +def HIP : LangOpt<"HIP">; +def COnly : LangOpt<"COnly", "!LangOpts.CPlusPlus">; def CPlusPlus : LangOpt<"CPlusPlus">; def OpenCL : LangOpt<"OpenCL">; def RenderScript : LangOpt<"RenderScript">; def ObjC : LangOpt<"ObjC">; def BlocksSupported : LangOpt<"Blocks">; def ObjCAutoRefCount : LangOpt<"ObjCAutoRefCount">; +def ObjCNonFragileRuntime : LangOpt<"ObjCNonFragileRuntime", + "LangOpts.ObjCRuntime.allowsClassStubs()">; + +// Language option for CMSE extensions +def Cmse : LangOpt<"Cmse">; // Defines targets for target-specific attributes. Empty lists are unchecked. class TargetSpec { @@ -310,12 +317,14 @@ class TargetSpec { // Specifies Operating Systems for which the target applies, based off the // OSType enumeration in Triple.h list OSes; - // Specifies the C++ ABIs for which the target applies, based off the - // TargetCXXABI::Kind in TargetCXXABI.h. - list CXXABIs; // Specifies Object Formats for which the target applies, based off the // ObjectFormatType enumeration in Triple.h list ObjectFormats; + // A custom predicate, written as an expression evaluated in a context + // with the following declarations in scope: + // const clang::TargetInfo &Target; + // const llvm::Triple &T = Target.getTriple(); + code CustomCode = [{}]; } class TargetArch arches> : TargetSpec { @@ -329,11 +338,15 @@ def TargetMSP430 : TargetArch<["msp430"]>; def TargetRISCV : TargetArch<["riscv32", "riscv64"]>; def TargetX86 : TargetArch<["x86"]>; def TargetAnyX86 : TargetArch<["x86", "x86_64"]>; +def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>; def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> { let OSes = ["Win32"]; } +def TargetItaniumCXXABI : TargetSpec { + let CustomCode = [{ Target.getCXXABI().isItaniumFamily() }]; +} def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> { - let CXXABIs = ["Microsoft"]; + let CustomCode = [{ Target.getCXXABI().isMicrosoft() }]; } def TargetELF : TargetSpec { let ObjectFormats = ["ELF"]; @@ -421,6 +434,10 @@ def SubjectMatcherForObjCCategory : AttrSubjectMatcherRule<"objc_category", [ObjCCategory]> { let LangOpts = [ObjC]; } +def SubjectMatcherForObjCImplementation : + AttrSubjectMatcherRule<"objc_implementation", [ObjCImpl]> { + let LangOpts = [ObjC]; +} def SubjectMatcherForObjCMethod : AttrSubjectMatcherRule<"objc_method", [ObjCMethod], [ AttrSubjectMatcherSubRule<"is_instance", [ObjCInstanceMethod]> @@ -715,7 +732,8 @@ def Availability : InheritableAttr { let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">, VersionArgument<"deprecated">, VersionArgument<"obsoleted">, BoolArgument<"unavailable">, StringArgument<"message">, - BoolArgument<"strict">, StringArgument<"replacement">]; + BoolArgument<"strict">, StringArgument<"replacement">, + IntArgument<"priority">]; let AdditionalMembers = [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { return llvm::StringSwitch(Platform) @@ -940,6 +958,13 @@ def CUDADevice : InheritableAttr { let Documentation = [Undocumented]; } +def HIPPinnedShadow : InheritableAttr { + let Spellings = [GNU<"hip_pinned_shadow">, Declspec<"__hip_pinned_shadow__">]; + let Subjects = SubjectList<[Var]>; + let LangOpts = [HIP]; + let Documentation = [HIPPinnedShadowDocs]; +} + def CUDADeviceBuiltin : IgnoredAttr { let Spellings = [GNU<"device_builtin">, Declspec<"__device_builtin__">]; let LangOpts = [CUDA]; @@ -1210,6 +1235,13 @@ def FormatArg : InheritableAttr { let Documentation = [Undocumented]; } +def Callback : InheritableAttr { + let Spellings = [Clang<"callback">]; + let Args = [VariadicParamOrParamIdxArgument<"Encoding">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [CallbackDocs]; +} + def GNUInline : InheritableAttr { let Spellings = [GCC<"gnu_inline">]; let Subjects = SubjectList<[Function]>; @@ -1296,6 +1328,12 @@ def MayAlias : InheritableAttr { let Documentation = [Undocumented]; } +def MIGServerRoutine : InheritableAttr { + let Spellings = [Clang<"mig_server_routine">]; + let Subjects = SubjectList<[Function, ObjCMethod, Block]>; + let Documentation = [MIGConventionDocs]; +} + def MSABI : DeclOrTypeAttr { let Spellings = [GCC<"ms_abi">]; // let Subjects = [Function, ObjCMethod]; @@ -1384,6 +1422,12 @@ def NeonVectorType : TypeAttr { let ASTNode = 0; } +def NoUniqueAddress : InheritableAttr, TargetSpecificAttr { + let Spellings = [CXX11<"", "no_unique_address", 201803>]; + let Subjects = SubjectList<[NonBitField], ErrorDiag>; + let Documentation = [NoUniqueAddressDocs]; +} + def ReturnsTwice : InheritableAttr { let Spellings = [GCC<"returns_twice">]; let Subjects = SubjectList<[Function]>; @@ -1410,7 +1454,7 @@ def NoCommon : InheritableAttr { def NoDebug : InheritableAttr { let Spellings = [GCC<"nodebug">]; - let Subjects = SubjectList<[FunctionLike, ObjCMethod, NonParmVar]>; + let Subjects = SubjectList<[TypedefName, FunctionLike, ObjCMethod, NonParmVar]>; let Documentation = [NoDebugDocs]; } @@ -1474,14 +1518,14 @@ def RISCVInterrupt : InheritableAttr, TargetSpecificAttr { def AMDGPUFlatWorkGroupSize : InheritableAttr { let Spellings = [Clang<"amdgpu_flat_work_group_size", 0>]; - let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max">]; + let Args = [ExprArgument<"Min">, ExprArgument<"Max">]; let Documentation = [AMDGPUFlatWorkGroupSizeDocs]; let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } def AMDGPUWavesPerEU : InheritableAttr { let Spellings = [Clang<"amdgpu_waves_per_eu", 0>]; - let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max", 1>]; + let Args = [ExprArgument<"Min">, ExprArgument<"Max", 1>]; let Documentation = [AMDGPUWavesPerEUDocs]; let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } @@ -1500,6 +1544,22 @@ def AMDGPUNumVGPR : InheritableAttr { let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } +def WebAssemblyImportModule : InheritableAttr, + TargetSpecificAttr { + let Spellings = [Clang<"import_module">]; + let Args = [StringArgument<"ImportModule">]; + let Documentation = [WebAssemblyImportModuleDocs]; + let Subjects = SubjectList<[Function], ErrorDiag>; +} + +def WebAssemblyImportName : InheritableAttr, + TargetSpecificAttr { + let Spellings = [Clang<"import_name">]; + let Args = [StringArgument<"ImportName">]; + let Documentation = [WebAssemblyImportNameDocs]; + let Subjects = SubjectList<[Function], ErrorDiag>; +} + def NoSplitStack : InheritableAttr { let Spellings = [GCC<"no_split_stack">]; let Subjects = SubjectList<[Function], ErrorDiag>; @@ -1534,7 +1594,9 @@ def ReturnsNonNull : InheritableAttr { // pass_object_size(N) indicates that the parameter should have // __builtin_object_size with Type=N evaluated on the parameter at the callsite. def PassObjectSize : InheritableParamAttr { - let Spellings = [Clang<"pass_object_size">]; + let Spellings = [Clang<"pass_object_size">, + Clang<"pass_dynamic_object_size">]; + let Accessors = [Accessor<"isDynamic", [Clang<"pass_dynamic_object_size">]>]; let Args = [IntArgument<"Type">]; let Subjects = SubjectList<[ParmVar]>; let Documentation = [PassObjectSizeDocs]; @@ -1615,7 +1677,7 @@ def NoStackProtector : InheritableAttr { def NoThrow : InheritableAttr { let Spellings = [GCC<"nothrow">, Declspec<"nothrow">]; - let Subjects = SubjectList<[Function]>; + let Subjects = SubjectList<[FunctionLike]>; let Documentation = [NoThrowDocs]; } @@ -1731,6 +1793,13 @@ def ObjCRootClass : InheritableAttr { let Documentation = [Undocumented]; } +def ObjCNonLazyClass : Attr { + let Spellings = [Clang<"objc_nonlazy_class">]; + let Subjects = SubjectList<[ObjCInterface, ObjCImpl], ErrorDiag>; + let LangOpts = [ObjC]; + let Documentation = [ObjCNonLazyClassDocs]; +} + def ObjCSubclassingRestricted : InheritableAttr { let Spellings = [Clang<"objc_subclassing_restricted">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; @@ -1745,7 +1814,7 @@ def ObjCExplicitProtocolImpl : InheritableAttr { def ObjCDesignatedInitializer : Attr { let Spellings = [Clang<"objc_designated_initializer">]; - let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag>; + let Subjects = SubjectList<[ObjCMethod], ErrorDiag>; let Documentation = [Undocumented]; } @@ -1762,6 +1831,13 @@ def ObjCRuntimeVisible : Attr { let Documentation = [ObjCRuntimeVisibleDocs]; } +def ObjCClassStub : Attr { + let Spellings = [Clang<"objc_class_stub">]; + let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; + let Documentation = [ObjCClassStubDocs]; + let LangOpts = [ObjCNonFragileRuntime]; +} + def ObjCBoxable : Attr { let Spellings = [Clang<"objc_boxable">]; let Subjects = SubjectList<[Record], ErrorDiag>; @@ -1893,6 +1969,8 @@ def Section : InheritableAttr { let Documentation = [SectionDocs]; } +// This is used for `__declspec(code_seg("segname"))`, but not for +// `#pragma code_seg("segname")`. def CodeSeg : InheritableAttr { let Spellings = [Declspec<"code_seg">]; let Args = [StringArgument<"Name">]; @@ -2326,7 +2404,7 @@ def NoSanitize : InheritableAttr { let Documentation = [NoSanitizeDocs]; let AdditionalMembers = [{ SanitizerMask getMask() const { - SanitizerMask Mask = 0; + SanitizerMask Mask; for (auto SanitizerName : sanitizers()) { SanitizerMask ParsedMask = parseSanitizerValue(SanitizerName, /*AllowGroups=*/true); @@ -2722,6 +2800,12 @@ def : IgnoredAttr { let Spellings = [Declspec<"property">]; } +def MSAllocator : InheritableAttr { + let Spellings = [Declspec<"allocator">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [MSAllocatorDocs]; +} + def MSStruct : InheritableAttr { let Spellings = [GCC<"ms_struct">]; let Subjects = SubjectList<[Record]>; @@ -3112,6 +3196,29 @@ def OMPDeclareTargetDecl : InheritableAttr { }]; } +def OMPAllocateDecl : InheritableAttr { + // This attribute has no spellings as it is only ever created implicitly. + let Spellings = []; + let SemaHandler = 0; + let Args = [ + EnumArgument<"AllocatorType", "AllocatorTypeTy", + [ + "omp_default_mem_alloc", "omp_large_cap_mem_alloc", + "omp_const_mem_alloc", "omp_high_bw_mem_alloc", + "omp_low_lat_mem_alloc", "omp_cgroup_mem_alloc", + "omp_pteam_mem_alloc", "omp_thread_mem_alloc", "" + ], + [ + "OMPDefaultMemAlloc", "OMPLargeCapMemAlloc", + "OMPConstMemAlloc", "OMPHighBWMemAlloc", "OMPLowLatMemAlloc", + "OMPCGroupMemAlloc", "OMPPTeamMemAlloc", "OMPThreadMemAlloc", + "OMPUserDefinedMemAlloc" + ]>, + ExprArgument<"Allocator"> + ]; + let Documentation = [Undocumented]; +} + def InternalLinkage : InheritableAttr { let Spellings = [Clang<"internal_linkage">]; let Subjects = SubjectList<[Var, Function, CXXRecord]>; @@ -3149,6 +3256,12 @@ def SpeculativeLoadHardening : InheritableAttr { let Documentation = [SpeculativeLoadHardeningDocs]; } +def NoSpeculativeLoadHardening : InheritableAttr { + let Spellings = [Clang<"no_speculative_load_hardening">]; + let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>; + let Documentation = [NoSpeculativeLoadHardeningDocs]; +} + def Uninitialized : InheritableAttr { let Spellings = [Clang<"uninitialized", 0>]; let Subjects = SubjectList<[LocalVar]>; diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index 5773a92c9c15..fac6116057dc 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/include/clang/Basic/AttrDocs.td @@ -1,9 +1,8 @@ //==--- AttrDocs.td - Attribute documentation ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===---------------------------------------------------------------------===// @@ -607,6 +606,7 @@ Query for this feature with ``__has_attribute(diagnose_if)``. def PassObjectSizeDocs : Documentation { let Category = DocCatVariable; // Technically it's a parameter doc, but eh. + let Heading = "pass_object_size, pass_dynamic_object_size"; let Content = [{ .. Note:: The mangling of functions with parameters that are annotated with ``pass_object_size`` is subject to change. You can get around this by @@ -699,6 +699,15 @@ Currently, ``pass_object_size`` is a bit restricted in terms of its usage: * It is an error to apply the ``pass_object_size`` attribute to parameters that are not pointers. Additionally, any parameter that ``pass_object_size`` is applied to must be marked ``const`` at its function's definition. + +Clang also supports the ``pass_dynamic_object_size`` attribute, which behaves +identically to ``pass_object_size``, but evaluates a call to +``__builtin_dynamic_object_size`` at the callee instead of +``__builtin_object_size``. ``__builtin_dynamic_object_size`` provides some extra +runtime checks when the object size can't be determined at compile-time. You can +read more about ``__builtin_dynamic_object_size`` `here +`_. + }]; } @@ -912,8 +921,6 @@ and Objective-C methods. }]; } - - def NoDebugDocs : Documentation { let Category = DocCatVariable; let Content = [{ @@ -1002,6 +1009,32 @@ is not specified. }]; } +def NoUniqueAddressDocs : Documentation { + let Category = DocCatField; + let Content = [{ +The ``no_unique_address`` attribute allows tail padding in a non-static data +member to overlap other members of the enclosing class (and in the special +case when the type is empty, permits it to fully overlap other members). +The field is laid out as if a base class were encountered at the corresponding +point within the class (except that it does not share a vptr with the enclosing +object). + +Example usage: + +.. code-block:: c++ + + template struct my_vector { + T *p; + [[no_unique_address]] Alloc alloc; + // ... + }; + static_assert(sizeof(my_vector>) == sizeof(int*)); + +``[[no_unique_address]]`` is a standard C++20 attribute. Clang supports its use +in C++11 onwards. + }]; +} + def ObjCRequiresSuperDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -1048,7 +1081,7 @@ implementation of an override in a subclass does not call super. For example: } def ObjCRuntimeNameDocs : Documentation { - let Category = DocCatFunction; + let Category = DocCatDecl; let Content = [{ By default, the Objective-C interface or protocol identifier is used in the metadata name for that object. The `objc_runtime_name` @@ -1069,14 +1102,36 @@ can only be placed before an @protocol or @interface declaration: } def ObjCRuntimeVisibleDocs : Documentation { - let Category = DocCatFunction; + let Category = DocCatDecl; let Content = [{ -This attribute specifies that the Objective-C class to which it applies is visible to the Objective-C runtime but not to the linker. Classes annotated with this attribute cannot be subclassed and cannot have categories defined for them. +This attribute specifies that the Objective-C class to which it applies is +visible to the Objective-C runtime but not to the linker. Classes annotated +with this attribute cannot be subclassed and cannot have categories defined for +them. + }]; +} + +def ObjCClassStubDocs : Documentation { + let Category = DocCatType; + let Content = [{ +This attribute specifies that the Objective-C class to which it applies is +instantiated at runtime. + +Unlike ``__attribute__((objc_runtime_visible))``, a class having this attribute +still has a "class stub" that is visible to the linker. This allows categories +to be defined. Static message sends with the class as a receiver use a special +access pattern to ensure the class is lazily instantiated from the class stub. + +Classes annotated with this attribute cannot be subclassed and cannot have +implementations defined for them. This attribute is intended for use in +Swift-generated headers for classes defined in Swift. + +Adding or removing this attribute to a class is an ABI-breaking change. }]; } def ObjCBoxableDocs : Documentation { - let Category = DocCatFunction; + let Category = DocCatDecl; let Content = [{ Structs and unions marked with the ``objc_boxable`` attribute can be used with the Objective-C boxed expression syntax, ``@(...)``. @@ -1153,11 +1208,14 @@ replacement=\ *string-literal* the deprecated declaration with the new declaration specified. Multiple availability attributes can be placed on a declaration, which may -correspond to different platforms. Only the availability attribute with the -platform corresponding to the target platform will be used; any others will be -ignored. If no availability attribute specifies availability for the current -target platform, the availability attributes are ignored. Supported platforms -are: +correspond to different platforms. For most platforms, the availability +attribute with the platform corresponding to the target platform will be used; +any others will be ignored. However, the availability for ``watchOS`` and +``tvOS`` can be implicitly inferred from an ``iOS`` availability attribute. +Any explicit availability attributes for those platforms are still prefered over +the implicitly inferred availability attributes. If no availability attribute +specifies availability for the current target platform, the availability +attributes are ignored. Supported platforms are: ``ios`` Apple's iOS operating system. The minimum deployment target is specified by @@ -1230,13 +1288,70 @@ Starting with the macOS 10.12 SDK, the ``API_AVAILABLE`` macro from - (id)otherMethod API_AVAILABLE(macos(10.11), ios(11.0)); @end +Availability attributes can also be applied using a ``#pragma clang attribute``. +Any explicit availability attribute whose platform corresponds to the target +platform is applied to a declaration regardless of the availability attributes +specified in the pragma. For example, in the code below, +``hasExplicitAvailabilityAttribute`` will use the ``macOS`` availability +attribute that is specified with the declaration, whereas +``getsThePragmaAvailabilityAttribute`` will use the ``macOS`` availability +attribute that is applied by the pragma. + +.. code-block:: c + + #pragma clang attribute push (__attribute__((availability(macOS, introduced=10.12))), apply_to=function) + void getsThePragmaAvailabilityAttribute(void); + void hasExplicitAvailabilityAttribute(void) __attribute__((availability(macos,introduced=10.4))); + #pragma clang attribute pop + +For platforms like ``watchOS`` and ``tvOS``, whose availability attributes can +be implicitly inferred from an ``iOS`` availability attribute, the logic is +slightly more complex. The explicit and the pragma-applied availability +attributes whose platform corresponds to the target platform are applied as +described in the previous paragraph. However, the implicitly inferred attributes +are applied to a declaration only when there is no explicit or pragma-applied +availability attribute whose platform corresponds to the target platform. For +example, the function below will receive the ``tvOS`` availability from the +pragma rather than using the inferred ``iOS`` availability from the declaration: + +.. code-block:: c + + #pragma clang attribute push (__attribute__((availability(tvOS, introduced=12.0))), apply_to=function) + void getsThePragmaTVOSAvailabilityAttribute(void) __attribute__((availability(iOS,introduced=11.0))); + #pragma clang attribute pop + +The compiler is also able to apply implicly inferred attributes from a pragma +as well. For example, when targeting ``tvOS``, the function below will receive +a ``tvOS`` availability attribute that is implicitly inferred from the ``iOS`` +availability attribute applied by the pragma: + +.. code-block:: c + + #pragma clang attribute push (__attribute__((availability(iOS, introduced=12.0))), apply_to=function) + void infersTVOSAvailabilityFromPragma(void); + #pragma clang attribute pop + +The implicit attributes that are inferred from explicitly specified attributes +whose platform corresponds to the target platform are applied to the declaration +even if there is an availability attribute that can be inferred from a pragma. +For example, the function below will receive the ``tvOS, introduced=11.0`` +availability that is inferred from the attribute on the declaration rather than +inferring availability from the pragma: + +.. code-block:: c + + #pragma clang attribute push (__attribute__((availability(iOS, unavailable))), apply_to=function) + void infersTVOSAvailabilityFromAttributeNextToDeclaration(void) + __attribute__((availability(iOS,introduced=11.0))); + #pragma clang attribute pop + Also see the documentation for `@available `_ }]; } def ExternalSourceSymbolDocs : Documentation { - let Category = DocCatFunction; + let Category = DocCatDecl; let Content = [{ The ``external_source_symbol`` attribute specifies that a declaration originates from an external source and describes the nature of that source. @@ -2380,7 +2495,7 @@ behavior of the program is undefined. } def FlagEnumDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ This attribute can be added to an enumerator to signal to the compiler that it is intended to be used as a flag type. This will cause the compiler to assume @@ -2390,7 +2505,7 @@ manipulating bits of the enumerator when issuing warnings. } def EnumExtensibilityDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ Attribute ``enum_extensibility`` is used to distinguish between enum definitions that are extensible and those that are not. The attribute can take either @@ -2439,7 +2554,7 @@ standard and instructs clang to be more lenient when issuing warnings. } def EmptyBasesDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ The empty_bases attribute permits the compiler to utilize the empty-base-optimization more frequently. @@ -2449,7 +2564,7 @@ It is only supported when using the Microsoft C++ ABI. } def LayoutVersionDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ The layout_version attribute requests that the compiler utilize the class layout rules of a particular compiler version. @@ -2475,7 +2590,7 @@ changes. } def TrivialABIDocs : Documentation { - let Category = DocCatVariable; + let Category = DocCatDecl; let Content = [{ The ``trivial_abi`` attribute can be applied to a C++ class, struct, or union. It instructs the compiler to pass and return the type using the C ABI for the @@ -2517,7 +2632,7 @@ Attribute ``trivial_abi`` has no effect in the following cases: } def MSInheritanceDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance"; let Content = [{ This collection of keywords is enabled under ``-fms-extensions`` and controls @@ -2564,7 +2679,7 @@ an error: } def MSNoVTableDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ This attribute can be added to a class declaration or definition to signal to the compiler that constructors and destructors will not reference the virtual @@ -2705,8 +2820,6 @@ def PipelineHintDocs : Documentation { }]; } - - def OpenCLUnrollHintDocs : Documentation { let Category = DocCatStmt; let Content = [{ @@ -3276,7 +3389,7 @@ jumps from i386 arch code). }]; } -def AnyX86NoCfCheckDocs : Documentation{ +def AnyX86NoCfCheckDocs : Documentation { let Category = DocCatFunction; let Content = [{ Jump Oriented Programming attacks rely on tampering with addresses used by @@ -3544,7 +3657,7 @@ experimental at this time. } def DeprecatedDocs : Documentation { - let Category = DocCatFunction; + let Category = DocCatDecl; let Content = [{ The ``deprecated`` attribute can be applied to a function, a variable, or a type. This is useful when identifying functions, variables, or types that are @@ -3579,7 +3692,7 @@ Not all targets support this attribute. ELF target support depends on both the l } def LTOVisibilityDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ See :doc:`LTOVisibility`. }]; @@ -3615,7 +3728,7 @@ If a function has neither of these attributes, they become subject to the XRay h } def TransparentUnionDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; 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 @@ -3633,16 +3746,29 @@ Transparent unions are not supported in C++. } def ObjCSubclassingRestrictedDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ This attribute can be added to an Objective-C ``@interface`` declaration to ensure that this class cannot be subclassed. }]; } +def ObjCNonLazyClassDocs : Documentation { + let Category = DocCatDecl; + let Content = [{ +This attribute can be added to an Objective-C ``@interface`` or +``@implementation`` declaration to add the class to the list of non-lazily +initialized classes. A non-lazy class will be initialized eagerly when the +Objective-C runtime is loaded. This is required for certain system classes which +have instances allocated in non-standard ways, such as the classes for blocks +and constant strings. Adding this attribute is essentially equivalent to +providing a trivial `+load` method but avoids the (fairly small) load-time +overheads associated with defining and calling such a method. + }]; +} def SelectAnyDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ This attribute appertains to a global symbol, causing it to have a weak definition ( @@ -3652,7 +3778,40 @@ definition ( For more information see `gcc documentation `_ or `msvc documentation `_. -}]; +}]; } + +def WebAssemblyImportModuleDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the ``__attribute__((import_module()))`` +attribute for the WebAssembly target. This attribute may be attached to a +function declaration, where it modifies how the symbol is to be imported +within the WebAssembly linking environment. + +WebAssembly imports use a two-level namespace scheme, consisting of a module +name, which typically identifies a module from which to import, and a field +name, which typically identifies a field from that module to import. By +default, module names for C/C++ symbols are assigned automatically by the +linker. This attribute can be used to override the default behavior, and +reuqest a specific module name be used instead. + }]; +} + +def WebAssemblyImportNameDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the ``__attribute__((import_name()))`` +attribute for the WebAssembly target. This attribute may be attached to a +function declaration, where it modifies how the symbol is to be imported +within the WebAssembly linking environment. + +WebAssembly imports use a two-level namespace scheme, consisting of a module +name, which typically identifies a module from which to import, and a field +name, which typically identifies a field from that module to import. By +default, field names for C/C++ symbols are the same as their C/C++ symbol +names. This attribute can be used to override the default behavior, and +reuqest a specific field name be used instead. + }]; } def ArtificialDocs : Documentation { @@ -3766,6 +3925,39 @@ The ``no_destroy`` attribute specifies that a variable with static or thread storage duration shouldn't have its exit-time destructor run. Annotating every static and thread duration variable with this attribute is equivalent to invoking clang with -fno-c++-static-destructors. + +If a variable is declared with this attribute, clang doesn't access check or +generate the type's destructor. If you have a type that you only want to be +annotated with ``no_destroy``, you can therefore declare the destructor private: + +.. code-block:: c++ + + struct only_no_destroy { + only_no_destroy(); + private: + ~only_no_destroy(); + }; + + [[clang::no_destroy]] only_no_destroy global; // fine! + +Note that destructors are still required for subobjects of aggregates annotated +with this attribute. This is because previously constructed subobjects need to +be destroyed if an exception gets thrown before the initialization of the +complete object is complete. For instance: + +.. code-block::c++ + + void f() { + try { + [[clang::no_destroy]] + static only_no_destroy array[10]; // error, only_no_destroy has a private destructor. + } catch (...) { + // Handle the error + } + } + +Here, if the construction of `array[9]` fails with an exception, `array[0..8]` +will be destroyed, so the element's destructor needs to be accessible. }]; } @@ -3781,6 +3973,55 @@ it rather documents the programmer's intent. }]; } +def CallbackDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``callback`` attribute specifies that the annotated function may invoke the +specified callback zero or more times. The callback, as well as the passed +arguments, are identified by their parameter name or position (starting with +1!) in the annotated function. The first position in the attribute identifies +the callback callee, the following positions declare describe its arguments. +The callback callee is required to be callable with the number, and order, of +the specified arguments. The index `0`, or the identifier `this`, is used to +represent an implicit "this" pointer in class methods. If there is no implicit +"this" pointer it shall not be referenced. The index '-1', or the name "__", +represents an unknown callback callee argument. This can be a value which is +not present in the declared parameter list, or one that is, but is potentially +inspected, captured, or modified. Parameter names and indices can be mixed in +the callback attribute. + +The ``callback`` attribute, which is directly translated to ``callback`` +metadata , make the +connection between the call to the annotated function and the callback callee. +This can enable interprocedural optimizations which were otherwise impossible. +If a function parameter is mentioned in the ``callback`` attribute, through its +position, it is undefined if that parameter is used for anything other than the +actual callback. Inspected, captured, or modified parameters shall not be +listed in the ``callback`` metadata. + +Example encodings for the callback performed by `pthread_create` are shown +below. The explicit attribute annotation indicates that the third parameter +(`start_routine`) is called zero or more times by the `pthread_create` function, +and that the fourth parameter (`arg`) is passed along. Note that the callback +behavior of `pthread_create` is automatically recognized by Clang. In addition, +the declarations of `__kmpc_fork_teams` and `__kmpc_fork_call`, generated for +`#pragma omp target teams` and `#pragma omp parallel`, respectively, are also +automatically recognized as broker functions. Further functions might be added +in the future. + + .. code-block:: c + + __attribute__((callback (start_routine, arg))) + int pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine) (void *), void *arg); + + __attribute__((callback (3, 4))) + int pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine) (void *), void *arg); + + }]; +} + def GnuInlineDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -3788,13 +4029,13 @@ The ``gnu_inline`` changes the meaning of ``extern inline`` to use GNU inline semantics, meaning: * If any declaration that is declared ``inline`` is not declared ``extern``, -then the ``inline`` keyword is just a hint. In particular, an out-of-line -definition is still emitted for a function with external linkage, even if all -call sites are inlined, unlike in C99 and C++ inline semantics. + then the ``inline`` keyword is just a hint. In particular, an out-of-line + definition is still emitted for a function with external linkage, even if all + call sites are inlined, unlike in C99 and C++ inline semantics. * If all declarations that are declared ``inline`` are also declared -``extern``, then the function body is present only for inlining and no -out-of-line version is emitted. + ``extern``, then the function body is present only for inlining and no + out-of-line version is emitted. Some important consequences: ``static inline`` emits an out-of-line version if needed, a plain ``inline`` definition emits an out-of-line version @@ -3822,7 +4063,8 @@ def SpeculativeLoadHardeningDocs : Documentation { This attribute can be applied to a function declaration in order to indicate that `Speculative Load Hardening `_ should be enabled for the function body. This can also be applied to a method - in Objective C. + in Objective C. This attribute will take precedence over the command line flag in + the case where `-mno-speculative-load-hardening `_ is specified. Speculative Load Hardening is a best-effort mitigation against information leak attacks that make use of control flow @@ -3840,6 +4082,42 @@ def SpeculativeLoadHardeningDocs : Documentation { }]; } +def NoSpeculativeLoadHardeningDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ + This attribute can be applied to a function declaration in order to indicate + that `Speculative Load Hardening `_ + is *not* needed for the function body. This can also be applied to a method + in Objective C. This attribute will take precedence over the command line flag in + the case where `-mspeculative-load-hardening `_ is specified. + + Warning: This attribute may not prevent Speculative Load Hardening from being + enabled for a function which inlines a function that has the + 'speculative_load_hardening' attribute. This is intended to provide a + maximally conservative model where the code that is marked with the + 'speculative_load_hardening' attribute will always (even when inlined) + be hardened. A user of this attribute may want to mark functions called by + a function they do not want to be hardened with the 'noinline' attribute. + + For example: + + .. code-block:: c + + __attribute__((speculative_load_hardening)) + int foo(int i) { + return i; + } + + // Note: bar() may still have speculative load hardening enabled if + // foo() is inlined into bar(). Mark foo() with __attribute__((noinline)) + // to avoid this situation. + __attribute__((no_speculative_load_hardening)) + int bar(int i) { + return foo(i); + } + }]; +} + def ObjCExternallyRetainedDocs : Documentation { let Category = DocCatVariable; let Content = [{ @@ -3867,3 +4145,53 @@ Likewise, when applied to a strong local variable, that variable becomes When compiled without ``-fobjc-arc``, this attribute is ignored. }]; } + +def MIGConventionDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ + The Mach Interface Generator release-on-success convention dictates +functions that follow it to only release arguments passed to them when they +return "success" (a ``kern_return_t`` error code that indicates that +no errors have occured). Otherwise the release is performed by the MIG client +that called the function. The annotation ``__attribute__((mig_server_routine))`` +is applied in order to specify which functions are expected to follow the +convention. This allows the Static Analyzer to find bugs caused by violations of +that convention. The attribute would normally appear on the forward declaration +of the actual server routine in the MIG server header, but it may also be +added to arbitrary functions that need to follow the same convention - for +example, a user can add them to auxiliary functions called by the server routine +that have their return value of type ``kern_return_t`` unconditionally returned +from the routine. The attribute can be applied to C++ methods, and in this case +it will be automatically applied to overrides if the method is virtual. The +attribute can also be written using C++11 syntax: ``[[mig::server_routine]]``. +}]; +} + +def MSAllocatorDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``__declspec(allocator)`` attribute is applied to functions that allocate +memory, such as operator new in C++. When CodeView debug information is emitted +(enabled by ``clang -gcodeview`` or ``clang-cl /Z7``), Clang will attempt to +record the code offset of heap allocation call sites in the debug info. It will +also record the type being allocated using some local heuristics. The Visual +Studio debugger uses this information to `profile memory usage`_. + +.. _profile memory usage: https://docs.microsoft.com/en-us/visualstudio/profiling/memory-usage + +This attribute does not affect optimizations in any way, unlike GCC's +``__attribute__((malloc))``. +}]; +} + +def HIPPinnedShadowDocs : Documentation { + let Category = DocCatType; + let Content = [{ +The GNU style attribute __attribute__((hip_pinned_shadow)) or MSVC style attribute +__declspec(hip_pinned_shadow) can be added to the definition of a global variable +to indicate it is a HIP pinned shadow variable. A HIP pinned shadow variable can +be accessed on both device side and host side. It has external linkage and is +not initialized on device side. It has internal linkage and is initialized by +the initializer on host side. + }]; +} \ No newline at end of file diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h index d82dbb032be9..ec0052dfea35 100644 --- a/include/clang/Basic/AttrKinds.h +++ b/include/clang/Basic/AttrKinds.h @@ -1,9 +1,8 @@ //===----- Attr.h - Enum values for C Attribute Kinds ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/AttrSubjectMatchRules.h b/include/clang/Basic/AttrSubjectMatchRules.h index 81aa634dfeb8..010cefcaf340 100644 --- a/include/clang/Basic/AttrSubjectMatchRules.h +++ b/include/clang/Basic/AttrSubjectMatchRules.h @@ -1,9 +1,8 @@ //===-- AttrSubjectMatchRules.h - Attribute subject match rules -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h index 3152453694c9..c69633decd57 100644 --- a/include/clang/Basic/Attributes.h +++ b/include/clang/Basic/Attributes.h @@ -1,9 +1,8 @@ //===--- Attributes.h - Attributes header -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/BitmaskEnum.h b/include/clang/Basic/BitmaskEnum.h index 12ff3cf207be..34bfa1764e5e 100644 --- a/include/clang/Basic/BitmaskEnum.h +++ b/include/clang/Basic/BitmaskEnum.h @@ -1,9 +1,8 @@ //===--- BitmaskEnum.h - wrapper of LLVM's bitmask enum facility-*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def index fa031ce09f6b..984e607a2fc4 100644 --- a/include/clang/Basic/Builtins.def +++ b/include/clang/Basic/Builtins.def @@ -1,9 +1,8 @@ //===--- Builtins.def - Builtin function info database ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -51,8 +50,10 @@ // L -> long (e.g. Li for 'long int', Ld for 'long double') // LL -> long long (e.g. LLi for 'long long int', LLd for __float128) // LLL -> __int128_t (e.g. LLLi) -// W -> int64_t +// Z -> int32_t (require a native 32-bit integer type on the target) +// W -> int64_t (require a native 64-bit integer type on the target) // N -> 'int' size if target is LP64, 'L' otherwise. +// O -> long for OpenCL targets, long long otherwise. // S -> signed // U -> unsigned // I -> Required to constant fold to an integer constant expression. @@ -93,6 +94,8 @@ // j -> returns_twice (like setjmp) // u -> arguments are not evaluated for their side-effects // V:N: -> requires vectors of at least N bits to be legal +// C -> callback behavior: argument N is called with argument +// M_0, ..., M_k as payload // FIXME: gcc has nonnull #if defined(BUILTIN) && !defined(LIBBUILTIN) @@ -417,25 +420,27 @@ BUILTIN(__builtin_clrsb , "ii" , "nc") BUILTIN(__builtin_clrsbl , "iLi" , "nc") BUILTIN(__builtin_clrsbll, "iLLi", "nc") -// FIXME: These type signatures are not correct for targets with int != 32-bits -// or with ULL != 64-bits. +// The following builtins rely on that char == 8 bits, short == 16 bits and that +// there exists native types on the target that are 32- and 64-bits wide, unless +// these conditions are fulfilled these builtins will operate on a not intended +// bitwidth. BUILTIN(__builtin_bswap16, "UsUs", "nc") -BUILTIN(__builtin_bswap32, "UiUi", "nc") -BUILTIN(__builtin_bswap64, "ULLiULLi", "nc") +BUILTIN(__builtin_bswap32, "UZiUZi", "nc") +BUILTIN(__builtin_bswap64, "UWiUWi", "nc") BUILTIN(__builtin_bitreverse8, "UcUc", "nc") BUILTIN(__builtin_bitreverse16, "UsUs", "nc") -BUILTIN(__builtin_bitreverse32, "UiUi", "nc") -BUILTIN(__builtin_bitreverse64, "ULLiULLi", "nc") +BUILTIN(__builtin_bitreverse32, "UZiUZi", "nc") +BUILTIN(__builtin_bitreverse64, "UWiUWi", "nc") BUILTIN(__builtin_rotateleft8, "UcUcUc", "nc") BUILTIN(__builtin_rotateleft16, "UsUsUs", "nc") -BUILTIN(__builtin_rotateleft32, "UiUiUi", "nc") -BUILTIN(__builtin_rotateleft64, "ULLiULLiULLi", "nc") +BUILTIN(__builtin_rotateleft32, "UZiUZiUZi", "nc") +BUILTIN(__builtin_rotateleft64, "UWiUWiUWi", "nc") BUILTIN(__builtin_rotateright8, "UcUcUc", "nc") BUILTIN(__builtin_rotateright16, "UsUsUs", "nc") -BUILTIN(__builtin_rotateright32, "UiUiUi", "nc") -BUILTIN(__builtin_rotateright64, "ULLiULLiULLi", "nc") +BUILTIN(__builtin_rotateright32, "UZiUZiUZi", "nc") +BUILTIN(__builtin_rotateright64, "UWiUWiWi", "nc") // Random GCC builtins BUILTIN(__builtin_constant_p, "i.", "nctu") @@ -447,7 +452,7 @@ BUILTIN(__builtin_va_end, "vA", "n") BUILTIN(__builtin_va_copy, "vAA", "n") BUILTIN(__builtin_stdarg_start, "vA.", "n") BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nc") -BUILTIN(__builtin_bcmp, "iv*v*z", "Fn") +BUILTIN(__builtin_bcmp, "ivC*vC*z", "Fn") BUILTIN(__builtin_bcopy, "vv*v*z", "n") BUILTIN(__builtin_bzero, "vv*z", "nF") BUILTIN(__builtin_fprintf, "iP*cC*.", "Fp:1:") @@ -499,6 +504,7 @@ BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:") BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:") BUILTIN(__builtin_thread_pointer, "v*", "nc") BUILTIN(__builtin_launder, "v*v*", "nt") +LANGBUILTIN(__builtin_is_constant_evaluated, "b", "n", CXX_LANG) // GCC exception builtins BUILTIN(__builtin_eh_return, "vzv*", "r") // FIXME: Takes intptr_t, not size_t! @@ -510,6 +516,7 @@ BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t // GCC Object size checking builtins BUILTIN(__builtin_object_size, "zvC*i", "nu") +BUILTIN(__builtin_dynamic_object_size, "zvC*i", "nu") // Clang only. BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF") BUILTIN(__builtin___memccpy_chk, "v*v*vC*izz", "nF") BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF") @@ -818,6 +825,14 @@ LANGBUILTIN(_interlockedbittestandset64, "UcWiD*Wi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_interlockedbittestandset_acq, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_interlockedbittestandset_nf, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_interlockedbittestandset_rel, "UcNiD*Ni", "n", 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(__noop, "i.", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__lzcnt16, "UsUs", "nc", ALL_MS_LANGUAGES) LANGBUILTIN(__lzcnt, "UiUi", "nc", ALL_MS_LANGUAGES) @@ -829,12 +844,12 @@ 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, "UNiUNii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_lrotl, "ULiULii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl64, "UWiUWii", "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, "UNiUNii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_lrotr, "ULiULii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotr64, "UWiUWii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES) LANGBUILTIN(__fastfail, "vUi", "nr", ALL_MS_LANGUAGES) @@ -951,6 +966,7 @@ LIBBUILTIN(strndup, "c*cC*z", "f", "string.h", ALL_GNU_LANGUAGES) LIBBUILTIN(index, "c*cC*i", "f", "strings.h", ALL_GNU_LANGUAGES) LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h", ALL_GNU_LANGUAGES) LIBBUILTIN(bzero, "vv*z", "f", "strings.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(bcmp, "ivC*vC*z", "f", "strings.h", ALL_GNU_LANGUAGES) // In some systems str[n]casejmp is a macro that expands to _str[n]icmp. // We undefine then here to avoid wrong name. #undef strcasecmp @@ -960,6 +976,9 @@ LIBBUILTIN(strncasecmp, "icC*cC*z", "f", "strings.h", ALL_GNU_LANGUAGES) // POSIX unistd.h LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_GNU_LANGUAGES) LIBBUILTIN(vfork, "p", "fj", "unistd.h", ALL_LANGUAGES) +// POSIX pthread.h +LIBBUILTIN(pthread_create, "", "fC<2,3>", "pthread.h", ALL_GNU_LANGUAGES) + // POSIX setjmp.h LIBBUILTIN(_setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) @@ -1430,6 +1449,7 @@ BUILTIN(__builtin_operator_new, "v*z", "tc") BUILTIN(__builtin_operator_delete, "vv*", "tn") BUILTIN(__builtin_char_memchr, "c*cC*iz", "n") BUILTIN(__builtin_dump_struct, "ivC*v*", "tn") +BUILTIN(__builtin_preserve_access_index, "vC*vC*", "nU") // Safestack builtins BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn") @@ -1458,6 +1478,7 @@ BUILTIN(__builtin_coro_begin, "v*v*", "n") BUILTIN(__builtin_coro_end, "bv*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) @@ -1493,6 +1514,8 @@ LANGBUILTIN(get_kernel_max_sub_group_size_for_ndrange, "Ui.", "tn", OCLC20_LANG) LANGBUILTIN(get_kernel_sub_group_count_for_ndrange, "Ui.", "tn", OCLC20_LANG) // OpenCL v2.0 s6.13.9 - Address space qualifier functions. +// FIXME: Pointer parameters of OpenCL builtins should have their address space +// requirement defined. LANGBUILTIN(to_global, "v*v*", "tn", OCLC20_LANG) LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG) LANGBUILTIN(to_private, "v*v*", "tn", OCLC20_LANG) diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h index fa2bcc4c7ab0..fed0dae20193 100644 --- a/include/clang/Basic/Builtins.h +++ b/include/clang/Basic/Builtins.h @@ -1,9 +1,8 @@ //===--- Builtins.h - Builtin function header -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -194,6 +193,12 @@ public: /// argument and whether this function as a va_list argument. bool isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg); + /// Determine whether this builtin has callback behavior (see + /// llvm::AbstractCallSites for details). If so, add the index to the + /// callback callee argument and the callback payload arguments. + bool performsCallback(unsigned ID, + llvm::SmallVectorImpl &Encoding) const; + /// Return true if this function has no side effects and doesn't /// read memory, except for possibly errno. /// diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def index 1892ff11a31d..7701ad98f483 100644 --- a/include/clang/Basic/BuiltinsAArch64.def +++ b/include/clang/Basic/BuiltinsAArch64.def @@ -1,9 +1,8 @@ //==- BuiltinsAArch64.def - AArch64 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -33,7 +32,7 @@ BUILTIN(__builtin_arm_clrex, "v", "") // Bit manipulation BUILTIN(__builtin_arm_rbit, "UiUi", "nc") -BUILTIN(__builtin_arm_rbit64, "LUiLUi", "nc") +BUILTIN(__builtin_arm_rbit64, "WUiWUi", "nc") // HINT BUILTIN(__builtin_arm_nop, "v", "") @@ -50,23 +49,33 @@ BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc") BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc") BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc") BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc") -BUILTIN(__builtin_arm_crc32d, "UiUiLUi", "nc") -BUILTIN(__builtin_arm_crc32cd, "UiUiLUi", "nc") +BUILTIN(__builtin_arm_crc32d, "UiUiWUi", "nc") +BUILTIN(__builtin_arm_crc32cd, "UiUiWUi", "nc") + +// Memory Tagging Extensions (MTE) +BUILTIN(__builtin_arm_irg, "v*v*Ui", "t") +BUILTIN(__builtin_arm_addg, "v*v*Ui", "t") +BUILTIN(__builtin_arm_gmi, "Uiv*Ui", "t") +BUILTIN(__builtin_arm_ldg, "v*v*", "t") +BUILTIN(__builtin_arm_stg, "vv*", "t") +BUILTIN(__builtin_arm_subp, "Uiv*v*", "t") // Memory barrier BUILTIN(__builtin_arm_dmb, "vUi", "nc") BUILTIN(__builtin_arm_dsb, "vUi", "nc") BUILTIN(__builtin_arm_isb, "vUi", "nc") +BUILTIN(__builtin_arm_jcvt, "Zid", "nc") + // Prefetch BUILTIN(__builtin_arm_prefetch, "vvC*UiUiUiUi", "nc") // System Registers BUILTIN(__builtin_arm_rsr, "UicC*", "nc") -BUILTIN(__builtin_arm_rsr64, "LUicC*", "nc") +BUILTIN(__builtin_arm_rsr64, "WUicC*", "nc") BUILTIN(__builtin_arm_rsrp, "v*cC*", "nc") BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc") -BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc") +BUILTIN(__builtin_arm_wsr64, "vcC*WUi", "nc") BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc") // MSVC @@ -79,15 +88,8 @@ LANGBUILTIN(__wfi, "v", "", ALL_MS_LANGUAGES) LANGBUILTIN(__sev, "v", "", ALL_MS_LANGUAGES) LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES) -// MSVC intrinsics for volatile but non-acquire/release loads and stores -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) +// Misc +BUILTIN(__builtin_sponentry, "v*", "c") TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") @@ -204,8 +206,8 @@ TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", "intrin.h", TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__getReg, "ULLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_ReadStatusReg, "ii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_WriteStatusReg, "vii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_ReadStatusReg, "LLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_WriteStatusReg, "viLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") #undef BUILTIN diff --git a/include/clang/Basic/BuiltinsAMDGPU.def b/include/clang/Basic/BuiltinsAMDGPU.def index a25e45fe3fb8..2f8fb9000a76 100644 --- a/include/clang/Basic/BuiltinsAMDGPU.def +++ b/include/clang/Basic/BuiltinsAMDGPU.def @@ -1,9 +1,8 @@ //==- BuiltinsAMDGPU.def - AMDGPU 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -34,6 +33,9 @@ BUILTIN(__builtin_amdgcn_workitem_id_x, "Ui", "nc") BUILTIN(__builtin_amdgcn_workitem_id_y, "Ui", "nc") BUILTIN(__builtin_amdgcn_workitem_id_z, "Ui", "nc") +BUILTIN(__builtin_amdgcn_mbcnt_hi, "UiUiUi", "nc") +BUILTIN(__builtin_amdgcn_mbcnt_lo, "UiUiUi", "nc") + //===----------------------------------------------------------------------===// // Instruction builtins. //===----------------------------------------------------------------------===// @@ -46,6 +48,11 @@ BUILTIN(__builtin_amdgcn_s_barrier, "v", "n") BUILTIN(__builtin_amdgcn_wave_barrier, "v", "n") BUILTIN(__builtin_amdgcn_s_dcache_inv, "v", "n") BUILTIN(__builtin_amdgcn_buffer_wbinvl1, "v", "n") +BUILTIN(__builtin_amdgcn_ds_gws_init, "vUiUi", "n") +BUILTIN(__builtin_amdgcn_ds_gws_barrier, "vUiUi", "n") +BUILTIN(__builtin_amdgcn_ds_gws_sema_v, "vUi", "n") +BUILTIN(__builtin_amdgcn_ds_gws_sema_br, "vUiUi", "n") +BUILTIN(__builtin_amdgcn_ds_gws_sema_p, "vUi", "n") // FIXME: Need to disallow constant address space. BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n") @@ -99,12 +106,34 @@ BUILTIN(__builtin_amdgcn_fmed3f, "ffff", "nc") BUILTIN(__builtin_amdgcn_ds_faddf, "ff*3fIiIiIb", "n") BUILTIN(__builtin_amdgcn_ds_fminf, "ff*3fIiIiIb", "n") BUILTIN(__builtin_amdgcn_ds_fmaxf, "ff*3fIiIiIb", "n") +BUILTIN(__builtin_amdgcn_ds_append, "ii*3", "n") +BUILTIN(__builtin_amdgcn_ds_consume, "ii*3", "n") +BUILTIN(__builtin_amdgcn_alignbit, "UiUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_alignbyte, "UiUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_ubfe, "UiUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_sbfe, "UiUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_cvt_pkrtz, "E2hff", "nc") +BUILTIN(__builtin_amdgcn_cvt_pknorm_i16, "E2sff", "nc") +BUILTIN(__builtin_amdgcn_cvt_pknorm_u16, "E2Usff", "nc") +BUILTIN(__builtin_amdgcn_cvt_pk_i16, "E2sii", "nc") +BUILTIN(__builtin_amdgcn_cvt_pk_u16, "E2UsUiUi", "nc") +BUILTIN(__builtin_amdgcn_cvt_pk_u8_f32, "UifUiUi", "nc") //===----------------------------------------------------------------------===// // CI+ only builtins. //===----------------------------------------------------------------------===// TARGET_BUILTIN(__builtin_amdgcn_s_dcache_inv_vol, "v", "n", "ci-insts") TARGET_BUILTIN(__builtin_amdgcn_buffer_wbinvl1_vol, "v", "n", "ci-insts") +TARGET_BUILTIN(__builtin_amdgcn_ds_gws_sema_release_all, "vUi", "n", "ci-insts") + +//===----------------------------------------------------------------------===// +// Interpolation builtins. +//===----------------------------------------------------------------------===// +BUILTIN(__builtin_amdgcn_interp_p1_f16, "ffUiUibUi", "nc") +BUILTIN(__builtin_amdgcn_interp_p2_f16, "hffUiUibUi", "nc") +BUILTIN(__builtin_amdgcn_interp_p1, "ffUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_interp_p2, "fffUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_interp_mov, "fUiUiUiUi", "nc") //===----------------------------------------------------------------------===// // VI+ only builtins. @@ -123,7 +152,7 @@ TARGET_BUILTIN(__builtin_amdgcn_classh, "bhi", "nc", "16-bit-insts") TARGET_BUILTIN(__builtin_amdgcn_s_memrealtime, "LUi", "n", "s-memrealtime") TARGET_BUILTIN(__builtin_amdgcn_mov_dpp, "iiIiIiIiIb", "nc", "dpp") TARGET_BUILTIN(__builtin_amdgcn_update_dpp, "iiiIiIiIiIb", "nc", "dpp") -TARGET_BUILTIN(__builtin_amdgcn_s_dcache_wb, "v", "n", "vi-insts") +TARGET_BUILTIN(__builtin_amdgcn_s_dcache_wb, "v", "n", "gfx8-insts") //===----------------------------------------------------------------------===// // GFX9+ only builtins. @@ -135,13 +164,20 @@ TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts") // Deep learning builtins. //===----------------------------------------------------------------------===// -TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot-insts") -TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dot-insts") -TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dot-insts") -TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dot-insts") -TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dot-insts") -TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot-insts") -TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot-insts") +TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot2-insts") +TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dot2-insts") +TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dot2-insts") +TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dot1-insts") +TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dot2-insts") +TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot1-insts") +TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot2-insts") + +//===----------------------------------------------------------------------===// +// GFX10+ only builtins. +//===----------------------------------------------------------------------===// +TARGET_BUILTIN(__builtin_amdgcn_permlane16, "UiUiUiUiUiIbIb", "nc", "gfx10-insts") +TARGET_BUILTIN(__builtin_amdgcn_permlanex16, "UiUiUiUiUiIbIb", "nc", "gfx10-insts") +TARGET_BUILTIN(__builtin_amdgcn_mov_dpp8, "UiUiIUi", "nc", "gfx10-insts") //===----------------------------------------------------------------------===// // Special builtins. diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def index ad778527b212..3f0765115b1c 100644 --- a/include/clang/Basic/BuiltinsARM.def +++ b/include/clang/Basic/BuiltinsARM.def @@ -1,9 +1,8 @@ //===--- BuiltinsARM.def - ARM Builtin function database ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -202,14 +201,6 @@ 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) diff --git a/include/clang/Basic/BuiltinsHexagon.def b/include/clang/Basic/BuiltinsHexagon.def index bb040c06fd07..18029af56ff7 100644 --- a/include/clang/Basic/BuiltinsHexagon.def +++ b/include/clang/Basic/BuiltinsHexagon.def @@ -1,9 +1,8 @@ //===-- BuiltinsHexagon.def - Hexagon 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/BuiltinsLe64.def b/include/clang/Basic/BuiltinsLe64.def index 532860603c29..776492cd21b3 100644 --- a/include/clang/Basic/BuiltinsLe64.def +++ b/include/clang/Basic/BuiltinsLe64.def @@ -1,9 +1,8 @@ //==- BuiltinsLe64.def - Le64 Builtin function database ----------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/BuiltinsMips.def b/include/clang/Basic/BuiltinsMips.def index 2d217f736498..9ac75b7a174e 100644 --- a/include/clang/Basic/BuiltinsMips.def +++ b/include/clang/Basic/BuiltinsMips.def @@ -1,9 +1,8 @@ //===-- BuiltinsMips.def - Mips 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/BuiltinsNEON.def b/include/clang/Basic/BuiltinsNEON.def index 241b93a915a9..b8eb5a7b6173 100644 --- a/include/clang/Basic/BuiltinsNEON.def +++ b/include/clang/Basic/BuiltinsNEON.def @@ -1,9 +1,8 @@ //===--- BuiltinsNEON.def - NEON 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/BuiltinsNVPTX.def b/include/clang/Basic/BuiltinsNVPTX.def index 08c60979779b..70be6182c7ac 100644 --- a/include/clang/Basic/BuiltinsNVPTX.def +++ b/include/clang/Basic/BuiltinsNVPTX.def @@ -1,9 +1,8 @@ //===--- BuiltinsPTX.def - PTX 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,13 +18,22 @@ #endif #pragma push_macro("SM_70") -#define SM_70 "sm_70|sm_71" +#pragma push_macro("SM_72") +#pragma push_macro("SM_75") +#define SM_75 "sm_75" +#define SM_72 "sm_72|" SM_75 +#define SM_70 "sm_70|" SM_72 + #pragma push_macro("SM_60") #define SM_60 "sm_60|sm_61|sm_62|" SM_70 -#pragma push_macro("PTX61") -#define PTX61 "ptx61" #pragma push_macro("PTX60") +#pragma push_macro("PTX61") +#pragma push_macro("PTX63") +#pragma push_macro("PTX64") +#define PTX64 "ptx64" +#define PTX63 "ptx63|" PTX64 +#define PTX61 "ptx61|" PTX63 #define PTX60 "ptx60|" PTX61 #pragma push_macro("AND") @@ -667,10 +675,53 @@ TARGET_BUILTIN(__hmma_m8n32k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", AND(SM_70,PTX TARGET_BUILTIN(__hmma_m8n32k16_mma_f32f32, "vf*iC*iC*fC*IiIi", "", AND(SM_70,PTX61)) TARGET_BUILTIN(__hmma_m8n32k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", AND(SM_70,PTX61)) +// Builtins to support integer and sub-integer WMMA instructions on sm_72/sm_75 +TARGET_BUILTIN(__bmma_m8n8k128_ld_a_b1, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__bmma_m8n8k128_ld_b_b1, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__bmma_m8n8k128_ld_c, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__bmma_m8n8k128_mma_xor_popc_b1, "vi*iC*iC*iC*Ii", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__bmma_m8n8k128_st_c_i32, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_ld_a_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_ld_a_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_ld_b_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_ld_b_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_ld_c, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_mma_s8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_mma_u8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_st_c_i32, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_ld_a_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_ld_a_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_ld_b_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_ld_b_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_ld_c, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_mma_s8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_mma_u8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_st_c_i32, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_ld_a_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_ld_a_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_ld_b_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_ld_b_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_ld_c, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_mma_s8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_mma_u8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_st_c_i32, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_ld_a_s4, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_ld_a_u4, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_ld_b_s4, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_ld_b_u4, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_ld_c, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_mma_s4, "vi*iC*iC*iC*IiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_mma_u4, "vi*iC*iC*iC*IiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_st_c_i32, "vi*iC*UiIi", "", AND(SM_75,PTX63)) + #undef BUILTIN #undef TARGET_BUILTIN #pragma pop_macro("AND") #pragma pop_macro("SM_60") #pragma pop_macro("SM_70") +#pragma pop_macro("SM_72") +#pragma pop_macro("SM_75") #pragma pop_macro("PTX60") #pragma pop_macro("PTX61") +#pragma pop_macro("PTX63") +#pragma pop_macro("PTX64") diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def index d31cb06f05f5..3b6348ad7d70 100644 --- a/include/clang/Basic/BuiltinsPPC.def +++ b/include/clang/Basic/BuiltinsPPC.def @@ -1,9 +1,8 @@ //===--- BuiltinsPPC.def - PowerPC Builtin function database ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -476,6 +475,12 @@ BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "") BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "") BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "") +// Set the floating point rounding mode +BUILTIN(__builtin_setrnd, "di", "") + +// Cache built-ins +BUILTIN(__builtin_dcbf, "vvC*", "") + // FIXME: Obviously incomplete. #undef BUILTIN diff --git a/include/clang/Basic/BuiltinsSystemZ.def b/include/clang/Basic/BuiltinsSystemZ.def index ac92286af0b5..5ea6671e623b 100644 --- a/include/clang/Basic/BuiltinsSystemZ.def +++ b/include/clang/Basic/BuiltinsSystemZ.def @@ -1,9 +1,8 @@ //===-- BuiltinsSystemZ.def - SystemZ 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -277,5 +276,20 @@ TARGET_BUILTIN(__builtin_s390_vfnmssb, "V4fV4fV4fV4f", "nc", "vector-enhancement TARGET_BUILTIN(__builtin_s390_vfsqsb, "V4fV4f", "nc", "vector-enhancements-1") TARGET_BUILTIN(__builtin_s390_vftcisb, "V4SiV4fIii*", "nc", "vector-enhancements-1") +// Vector-enhancements facility 2 intrinsics. +TARGET_BUILTIN(__builtin_s390_vsld, "V16UcV16UcV16UcIi", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vsrd, "V16UcV16UcV16UcIi", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vstrsb, "V16UcV16UcV16UcV16Uci*", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vstrsh, "V16UcV8UsV8UsV16Uci*", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vstrsf, "V16UcV4UiV4UiV16Uci*", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vstrszb, "V16UcV16UcV16UcV16Uci*", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vstrszh, "V16UcV8UsV8UsV16Uci*", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vstrszf, "V16UcV4UiV4UiV16Uci*", "nc", "vector-enhancements-2") + +// Helpers to implement vec_revb. +TARGET_BUILTIN(__builtin_s390_vlbrh, "V8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vlbrf, "V4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vlbrg, "V2ULLiV2ULLi", "nc", "vector") + #undef BUILTIN #undef TARGET_BUILTIN diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def index 55931edc5ca3..63177f016ac7 100644 --- a/include/clang/Basic/BuiltinsWebAssembly.def +++ b/include/clang/Basic/BuiltinsWebAssembly.def @@ -1,9 +1,8 @@ // BuiltinsWebAssembly.def - WebAssembly 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -26,6 +25,13 @@ BUILTIN(__builtin_wasm_memory_size, "zIi", "n") BUILTIN(__builtin_wasm_memory_grow, "zIiz", "n") +// Bulk memory builtins +TARGET_BUILTIN(__builtin_wasm_memory_init, "vIUiIUiv*UiUi", "", "bulk-memory") +TARGET_BUILTIN(__builtin_wasm_data_drop, "vIUi", "", "bulk-memory") + +// Thread-local storage +TARGET_BUILTIN(__builtin_wasm_tls_size, "z", "nc", "bulk-memory") + // Floating point min/max BUILTIN(__builtin_wasm_min_f32, "fff", "nc") BUILTIN(__builtin_wasm_max_f32, "fff", "nc") @@ -33,8 +39,8 @@ BUILTIN(__builtin_wasm_min_f64, "ddd", "nc") BUILTIN(__builtin_wasm_max_f64, "ddd", "nc") // Exception handling builtins. -TARGET_BUILTIN(__builtin_wasm_throw, "vUiv*", "r", "exception-handling") -TARGET_BUILTIN(__builtin_wasm_rethrow, "v", "r", "exception-handling") +TARGET_BUILTIN(__builtin_wasm_throw, "vIUiv*", "r", "exception-handling") +TARGET_BUILTIN(__builtin_wasm_rethrow_in_catch, "v", "r", "exception-handling") // Atomic wait and notify. BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n") diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index b3564b957e99..a0ba0ecf36bb 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -1,9 +1,8 @@ //===--- BuiltinsX86.def - X86 Builtin function database --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -102,24 +101,24 @@ TARGET_BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pand, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pandn, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_por, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pxor, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psllw, "V4sV4sV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pslld, "V2iV2iV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psllq, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrld, "V2iV2iV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrlq, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psraw, "V4sV4sV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrad, "V2iV2iV1LLi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_pand, "V1OiV1OiV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_pandn, "V1OiV1OiV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_por, "V1OiV1OiV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_pxor, "V1OiV1OiV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psllw, "V4sV4sV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_pslld, "V2iV2iV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psllq, "V1OiV1OiV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrld, "V2iV2iV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrlq, "V1OiV1OiV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psraw, "V4sV4sV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrad, "V2iV2iV1Oi", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psllqi, "V1LLiV1LLii", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psllqi, "V1OiV1Oii", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrlqi, "V1LLiV1LLii", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrlqi, "V1OiV1Oii", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "ncV:64:", "mmx") @@ -138,7 +137,7 @@ TARGET_BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "nV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_movntq, "vV1LLi*V1LLi", "nV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_movntq, "vV1Oi*V1Oi", "nV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "ncV:64:", "mmx") @@ -165,9 +164,9 @@ TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4siIi", "ncV:64:", "mmx,sse") TARGET_BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "ncV:64:", "mmx,sse2") TARGET_BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "ncV:64:", "mmx,sse2") TARGET_BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "ncV:64:", "mmx,sse2") -TARGET_BUILTIN(__builtin_ia32_paddq, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx,sse2") -TARGET_BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "ncV:64:", "mmx,sse2") -TARGET_BUILTIN(__builtin_ia32_psubq, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx,sse2") +TARGET_BUILTIN(__builtin_ia32_paddq, "V1OiV1OiV1Oi", "ncV:64:", "mmx,sse2") +TARGET_BUILTIN(__builtin_ia32_pmuludq, "V1OiV2iV2i", "ncV:64:", "mmx,sse2") +TARGET_BUILTIN(__builtin_ia32_psubq, "V1OiV1OiV1Oi", "ncV:64:", "mmx,sse2") // MMX+SSSE3 TARGET_BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "ncV:64:", "mmx,ssse3") @@ -264,6 +263,8 @@ TARGET_BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "ncV:128:", "sse2") @@ -305,8 +306,6 @@ TARGET_BUILTIN(__builtin_ia32_stmxcsr, "Ui", "n", "sse") TARGET_HEADER_BUILTIN(_mm_getcsr, "Ui", "nh", "xmmintrin.h", ALL_LANGUAGES, "sse") TARGET_BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "ncV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_cvttss2si, "iV4f", "ncV:128:", "sse") -TARGET_BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "nV:128:", "sse") -TARGET_BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "nV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_movmskps, "iV4f", "nV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_sfence, "v", "n", "sse") TARGET_HEADER_BUILTIN(_mm_sfence, "v", "nh", "xmmintrin.h", ALL_LANGUAGES, "sse") @@ -325,11 +324,11 @@ TARGET_BUILTIN(__builtin_ia32_movnti, "vi*i", "n", "sse2") TARGET_BUILTIN(__builtin_ia32_pshufd, "V4iV4iIi", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pshuflw, "V8sV8sIi", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pshufhw, "V8sV8sIi", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_psadbw128, "V2LLiV16cV16c", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_psadbw128, "V2OiV16cV16c", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_sqrtpd, "V2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_shufpd, "V2dV2dV2dIi", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_cvtpd2dq, "V2OiV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "ncV:128:", "sse2") @@ -345,26 +344,26 @@ TARGET_BUILTIN(__builtin_ia32_mfence, "v", "n", "sse2") TARGET_HEADER_BUILTIN(_mm_mfence, "v", "nh", "emmintrin.h", ALL_LANGUAGES, "sse2") TARGET_BUILTIN(__builtin_ia32_pause, "v", "n", "") TARGET_HEADER_BUILTIN(_mm_pause, "v", "nh", "emmintrin.h", ALL_LANGUAGES, "") -TARGET_BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_pmuludq128, "V2OiV4iV4i", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psrlw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psrld128, "V4iV4iV4i", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_psrlq128, "V2LLiV2LLiV2LLi", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_psrlq128, "V2OiV2OiV2Oi", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psllw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pslld128, "V4iV4iV4i", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_psllq128, "V2LLiV2LLiV2LLi", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_psllq128, "V2OiV2OiV2Oi", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psllwi128, "V8sV8si", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pslldi128, "V4iV4ii", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_psllqi128, "V2LLiV2LLii", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_psllqi128, "V2OiV2Oii", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psrlwi128, "V8sV8si", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psrldi128, "V4iV4ii", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_psrlqi128, "V2LLiV2LLii", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_psrlqi128, "V2OiV2Oii", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psrawi128, "V8sV8si", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psradi128, "V4iV4ii", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pmaddwd128, "V4iV8sV8s", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_pslldqi128_byteshift, "V2LLiV2LLiIi", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_psrldqi128_byteshift, "V2LLiV2LLiIi", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_pslldqi128_byteshift, "V2OiV2OiIi", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_psrldqi128_byteshift, "V2OiV2OiIi", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "n", "sse3") TARGET_BUILTIN(__builtin_ia32_mwait, "vUiUi", "n", "sse3") @@ -389,16 +388,16 @@ TARGET_BUILTIN(__builtin_ia32_pminsb128, "V16cV16cV16c", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_pminsd128, "V4iV4iV4i", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_pminud128, "V4iV4iV4i", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_pminuw128, "V8sV8sV8s", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmuldq128, "V2LLiV4iV4i", "ncV:128:", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_pmuldq128, "V2OiV4iV4i", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundps, "V4fV4fIi", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fIi", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2dIi", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundpd, "V2dV2dIi", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fIc", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_dppd, "V2dV2dV2dIc", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "ncV:128:", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_ptestz128, "iV2OiV2Oi", "ncV:128:", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_ptestc128, "iV2OiV2Oi", "ncV:128:", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_ptestnzc128, "iV2OiV2Oi", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16cIc", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_phminposuw128, "V8sV8s", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_vec_ext_v16qi, "cV16cIi", "ncV:128:", "sse4.1") @@ -427,30 +426,30 @@ TARGET_BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "nc", "sse4.2") TARGET_BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "nc", "sse4.2") // SSE4a -TARGET_BUILTIN(__builtin_ia32_extrqi, "V2LLiV2LLiIcIc", "ncV:128:", "sse4a") -TARGET_BUILTIN(__builtin_ia32_extrq, "V2LLiV2LLiV16c", "ncV:128:", "sse4a") -TARGET_BUILTIN(__builtin_ia32_insertqi, "V2LLiV2LLiV2LLiIcIc", "ncV:128:", "sse4a") -TARGET_BUILTIN(__builtin_ia32_insertq, "V2LLiV2LLiV2LLi", "ncV:128:", "sse4a") +TARGET_BUILTIN(__builtin_ia32_extrqi, "V2OiV2OiIcIc", "ncV:128:", "sse4a") +TARGET_BUILTIN(__builtin_ia32_extrq, "V2OiV2OiV16c", "ncV:128:", "sse4a") +TARGET_BUILTIN(__builtin_ia32_insertqi, "V2OiV2OiV2OiIcIc", "ncV:128:", "sse4a") +TARGET_BUILTIN(__builtin_ia32_insertq, "V2OiV2OiV2Oi", "ncV:128:", "sse4a") TARGET_BUILTIN(__builtin_ia32_movntsd, "vd*V2d", "nV:128:", "sse4a") TARGET_BUILTIN(__builtin_ia32_movntss, "vf*V4f", "nV:128:", "sse4a") // AES -TARGET_BUILTIN(__builtin_ia32_aesenc128, "V2LLiV2LLiV2LLi", "ncV:128:", "aes") -TARGET_BUILTIN(__builtin_ia32_aesenclast128, "V2LLiV2LLiV2LLi", "ncV:128:", "aes") -TARGET_BUILTIN(__builtin_ia32_aesdec128, "V2LLiV2LLiV2LLi", "ncV:128:", "aes") -TARGET_BUILTIN(__builtin_ia32_aesdeclast128, "V2LLiV2LLiV2LLi", "ncV:128:", "aes") -TARGET_BUILTIN(__builtin_ia32_aesimc128, "V2LLiV2LLi", "ncV:128:", "aes") -TARGET_BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLiIc", "ncV:128:", "aes") +TARGET_BUILTIN(__builtin_ia32_aesenc128, "V2OiV2OiV2Oi", "ncV:128:", "aes") +TARGET_BUILTIN(__builtin_ia32_aesenclast128, "V2OiV2OiV2Oi", "ncV:128:", "aes") +TARGET_BUILTIN(__builtin_ia32_aesdec128, "V2OiV2OiV2Oi", "ncV:128:", "aes") +TARGET_BUILTIN(__builtin_ia32_aesdeclast128, "V2OiV2OiV2Oi", "ncV:128:", "aes") +TARGET_BUILTIN(__builtin_ia32_aesimc128, "V2OiV2Oi", "ncV:128:", "aes") +TARGET_BUILTIN(__builtin_ia32_aeskeygenassist128, "V2OiV2OiIc", "ncV:128:", "aes") // VAES -TARGET_BUILTIN(__builtin_ia32_aesenc256, "V4LLiV4LLiV4LLi", "ncV:256:", "vaes") -TARGET_BUILTIN(__builtin_ia32_aesenc512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f,vaes") -TARGET_BUILTIN(__builtin_ia32_aesenclast256, "V4LLiV4LLiV4LLi", "ncV:256:", "vaes") -TARGET_BUILTIN(__builtin_ia32_aesenclast512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f,vaes") -TARGET_BUILTIN(__builtin_ia32_aesdec256, "V4LLiV4LLiV4LLi", "ncV:256:", "vaes") -TARGET_BUILTIN(__builtin_ia32_aesdec512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f,vaes") -TARGET_BUILTIN(__builtin_ia32_aesdeclast256, "V4LLiV4LLiV4LLi", "ncV:256:", "vaes") -TARGET_BUILTIN(__builtin_ia32_aesdeclast512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f,vaes") +TARGET_BUILTIN(__builtin_ia32_aesenc256, "V4OiV4OiV4Oi", "ncV:256:", "vaes") +TARGET_BUILTIN(__builtin_ia32_aesenc512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,vaes") +TARGET_BUILTIN(__builtin_ia32_aesenclast256, "V4OiV4OiV4Oi", "ncV:256:", "vaes") +TARGET_BUILTIN(__builtin_ia32_aesenclast512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,vaes") +TARGET_BUILTIN(__builtin_ia32_aesdec256, "V4OiV4OiV4Oi", "ncV:256:", "vaes") +TARGET_BUILTIN(__builtin_ia32_aesdec512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,vaes") +TARGET_BUILTIN(__builtin_ia32_aesdeclast256, "V4OiV4OiV4Oi", "ncV:256:", "vaes") +TARGET_BUILTIN(__builtin_ia32_aesdeclast512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,vaes") // GFNI TARGET_BUILTIN(__builtin_ia32_vgf2p8affineinvqb_v16qi, "V16cV16cV16cIc", "ncV:128:", "gfni") @@ -464,11 +463,11 @@ TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v32qi, "V32cV32cV32c", "ncV:256:", "avx TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v64qi, "V64cV64cV64c", "ncV:512:", "avx512bw,gfni") // CLMUL -TARGET_BUILTIN(__builtin_ia32_pclmulqdq128, "V2LLiV2LLiV2LLiIc", "ncV:128:", "pclmul") +TARGET_BUILTIN(__builtin_ia32_pclmulqdq128, "V2OiV2OiV2OiIc", "ncV:128:", "pclmul") // VPCLMULQDQ -TARGET_BUILTIN(__builtin_ia32_pclmulqdq256, "V4LLiV4LLiV4LLiIc", "ncV:256:", "vpclmulqdq") -TARGET_BUILTIN(__builtin_ia32_pclmulqdq512, "V8LLiV8LLiV8LLiIc", "ncV:512:", "avx512f,vpclmulqdq") +TARGET_BUILTIN(__builtin_ia32_pclmulqdq256, "V4OiV4OiV4OiIc", "ncV:256:", "vpclmulqdq") +TARGET_BUILTIN(__builtin_ia32_pclmulqdq512, "V8OiV8OiV8OiIc", "ncV:512:", "avx512f,vpclmulqdq") // AVX TARGET_BUILTIN(__builtin_ia32_addsubpd256, "V4dV4dV4d", "ncV:256:", "avx") @@ -481,9 +480,9 @@ TARGET_BUILTIN(__builtin_ia32_maxpd256, "V4dV4dV4d", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_maxps256, "V8fV8fV8f", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_minpd256, "V4dV4dV4d", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_minps256, "V8fV8fV8f", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2LLi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2Oi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vpermilvarps, "V4fV4fV4i", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4LLi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4Oi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vpermilvarps256, "V8fV8fV8i", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_blendpd256, "V4dV4dV4dIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_blendps256, "V8fV8fV8fIi", "ncV:256:", "avx") @@ -534,21 +533,21 @@ TARGET_BUILTIN(__builtin_ia32_vtestnzcpd256, "iV4dV4d", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vtestzps256, "iV8fV8f", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vtestcps256, "iV8fV8f", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vtestnzcps256, "iV8fV8f", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_ptestz256, "iV4LLiV4LLi", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_ptestc256, "iV4LLiV4LLi", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_ptestnzc256, "iV4LLiV4LLi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_ptestz256, "iV4OiV4Oi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_ptestc256, "iV4OiV4Oi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_ptestnzc256, "iV4OiV4Oi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_movmskpd256, "iV4d", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_movmskps256, "iV8f", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vzeroall, "v", "n", "avx") TARGET_BUILTIN(__builtin_ia32_vzeroupper, "v", "n", "avx") TARGET_BUILTIN(__builtin_ia32_lddqu256, "V32ccC*", "nV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_maskloadpd, "V2dV2dC*V2LLi", "nV:128:", "avx") +TARGET_BUILTIN(__builtin_ia32_maskloadpd, "V2dV2dC*V2Oi", "nV:128:", "avx") TARGET_BUILTIN(__builtin_ia32_maskloadps, "V4fV4fC*V4i", "nV:128:", "avx") -TARGET_BUILTIN(__builtin_ia32_maskloadpd256, "V4dV4dC*V4LLi", "nV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_maskloadpd256, "V4dV4dC*V4Oi", "nV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_maskloadps256, "V8fV8fC*V8i", "nV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_maskstorepd, "vV2d*V2LLiV2d", "nV:128:", "avx") +TARGET_BUILTIN(__builtin_ia32_maskstorepd, "vV2d*V2OiV2d", "nV:128:", "avx") TARGET_BUILTIN(__builtin_ia32_maskstoreps, "vV4f*V4iV4f", "nV:128:", "avx") -TARGET_BUILTIN(__builtin_ia32_maskstorepd256, "vV4d*V4LLiV4d", "nV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_maskstorepd256, "vV4d*V4OiV4d", "nV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_maskstoreps256, "vV8f*V8iV8f", "nV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vec_ext_v32qi, "cV32cIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vec_ext_v16hi, "sV16sIi", "ncV:256:", "avx") @@ -575,6 +574,8 @@ TARGET_BUILTIN(__builtin_ia32_paddusw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psubusb256, "V32cV32cV32c", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psubusw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_pavgb256, "V32cV32cV32c", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_pavgw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pblendw256, "V16sV16sV16sIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "ncV:256:", "avx2") @@ -598,12 +599,12 @@ TARGET_BUILTIN(__builtin_ia32_pminsb256, "V32cV32cV32c", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pminsw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pminsd256, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmovmskb256, "iV32c", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmuldq256, "V4LLiV8iV8i", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmuldq256, "V4OiV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmulhrsw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmulhuw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmulhw256, "V16sV16sV16s", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmuludq256, "V4LLiV8iV8i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psadbw256, "V4LLiV32cV32c", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmuludq256, "V4OiV8iV8i", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psadbw256, "V4OiV32cV32c", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pshufb256, "V32cV32cV32c", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pshufd256, "V8iV8iIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pshuflw256, "V16sV16sIi", "ncV:256:", "avx2") @@ -613,68 +614,68 @@ TARGET_BUILTIN(__builtin_ia32_psignw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psignd256, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psllwi256, "V16sV16si", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psllw256, "V16sV16sV8s", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pslldqi256_byteshift, "V4LLiV4LLiIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_pslldqi256_byteshift, "V4OiV4OiIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pslldi256, "V8iV8ii", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pslld256, "V8iV8iV4i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psllqi256, "V4LLiV4LLii", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psllq256, "V4LLiV4LLiV2LLi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllqi256, "V4OiV4Oii", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllq256, "V4OiV4OiV2Oi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrawi256, "V16sV16si", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psraw256, "V16sV16sV8s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psradi256, "V8iV8ii", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrad256, "V8iV8iV4i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psrldqi256_byteshift, "V4LLiV4LLiIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrldqi256_byteshift, "V4OiV4OiIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrlwi256, "V16sV16si", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrlw256, "V16sV16sV8s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrldi256, "V8iV8ii", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrld256, "V8iV8iV4i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psrlqi256, "V4LLiV4LLii", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psrlq256, "V4LLiV4LLiV2LLi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlqi256, "V4OiV4Oii", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlq256, "V4OiV4OiV2Oi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pblendd128, "V4iV4iV4iIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pblendd256, "V8iV8iV8iIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_permvarsi256, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_permdf256, "V4dV4dIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_permvarsf256, "V8fV8fV8i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_permti256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_permdi256, "V4LLiV4LLiIi", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_extract128i256, "V2LLiV4LLiIi", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_insert128i256, "V4LLiV4LLiV2LLiIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_permti256, "V4OiV4OiV4OiIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_permdi256, "V4OiV4OiIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_extract128i256, "V2OiV4OiIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_insert128i256, "V4OiV4OiV2OiIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_maskloadd256, "V8iV8iC*V8i", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_maskloadq256, "V4LLiV4LLiC*V4LLi", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskloadq256, "V4OiV4OiC*V4Oi", "nV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_maskloadd, "V4iV4iC*V4i", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_maskloadq, "V2LLiV2LLiC*V2LLi", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskloadq, "V2OiV2OiC*V2Oi", "nV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_maskstored256, "vV8i*V8iV8i", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_maskstoreq256, "vV4LLi*V4LLiV4LLi", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskstoreq256, "vV4Oi*V4OiV4Oi", "nV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_maskstored, "vV4i*V4iV4i", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_maskstoreq, "vV2LLi*V2LLiV2LLi", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskstoreq, "vV2Oi*V2OiV2Oi", "nV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_psllv8si, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psllv4si, "V4iV4iV4i", "ncV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psllv4di, "V4LLiV4LLiV4LLi", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psllv2di, "V2LLiV2LLiV2LLi", "ncV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllv4di, "V4OiV4OiV4Oi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllv2di, "V2OiV2OiV2Oi", "ncV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrav8si, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrav4si, "V4iV4iV4i", "ncV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrlv8si, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrlv4si, "V4iV4iV4i", "ncV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psrlv4di, "V4LLiV4LLiV4LLi", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psrlv2di, "V2LLiV2LLiV2LLi", "ncV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlv4di, "V4OiV4OiV4Oi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlv2di, "V2OiV2OiV2Oi", "ncV:128:", "avx2") // GATHER TARGET_BUILTIN(__builtin_ia32_gatherd_pd, "V2dV2ddC*V4iV2dIc", "nV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_gatherd_pd256, "V4dV4ddC*V4iV4dIc", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_pd, "V2dV2ddC*V2LLiV2dIc", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_pd256, "V4dV4ddC*V4LLiV4dIc", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_pd, "V2dV2ddC*V2OiV2dIc", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_pd256, "V4dV4ddC*V4OiV4dIc", "nV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_gatherd_ps, "V4fV4ffC*V4iV4fIc", "nV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_gatherd_ps256, "V8fV8ffC*V8iV8fIc", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_ps, "V4fV4ffC*V2LLiV4fIc", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_ps256, "V4fV4ffC*V4LLiV4fIc", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_ps, "V4fV4ffC*V2OiV4fIc", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_ps256, "V4fV4ffC*V4OiV4fIc", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherd_q, "V2LLiV2LLiLLiC*V4iV2LLiIc", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherd_q256, "V4LLiV4LLiLLiC*V4iV4LLiIc", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_q, "V2LLiV2LLiLLiC*V2LLiV2LLiIc", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_q256, "V4LLiV4LLiLLiC*V4LLiV4LLiIc", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherd_q, "V2OiV2OiOiC*V4iV2OiIc", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherd_q256, "V4OiV4OiOiC*V4iV4OiIc", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_q, "V2OiV2OiOiC*V2OiV2OiIc", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_q256, "V4OiV4OiOiC*V4OiV4OiIc", "nV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_gatherd_d, "V4iV4iiC*V4iV4iIc", "nV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_gatherd_d256, "V8iV8iiC*V8iV8iIc", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_d, "V4iV4iiC*V2LLiV4iIc", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iiC*V4LLiV4iIc", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_d, "V4iV4iiC*V2OiV4iIc", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iiC*V4OiV4iIc", "nV:256:", "avx2") // F16C TARGET_BUILTIN(__builtin_ia32_vcvtps2ph, "V8sV4fIi", "ncV:128:", "f16c") @@ -691,12 +692,16 @@ TARGET_BUILTIN(__builtin_ia32_fxrstor, "vv*", "n", "fxsr") TARGET_BUILTIN(__builtin_ia32_fxsave, "vv*", "n", "fxsr") // XSAVE -TARGET_BUILTIN(__builtin_ia32_xsave, "vv*ULLi", "n", "xsave") -TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*ULLi", "n", "xsave") -TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*ULLi", "n", "xsaveopt") -TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "n", "xsaves") -TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "n", "xsavec") -TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "n", "xsaves") +TARGET_BUILTIN(__builtin_ia32_xsave, "vv*UOi", "n", "xsave") +TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*UOi", "n", "xsave") +TARGET_BUILTIN(__builtin_ia32_xgetbv, "UOiUi", "n", "xsave") +TARGET_HEADER_BUILTIN(_xgetbv, "UWiUi", "nh", "immintrin.h", ALL_MS_LANGUAGES, "") +TARGET_BUILTIN(__builtin_ia32_xsetbv, "vUiUOi", "n", "xsave") +TARGET_HEADER_BUILTIN(_xsetbv, "vUiUWi", "nh", "immintrin.h", ALL_MS_LANGUAGES, "") +TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*UOi", "n", "xsaveopt") +TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*UOi", "n", "xsaves") +TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*UOi", "n", "xsavec") +TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*UOi", "n", "xsaves") // SHSTK TARGET_BUILTIN(__builtin_ia32_incsspd, "vUi", "n", "shstk") @@ -796,55 +801,55 @@ TARGET_BUILTIN(__builtin_ia32_vpmacsswd, "V4iV8sV8sV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpmacswd, "V4iV8sV8sV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpmacssdd, "V4iV4iV4iV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpmacsdd, "V4iV4iV4iV4i", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpmacssdql, "V2LLiV4iV4iV2LLi", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpmacsdql, "V2LLiV4iV4iV2LLi", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpmacssdqh, "V2LLiV4iV4iV2LLi", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpmacsdqh, "V2LLiV4iV4iV2LLi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacssdql, "V2OiV4iV4iV2Oi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacsdql, "V2OiV4iV4iV2Oi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacssdqh, "V2OiV4iV4iV2Oi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacsdqh, "V2OiV4iV4iV2Oi", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpmadcsswd, "V4iV8sV8sV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpmadcswd, "V4iV8sV8sV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphaddbw, "V8sV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphaddbd, "V4iV16c", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphaddbq, "V2LLiV16c", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddbq, "V2OiV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphaddwd, "V4iV8s", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphaddwq, "V2LLiV8s", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphadddq, "V2LLiV4i", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddwq, "V2OiV8s", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphadddq, "V2OiV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphaddubw, "V8sV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphaddubd, "V4iV16c", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphaddubq, "V2LLiV16c", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddubq, "V2OiV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphadduwd, "V4iV8s", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphadduwq, "V2LLiV8s", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphaddudq, "V2LLiV4i", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphadduwq, "V2OiV8s", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddudq, "V2OiV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphsubbw, "V8sV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphsubwd, "V4iV8s", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphsubdq, "V2LLiV4i", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphsubdq, "V2OiV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpperm, "V16cV16cV16cV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vprotb, "V16cV16cV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vprotw, "V8sV8sV8s", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vprotd, "V4iV4iV4i", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vprotq, "V2LLiV2LLiV2LLi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vprotq, "V2OiV2OiV2Oi", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vprotbi, "V16cV16cIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vprotwi, "V8sV8sIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vprotdi, "V4iV4iIc", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vprotqi, "V2LLiV2LLiIc", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vprotqi, "V2OiV2OiIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpshlb, "V16cV16cV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpshlw, "V8sV8sV8s", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpshld, "V4iV4iV4i", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpshlq, "V2LLiV2LLiV2LLi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpshlq, "V2OiV2OiV2Oi", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpshab, "V16cV16cV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpshaw, "V8sV8sV8s", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpshad, "V4iV4iV4i", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpshaq, "V2LLiV2LLiV2LLi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpshaq, "V2OiV2OiV2Oi", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpcomub, "V16cV16cV16cIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpcomuw, "V8sV8sV8sIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpcomud, "V4iV4iV4iIc", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpcomuq, "V2LLiV2LLiV2LLiIc", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcomuq, "V2OiV2OiV2OiIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpcomb, "V16cV16cV16cIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpcomw, "V8sV8sV8sIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpcomd, "V4iV4iV4iIc", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpcomq, "V2LLiV2LLiV2LLiIc", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpermil2pd, "V2dV2dV2dV2LLiIc", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpermil2pd256, "V4dV4dV4dV4LLiIc", "ncV:256:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcomq, "V2OiV2OiV2OiIc", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpermil2pd, "V2dV2dV2dV2OiIc", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpermil2pd256, "V4dV4dV4dV4OiIc", "ncV:256:", "xop") TARGET_BUILTIN(__builtin_ia32_vpermil2ps, "V4fV4fV4fV4iIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpermil2ps256, "V8fV8fV8fV8iIc", "ncV:256:", "xop") TARGET_BUILTIN(__builtin_ia32_vfrczss, "V4fV4f", "ncV:128:", "xop") @@ -859,10 +864,10 @@ TARGET_BUILTIN(__builtin_ia32_xend, "v", "n", "rtm") TARGET_BUILTIN(__builtin_ia32_xabort, "vIc", "n", "rtm") TARGET_BUILTIN(__builtin_ia32_xtest, "i", "n", "rtm") -BUILTIN(__builtin_ia32_rdpmc, "ULLii", "") -BUILTIN(__builtin_ia32_rdtsc, "ULLi", "") -BUILTIN(__rdtsc, "ULLi", "") -BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "") +BUILTIN(__builtin_ia32_rdpmc, "UOii", "") +BUILTIN(__builtin_ia32_rdtsc, "UOi", "") +BUILTIN(__rdtsc, "UOi", "") +BUILTIN(__builtin_ia32_rdtscp, "UOiUi*", "") TARGET_BUILTIN(__builtin_ia32_rdpid, "Ui", "n", "rdpid") @@ -923,35 +928,35 @@ TARGET_BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcIi", "ncV:512:", "av TARGET_BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fIiV16sUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pabsd512, "V16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pabsq512, "V8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pabsq512, "V8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmaxsd512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmaxsq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmaxsq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmaxud512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmaxuq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmaxuq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pminsd512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pminsq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pminsq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pminud512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pminuq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8LLiV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8LLiV16iV16i", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pminuq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8OiV16iV16i", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8OiV16iV16i", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8OiOiC*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16ffC*V16fUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loadaps512_mask, "V16fV16fC*V16fUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loadupd512_mask, "V8ddC*V8dUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loadapd512_mask, "V8dV8dC*V8dUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_storedqudi512_mask, "vLLi*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_storedqudi512_mask, "vOi*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_storedqusi512_mask, "vi*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_storeupd512_mask, "vd*V8dUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_storeapd512_mask, "vV8d*V8dUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_storeups512_mask, "vf*V16fUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_storeaps512_mask, "vV16f*V16fUs", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_alignq512, "V8LLiV8LLiV8LLiIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_alignq512, "V8OiV8OiV8OiIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_alignd512, "V16iV16iV16iIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_alignd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_alignd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_alignq128, "V2LLiV2LLiV2LLiIi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_alignq256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_alignq128, "V2OiV2OiV2OiIi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_alignq256, "V4OiV4OiV4OiIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_extractf64x4_mask, "V4dV8dIiV4dUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_extractf32x4_mask, "V4fV16fIiV4fUc", "ncV:512:", "avx512f") @@ -968,76 +973,76 @@ TARGET_BUILTIN(__builtin_ia32_vpdpwssds128, "V4iV4iV4iV4i", "ncV:128:", "avx512v TARGET_BUILTIN(__builtin_ia32_vpdpwssds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni") TARGET_BUILTIN(__builtin_ia32_vpdpwssds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni") -TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2dvC*V2LLiUcIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLivC*V2LLiUcIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4dvC*V4LLiUcIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLivC*V4LLiUcIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4fvC*V2LLiUcIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4ivC*V2LLiUcIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4fvC*V4LLiUcIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4ivC*V4LLiUcIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2dvC*V2OiUcIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2OiV2OivC*V2OiUcIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4dvC*V4OiUcIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4OiV4OivC*V4OiUcIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4fvC*V2OiUcIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4ivC*V2OiUcIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4fvC*V4OiUcIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4ivC*V4OiUcIi", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2dvC*V4iUcIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLivC*V4iUcIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2OiV2OivC*V4iUcIi", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4dvC*V4iUcIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLivC*V4iUcIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4OiV4OivC*V4iUcIi", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4fvC*V4iUcIi", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4ivC*V4iUcIi", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8fvC*V8iUcIi", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8ivC*V8iUcIi", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dvC*V8iUcIi", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fvC*V16iUsIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8LLiUcIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8LLiUcIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLivC*V8iUcIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8OiUcIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8OiUcIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8OiV8OivC*V8iUcIi", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16ivC*V16iUsIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLivC*V8LLiUcIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8LLiUcIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8OiV8OivC*V8OiUcIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8OiUcIi", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8dIi", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8LLiV8dIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8LLiV8fIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8LLiIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8OiV8dIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8OiV8fIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8OiIi", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8LLiV8LLiIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8LLiV8iIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8OiV8OiIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8OiV8iIi", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*IiIi", "nV:512:", "avx512pf") TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*IiIi", "nV:512:", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLivC*IiIi", "nV:512:", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLivC*IiIi", "nV:512:", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8OivC*IiIi", "nV:512:", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8OivC*IiIi", "nV:512:", "avx512pf") TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "nV:512:", "avx512pf") TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "nV:512:", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiv*IiIi", "nV:512:", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLiv*IiIi", "nV:512:", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8Oiv*IiIi", "nV:512:", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8Oiv*IiIi", "nV:512:", "avx512pf") TARGET_BUILTIN(__builtin_ia32_knotqi, "UcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_knothi, "UsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_knotsi, "UiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_knotdi, "ULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_knotdi, "UOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_cmpb128_mask, "UsV16cV16cIiUs", "ncV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_cmpd128_mask, "UcV4iV4iIiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_cmpq128_mask, "UcV2LLiV2LLiIiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cmpq128_mask, "UcV2OiV2OiIiUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_cmpw128_mask, "UcV8sV8sIiUc", "ncV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_cmpb256_mask, "UiV32cV32cIiUi", "ncV:256:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_cmpd256_mask, "UcV8iV8iIiUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_cmpq256_mask, "UcV4LLiV4LLiIiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cmpq256_mask, "UcV4OiV4OiIiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_cmpw256_mask, "UsV16sV16sIiUs", "ncV:256:", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_cmpb512_mask, "ULLiV64cV64cIiULLi", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_cmpb512_mask, "UOiV64cV64cIiUOi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_cmpd512_mask, "UsV16iV16iIiUs", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8LLiV8LLiIiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8OiV8OiIiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_cmpw512_mask, "UiV32sV32sIiUi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_ucmpb128_mask, "UsV16cV16cIiUs", "ncV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_ucmpd128_mask, "UcV4iV4iIiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_ucmpq128_mask, "UcV2LLiV2LLiIiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_ucmpq128_mask, "UcV2OiV2OiIiUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_ucmpw128_mask, "UcV8sV8sIiUc", "ncV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_ucmpb256_mask, "UiV32cV32cIiUi", "ncV:256:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_ucmpd256_mask, "UcV8iV8iIiUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_ucmpq256_mask, "UcV4LLiV4LLiIiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_ucmpq256_mask, "UcV4OiV4OiIiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_ucmpw256_mask, "UsV16sV16sIiUs", "ncV:256:", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_ucmpb512_mask, "ULLiV64cV64cIiULLi", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_ucmpb512_mask, "UOiV64cV64cIiUOi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8LLiV8LLiIiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8OiV8OiIiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pabsb512, "V64cV64c", "ncV:512:", "avx512bw") @@ -1050,6 +1055,8 @@ TARGET_BUILTIN(__builtin_ia32_paddsb512, "V64cV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_paddsw512, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_paddusb512, "V64cV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_paddusw512, "V32sV32sV32s", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pavgb512, "V64cV64cV64c", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pavgw512, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmaxsb512, "V64cV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmaxsw512, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmaxub512, "V64cV64cV64c", "ncV:512:", "avx512bw") @@ -1064,21 +1071,21 @@ TARGET_BUILTIN(__builtin_ia32_psubsw512, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psubusb512, "V64cV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psubusw512, "V32sV32sV32s", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_vpconflictdi_128_mask, "V2LLiV2LLiV2LLiUc", "ncV:128:", "avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpconflictdi_256_mask, "V4LLiV4LLiV4LLiUc", "ncV:256:", "avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpconflictsi_128_mask, "V4iV4iV4iUc", "ncV:128:", "avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpconflictsi_256_mask, "V8iV8iV8iUc", "ncV:256:", "avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpconflictdi_512_mask, "V8LLiV8LLiV8LLiUc", "ncV:512:", "avx512cd") -TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512cd") +TARGET_BUILTIN(__builtin_ia32_vpconflictdi_128, "V2OiV2Oi", "ncV:128:", "avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpconflictdi_256, "V4OiV4Oi", "ncV:256:", "avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpconflictsi_128, "V4iV4i", "ncV:128:", "avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpconflictsi_256, "V8iV8i", "ncV:256:", "avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpconflictdi_512, "V8OiV8Oi", "ncV:512:", "avx512cd") +TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512, "V16iV16i", "ncV:512:", "avx512cd") TARGET_BUILTIN(__builtin_ia32_vplzcntd_512, "V16iV16i", "ncV:512:", "avx512cd") -TARGET_BUILTIN(__builtin_ia32_vplzcntq_512, "V8LLiV8LLi", "ncV:512:", "avx512cd") +TARGET_BUILTIN(__builtin_ia32_vplzcntq_512, "V8OiV8Oi", "ncV:512:", "avx512cd") TARGET_BUILTIN(__builtin_ia32_vpopcntd_128, "V4iV4i", "ncV:128:", "avx512vpopcntdq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpopcntq_128, "V2LLiV2LLi", "ncV:128:", "avx512vpopcntdq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpopcntq_128, "V2OiV2Oi", "ncV:128:", "avx512vpopcntdq,avx512vl") TARGET_BUILTIN(__builtin_ia32_vpopcntd_256, "V8iV8i", "ncV:256:", "avx512vpopcntdq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpopcntq_256, "V4LLiV4LLi", "ncV:256:", "avx512vpopcntdq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpopcntq_256, "V4OiV4Oi", "ncV:256:", "avx512vpopcntdq,avx512vl") TARGET_BUILTIN(__builtin_ia32_vpopcntd_512, "V16iV16i", "ncV:512:", "avx512vpopcntdq") -TARGET_BUILTIN(__builtin_ia32_vpopcntq_512, "V8LLiV8LLi", "ncV:512:", "avx512vpopcntdq") +TARGET_BUILTIN(__builtin_ia32_vpopcntq_512, "V8OiV8Oi", "ncV:512:", "avx512vpopcntdq") TARGET_BUILTIN(__builtin_ia32_vpopcntb_128, "V16cV16c", "ncV:128:", "avx512vl,avx512bitalg") TARGET_BUILTIN(__builtin_ia32_vpopcntw_128, "V8sV8s", "ncV:128:", "avx512vl,avx512bitalg") @@ -1089,7 +1096,7 @@ TARGET_BUILTIN(__builtin_ia32_vpopcntw_512, "V32sV32s", "ncV:512:", "avx512bital TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb128_mask, "UsV16cV16cUs", "ncV:128:", "avx512vl,avx512bitalg") TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb256_mask, "UiV32cV32cUi", "ncV:256:", "avx512vl,avx512bitalg") -TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb512_mask, "ULLiV64cV64cULLi", "ncV:512:", "avx512bitalg") +TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb512_mask, "UOiV64cV64cUOi", "ncV:512:", "avx512bitalg") TARGET_BUILTIN(__builtin_ia32_pmulhrsw512, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmulhuw512, "V32sV32sV32s", "ncV:512:", "avx512bw") @@ -1122,8 +1129,8 @@ TARGET_BUILTIN(__builtin_ia32_minsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", TARGET_BUILTIN(__builtin_ia32_compressdf128_mask, "V2dV2dV2dUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compressdf256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_compressdi128_mask, "V2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_compressdi256_mask, "V4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressdi128_mask, "V2OiV2OiV2OiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressdi256_mask, "V4OiV4OiV4OiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compresshi128_mask, "V8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_compresshi256_mask, "V16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2") @@ -1136,8 +1143,8 @@ TARGET_BUILTIN(__builtin_ia32_compresssi128_mask, "V4iV4iV4iUc", "ncV:128:", "av TARGET_BUILTIN(__builtin_ia32_compresssi256_mask, "V8iV8iV8iUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compressstoredf128_mask, "vV2d*V2dUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compressstoredf256_mask, "vV4d*V4dUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_compressstoredi128_mask, "vV2LLi*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_compressstoredi256_mask, "vV4LLi*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressstoredi128_mask, "vV2Oi*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressstoredi256_mask, "vV4Oi*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compressstorehi128_mask, "vV8s*V8sUc", "nV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_compressstorehi256_mask, "vV16s*V16sUs", "nV:256:", "avx512vl,avx512vbmi2") @@ -1161,8 +1168,8 @@ TARGET_BUILTIN(__builtin_ia32_cvttps2udq128_mask, "V4iV4fV4iUc", "ncV:128:", "av TARGET_BUILTIN(__builtin_ia32_cvttps2udq256_mask, "V8iV8fV8iUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expanddf128_mask, "V2dV2dV2dUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expanddf256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_expanddi128_mask, "V2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_expanddi256_mask, "V4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expanddi128_mask, "V2OiV2OiV2OiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expanddi256_mask, "V4OiV4OiV4OiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expandhi128_mask, "V8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_expandhi256_mask, "V16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2") @@ -1171,8 +1178,8 @@ TARGET_BUILTIN(__builtin_ia32_expandqi256_mask, "V32cV32cV32cUi", "ncV:256:", "a TARGET_BUILTIN(__builtin_ia32_expandloaddf128_mask, "V2dV2dC*V2dUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expandloaddf256_mask, "V4dV4dC*V4dUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_expandloaddi128_mask, "V4iV2LLiC*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_expandloaddi256_mask, "V4LLiV4LLiC*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandloaddi128_mask, "V4iV2OiC*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandloaddi256_mask, "V4OiV4OiC*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expandloadhi128_mask, "V8sV8sC*V8sUc", "nV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_expandloadhi256_mask, "V16sV16sC*V16sUs", "nV:256:", "avx512vl,avx512vbmi2") @@ -1191,16 +1198,16 @@ TARGET_BUILTIN(__builtin_ia32_getexppd128_mask, "V2dV2dV2dUc", "ncV:128:", "avx5 TARGET_BUILTIN(__builtin_ia32_getexppd256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_getexpps128_mask, "V4fV4fV4fUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_getexpps256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pabsq128, "V2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pabsq256, "V4LLiV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmaxsq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmaxsq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmaxuq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmaxuq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pminsq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pminsq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pminuq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pminuq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pabsq128, "V2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pabsq256, "V4OiV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxsq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxsq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxuq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxuq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminsq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminsq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminuq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminuq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rndscalepd_128_mask, "V2dV2dIiV2dUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rndscalepd_256_mask, "V4dV4dIiV4dUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rndscaleps_128_mask, "V4fV4fIiV4fUc", "ncV:128:", "avx512vl") @@ -1210,18 +1217,18 @@ TARGET_BUILTIN(__builtin_ia32_scalefpd256_mask, "V4dV4dV4dV4dUc", "ncV:256:", "a TARGET_BUILTIN(__builtin_ia32_scalefps128_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scalefps256_mask, "V8fV8fV8fV8fUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vv*UcV2LLiV2dIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vv*UcV2LLiV2LLiIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vv*UcV4LLiV4dIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vv*UcV4LLiV4LLiIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vv*UcV2LLiV4fIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vv*UcV2LLiV4iIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vv*UcV4LLiV4fIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vv*UcV4LLiV4iIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vv*UcV2OiV2dIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vv*UcV2OiV2OiIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vv*UcV4OiV4dIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vv*UcV4OiV4OiIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vv*UcV2OiV4fIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vv*UcV2OiV4iIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vv*UcV4OiV4fIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vv*UcV4OiV4iIi", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vv*UcV4iV2dIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vv*UcV4iV2LLiIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vv*UcV4iV2OiIi", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vv*UcV4iV4dIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vv*UcV4iV4LLiIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vv*UcV4iV4OiIi", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vv*UcV4iV4fIi", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vv*UcV4iV4iIi", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vv*UcV8iV8fIi", "nV:256:", "avx512vl") @@ -1230,15 +1237,15 @@ TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vv*UcV8iV8iIi", "nV:256:", "avx512 TARGET_BUILTIN(__builtin_ia32_vpermi2vard128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_vpermi2vard256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_vpermi2vard512, "V16iV16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vpermi2varpd128, "V2dV2dV2LLiV2d", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpermi2varpd256, "V4dV4dV4LLiV4d", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpermi2varpd512, "V8dV8dV8LLiV8d", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermi2varpd128, "V2dV2dV2OiV2d", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varpd256, "V4dV4dV4OiV4d", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varpd512, "V8dV8dV8OiV8d", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermi2varps128, "V4fV4fV4iV4f", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_vpermi2varps256, "V8fV8fV8iV8f", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_vpermi2varps512, "V16fV16fV16iV16f", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vpermi2varq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpermi2varq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpermi2varq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermi2varq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermi2varqi128, "V16cV16cV16cV16c", "ncV:128:", "avx512vbmi,avx512vl") TARGET_BUILTIN(__builtin_ia32_vpermi2varqi256, "V32cV32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl") TARGET_BUILTIN(__builtin_ia32_vpermi2varqi512, "V64cV64cV64cV64c", "ncV:512:", "avx512vbmi") @@ -1249,9 +1256,9 @@ TARGET_BUILTIN(__builtin_ia32_vpermi2varhi512, "V32sV32sV32sV32s", "ncV:512:", " TARGET_BUILTIN(__builtin_ia32_vpshldd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldd512, "V16iV16iV16iIi", "ncV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshldq128, "V2LLiV2LLiV2LLiIi", "ncV:128:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshldq256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshldq512, "V8LLiV8LLiV8LLiIi", "ncV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshldq128, "V2OiV2OiV2OiIi", "ncV:128:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshldq256, "V4OiV4OiV4OiIi", "ncV:256:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshldq512, "V8OiV8OiV8OiIi", "ncV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2") @@ -1259,9 +1266,9 @@ TARGET_BUILTIN(__builtin_ia32_vpshldw512, "V32sV32sV32sIi", "ncV:512:", "avx512v TARGET_BUILTIN(__builtin_ia32_vpshldvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshldvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshldvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshldvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshldvq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshldvq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshldvq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2") @@ -1269,9 +1276,9 @@ TARGET_BUILTIN(__builtin_ia32_vpshldvw512, "V32sV32sV32sV32s", "ncV:512:", "avx5 TARGET_BUILTIN(__builtin_ia32_vpshrdvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshrdvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshrdvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshrdvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshrdvq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshrdvq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshrdvq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2") @@ -1279,9 +1286,9 @@ TARGET_BUILTIN(__builtin_ia32_vpshrdvw512, "V32sV32sV32sV32s", "ncV:512:", "avx5 TARGET_BUILTIN(__builtin_ia32_vpshrdd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdd512, "V16iV16iV16iIi", "ncV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshrdq128, "V2LLiV2LLiV2LLiIi", "ncV:128:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshrdq256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshrdq512, "V8LLiV8LLiV8LLiIi", "ncV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshrdq128, "V2OiV2OiV2OiIi", "ncV:128:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshrdq256, "V4OiV4OiV4OiIi", "ncV:256:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshrdq512, "V8OiV8OiV8OiIi", "ncV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2") @@ -1289,26 +1296,24 @@ TARGET_BUILTIN(__builtin_ia32_vpshrdw512, "V32sV32sV32sIi", "ncV:512:", "avx512v TARGET_BUILTIN(__builtin_ia32_pmovswb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovuswb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovwb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_cvtpd2qq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtpd2qq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtps2qq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtps2qq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtps2uqq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtps2uqq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtqq2ps128_mask, "V4fV2LLiV4fUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtqq2ps256_mask, "V4fV4LLiV4fUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttpd2qq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttpd2qq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttps2qq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttps2qq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttps2uqq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttps2uqq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps128_mask, "V4fV2LLiV4fUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps256_mask, "V4fV4LLiV4fUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtpd2qq128_mask, "V2OiV2dV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtpd2qq256_mask, "V4OiV4dV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq128_mask, "V2OiV2dV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq256_mask, "V4OiV4dV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2qq128_mask, "V2OiV4fV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2qq256_mask, "V4OiV4fV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2uqq128_mask, "V2OiV4fV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2uqq256_mask, "V4OiV4fV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtqq2ps128_mask, "V4fV2OiV4fUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2qq128_mask, "V2OiV2dV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2qq256_mask, "V4OiV4dV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq128_mask, "V2OiV2dV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq256_mask, "V4OiV4dV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2qq128_mask, "V2OiV4fV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2qq256_mask, "V4OiV4fV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2uqq128_mask, "V2OiV4fV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2uqq256_mask, "V4OiV4fV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps128_mask, "V4fV2OiV4fUc", "ncV:128:", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_rangepd128_mask, "V2dV2dV2dIiV2dUc", "ncV:128:", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_rangepd256_mask, "V4dV4dV4dIiV4dUc", "ncV:256:", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_rangeps128_mask, "V4fV4fV4fIiV4fUc", "ncV:128:", "avx512vl,avx512dq") @@ -1326,46 +1331,46 @@ TARGET_BUILTIN(__builtin_ia32_pmovswb256_mask, "V16cV16sV16cUs", "ncV:256:", "av TARGET_BUILTIN(__builtin_ia32_pmovuswb128_mask, "V16cV8sV16cUc", "ncV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovuswb256_mask, "V16cV16sV16cUs", "ncV:256:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovwb128_mask, "V16cV8sV16cUc", "ncV:128:", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_cvtpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtps2qq512_mask, "V8LLiV8fV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtps2uqq512_mask, "V8LLiV8fV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtqq2pd512_mask, "V8dV8LLiV8dUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtqq2ps512_mask, "V8fV8LLiV8fUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttps2qq512_mask, "V8LLiV8fV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttps2uqq512_mask, "V8LLiV8fV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd512_mask, "V8dV8LLiV8dUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps512_mask, "V8fV8LLiV8fUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtpd2qq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2qq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2uqq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtqq2pd512_mask, "V8dV8OiV8dUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtqq2ps512_mask, "V8fV8OiV8fUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2qq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2qq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2uqq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd512_mask, "V8dV8OiV8dUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps512_mask, "V8fV8OiV8fUcIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_rangepd512_mask, "V8dV8dV8dIiV8dUcIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_rangeps512_mask, "V16fV16fV16fIiV16fUsIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_reducepd512_mask, "V8dV8dIiV8dUcIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_reduceps512_mask, "V16fV16fIiV16fUsIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_prold512, "V16iV16iIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_prolq512, "V8LLiV8LLiIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_prolq512, "V8OiV8OiIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_prold128, "V4iV4iIi", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prold256, "V8iV8iIi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prolq128, "V2LLiV2LLiIi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prolq256, "V4LLiV4LLiIi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolq128, "V2OiV2OiIi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolq256, "V4OiV4OiIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prolvd512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_prolvq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_prolvq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_prord512, "V16iV16iIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_prorq512, "V8LLiV8LLiIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_prorq512, "V8OiV8OiIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_prolvd128, "V4iV4iV4i", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prolvd256, "V8iV8iV8i", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prolvq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prolvq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolvq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolvq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prord128, "V4iV4iIi", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prord256, "V8iV8iIi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prorq128, "V2LLiV2LLiIi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prorq256, "V4LLiV4LLiIi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorq128, "V2OiV2OiIi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorq256, "V4OiV4OiIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prorvd512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_prorvq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_prorvq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_prorvd128, "V4iV4iV4i", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prorvd256, "V8iV8iV8i", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prorvq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prorvq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorvq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorvq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pshufhw512, "V32sV32sIi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pshuflw512, "V32sV32sIi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psllv32hi, "V32sV32sV32s", "ncV:512:", "avx512bw") @@ -1374,53 +1379,53 @@ TARGET_BUILTIN(__builtin_ia32_psllwi512, "V32sV32si", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psllv16hi, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_psllv8hi, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_pslldi512, "V16iV16ii", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psllqi512, "V8LLiV8LLii", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psllqi512, "V8OiV8Oii", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psrlv32hi, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psrlv16hi, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_psrlv8hi, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_psrldi512, "V16iV16ii", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psrlqi512, "V8LLiV8LLii", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psrlqi512, "V8OiV8Oii", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psrav32hi, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psrav16hi, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_psrav8hi, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl") -TARGET_BUILTIN(__builtin_ia32_psravq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_psravq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psravq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psravq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_psraw512, "V32sV32sV8s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psrawi512, "V32sV32si", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psrlw512, "V32sV32sV8s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psrlwi512, "V32sV32si", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pslldqi512_byteshift, "V8LLiV8LLiIi", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_psrldqi512_byteshift, "V8LLiV8LLiIi", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pslldqi512_byteshift, "V8OiV8OiIi", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_psrldqi512_byteshift, "V8OiV8OiIi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_movdqa32load128_mask, "V4iV4i*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_movdqa32load256_mask, "V8iV8i*V8iUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_movdqa32load512_mask, "V16iV16iC*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_movdqa32store512_mask, "vV16i*V16iUs", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_movdqa64load512_mask, "V8LLiV8LLiC*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_movdqa64store512_mask, "vV8LLi*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa64load512_mask, "V8OiV8OiC*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa64store512_mask, "vV8Oi*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_movdqa32store128_mask, "vV4i*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_movdqa32store256_mask, "vV8i*V8iUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_movdqa64load128_mask, "V2LLiV2LLiC*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_movdqa64load256_mask, "V4LLiV4LLiC*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_movdqa64store128_mask, "vV2LLi*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_movdqa64store256_mask, "vV4LLi*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512ifma") -TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512ifma") -TARGET_BUILTIN(__builtin_ia32_vpmadd52huq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512ifma,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpmadd52huq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512ifma,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpmadd52luq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512ifma,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpmadd52luq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_movdqa64load128_mask, "V2OiV2OiC*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_movdqa64load256_mask, "V4OiV4OiC*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_movdqa64store128_mask, "vV2Oi*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_movdqa64store256_mask, "vV4Oi*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512ifma") +TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512ifma") +TARGET_BUILTIN(__builtin_ia32_vpmadd52huq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52huq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52luq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52luq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512ifma,avx512vl") TARGET_BUILTIN(__builtin_ia32_vcomisd, "iV2dV2dIiIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcomiss, "iV4fV4fIiIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_kunpckdi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kunpckdi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kunpcksi, "UiUiUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_loaddquhi512_mask, "V32sV32s*V32sUi", "nV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_loaddquqi512_mask, "V64cV64c*V64cULLi", "nV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_mask, "V8dV8dV8dV8LLiIiUcIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_maskz, "V8dV8dV8dV8LLiIiUcIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_loaddquqi512_mask, "V64cV64c*V64cUOi", "nV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_mask, "V8dV8dV8dV8OiIiUcIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_maskz, "V8dV8dV8dV8OiIiUcIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_fixupimmps512_mask, "V16fV16fV16fV16iIiUsIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_fixupimmps512_maskz, "V16fV16fV16fV16iIiUsIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_fixupimmsd_mask, "V2dV2dV2dV2LLiIiUcIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_fixupimmsd_maskz, "V2dV2dV2dV2LLiIiUcIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmsd_mask, "V2dV2dV2dV2OiIiUcIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmsd_maskz, "V2dV2dV2dV2OiIiUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_fixupimmss_mask, "V4fV4fV4fV4iIiUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_fixupimmss_maskz, "V4fV4fV4fV4iIiUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_getexpsd128_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f") @@ -1431,10 +1436,10 @@ TARGET_BUILTIN(__builtin_ia32_loaddquhi128_mask, "V8sV8s*V8sUc", "nV:128:", "avx TARGET_BUILTIN(__builtin_ia32_loaddquhi256_mask, "V16sV16s*V16sUs", "nV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_loaddquqi128_mask, "V16cV16c*V16cUs", "nV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_loaddquqi256_mask, "V32cV32c*V32cUi", "nV:256:", "avx512bw,avx512vl") -TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_mask, "V2dV2dV2dV2LLiIiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_maskz, "V2dV2dV2dV2LLiIiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_mask, "V4dV4dV4dV4LLiIiUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_maskz, "V4dV4dV4dV4LLiIiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_mask, "V2dV2dV2dV2OiIiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_maskz, "V2dV2dV2dV2OiIiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_mask, "V4dV4dV4dV4OiIiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_maskz, "V4dV4dV4dV4OiIiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_fixupimmps128_mask, "V4fV4fV4fV4iIiUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_fixupimmps128_maskz, "V4fV4fV4fV4iIiUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_fixupimmps256_mask, "V8fV8fV8fV8iIiUc", "ncV:256:", "avx512vl") @@ -1445,8 +1450,8 @@ TARGET_BUILTIN(__builtin_ia32_loadapd256_mask, "V4dV4d*V4dUc", "nV:256:", "avx51 TARGET_BUILTIN(__builtin_ia32_loadaps128_mask, "V4fV4f*V4fUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_loadss128_mask, "V4fV4f*V4fUc", "nV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loadaps256_mask, "V8fV8f*V8fUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_loaddqudi128_mask, "V2LLiV2LLi*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_loaddqudi256_mask, "V4LLiV4LLi*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_loaddqudi128_mask, "V2OiV2Oi*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_loaddqudi256_mask, "V4OiV4Oi*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_loaddqusi128_mask, "V4iV4i*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_loaddqusi256_mask, "V8iV8i*V8iUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_loadupd128_mask, "V2dV2d*V2dUc", "nV:128:", "avx512vl") @@ -1454,7 +1459,7 @@ TARGET_BUILTIN(__builtin_ia32_loadupd256_mask, "V4dV4d*V4dUc", "nV:256:", "avx51 TARGET_BUILTIN(__builtin_ia32_loadups128_mask, "V4fV4f*V4fUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_loadups256_mask, "V8fV8f*V8fUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_storedquhi512_mask, "vV32s*V32sUi", "nV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_storedquqi512_mask, "vV64c*V64cULLi", "nV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_storedquqi512_mask, "vV64c*V64cUOi", "nV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_storedquhi128_mask, "vV8s*V8sUc", "nV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_storedquhi256_mask, "vV16s*V16sUs", "nV:256:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_storedquqi128_mask, "vV16c*V16cUs", "nV:128:", "avx512vl,avx512bw") @@ -1465,8 +1470,8 @@ TARGET_BUILTIN(__builtin_ia32_storeapd256_mask, "vV4d*V4dUc", "nV:256:", "avx512 TARGET_BUILTIN(__builtin_ia32_storeaps128_mask, "vV4f*V4fUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_storess128_mask, "vV4f*V4fUc", "nV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_storeaps256_mask, "vV8f*V8fUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_storedqudi128_mask, "vV2LLi*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_storedqudi256_mask, "vV4LLi*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_storedqudi128_mask, "vV2Oi*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_storedqudi256_mask, "vV4Oi*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_storedqusi128_mask, "vV4i*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_storedqusi256_mask, "vV8i*V8iUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_storeupd128_mask, "vV2d*V2dUc", "nV:128:", "avx512vl") @@ -1479,8 +1484,8 @@ TARGET_BUILTIN(__builtin_ia32_rcp14ps128_mask, "V4fV4fV4fUc", "ncV:128:", "avx51 TARGET_BUILTIN(__builtin_ia32_rcp14ps256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_vplzcntd_128, "V4iV4i", "ncV:128:", "avx512cd,avx512vl") TARGET_BUILTIN(__builtin_ia32_vplzcntd_256, "V8iV8i", "ncV:256:", "avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vplzcntq_128, "V2LLiV2LLi", "ncV:128:", "avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vplzcntq_256, "V4LLiV4LLi", "ncV:256:", "avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vplzcntq_128, "V2OiV2Oi", "ncV:128:", "avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vplzcntq_256, "V4OiV4Oi", "ncV:256:", "avx512cd,avx512vl") TARGET_BUILTIN(__builtin_ia32_vcvtsd2si32, "iV2dIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi32, "UiV2dIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtss2si32, "iV4fIi", "ncV:128:", "avx512f") @@ -1491,7 +1496,7 @@ TARGET_BUILTIN(__builtin_ia32_vcvttss2si32, "iV4fIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvttss2usi32, "UiV4fIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermilpd512, "V8dV8dIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermilps512, "V16fV16fIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512, "V8dV8dV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512, "V8dV8dV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermilvarps512, "V16fV16fV16i", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_rndscalesd_round_mask, "V2dV2dV2dV2dUcIiIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_rndscaless_round_mask, "V4fV4fV4fV4fUcIiIi", "ncV:128:", "avx512f") @@ -1500,58 +1505,58 @@ TARGET_BUILTIN(__builtin_ia32_scalefps512_mask, "V16fV16fV16fV16fUsIi", "ncV:512 TARGET_BUILTIN(__builtin_ia32_scalefsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_scalefss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psradi512, "V16iV16ii", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psraqi512, "V8LLiV8LLii", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psraq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_psraq256, "V4LLiV4LLiV2LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_psraqi128, "V2LLiV2LLii", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_psraqi256, "V4LLiV4LLii", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraqi512, "V8OiV8Oii", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psraq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraq256, "V4OiV4OiV2Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraqi128, "V2OiV2Oii", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraqi256, "V4OiV4Oii", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pslld512, "V16iV16iV4i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psllq512, "V8LLiV8LLiV2LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psllq512, "V8OiV8OiV2Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psllv16si, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psllv8di, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psllv8di, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psrad512, "V16iV16iV4i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psraq512, "V8LLiV8LLiV2LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psraq512, "V8OiV8OiV2Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psrav16si, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psrav8di, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psrav8di, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psrld512, "V16iV16iV4i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psrlq512, "V8LLiV8LLiV2LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psrlq512, "V8OiV8OiV2Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psrlv16si, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psrlv8di, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psrlv8di, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pternlogd512_mask, "V16iV16iV16iV16iIiUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pternlogd512_maskz, "V16iV16iV16iV16iIiUs", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pternlogq512_mask, "V8LLiV8LLiV8LLiV8LLiIiUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pternlogq512_maskz, "V8LLiV8LLiV8LLiV8LLiIiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pternlogq512_mask, "V8OiV8OiV8OiV8OiIiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pternlogq512_maskz, "V8OiV8OiV8OiV8OiIiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pternlogd128_mask, "V4iV4iV4iV4iIiUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pternlogd128_maskz, "V4iV4iV4iV4iIiUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pternlogd256_mask, "V8iV8iV8iV8iIiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pternlogd256_maskz, "V8iV8iV8iV8iIiUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pternlogq128_mask, "V2LLiV2LLiV2LLiV2LLiIiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pternlogq128_maskz, "V2LLiV2LLiV2LLiV2LLiIiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pternlogq256_mask, "V4LLiV4LLiV4LLiV4LLiIiUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pternlogq256_maskz, "V4LLiV4LLiV4LLiV4LLiIiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogq128_mask, "V2OiV2OiV2OiV2OiIiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogq128_maskz, "V2OiV2OiV2OiV2OiIiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogq256_mask, "V4OiV4OiV4OiV4OiIiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogq256_maskz, "V4OiV4OiV4OiV4OiIiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_shuf_f32x4, "V16fV16fV16fIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_shuf_f64x2, "V8dV8dV8dIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_shuf_i32x4, "V16iV16iV16iIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_shuf_i64x2, "V8LLiV8LLiV8LLiIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_shuf_i64x2, "V8OiV8OiV8OiIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_shufpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_shufps512, "V16fV16fV16fIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_shuf_f32x4_256, "V8fV8fV8fIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_shuf_f64x2_256, "V4dV4dV4dIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_shuf_i32x4_256, "V8iV8iV8iIi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_shuf_i64x2_256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_shuf_i64x2_256, "V4OiV4OiV4OiIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_sqrtsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_sqrtss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_rsqrt14pd128_mask, "V2dV2dV2dUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rsqrt14pd256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rsqrt14ps128_mask, "V4fV4fV4fUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rsqrt14ps256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_cvtb2mask512, "ULLiV64c", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_cvtmask2b512, "V64cULLi", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_cvtb2mask512, "UOiV64c", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_cvtmask2b512, "V64cUOi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_cvtmask2w512, "V32sUi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_cvtd2mask512, "UsV16i", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtmask2d512, "V16iUs", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtmask2q512, "V8LLiUc", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtq2mask512, "UcV8LLi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtmask2q512, "V8OiUc", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtq2mask512, "UcV8Oi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtb2mask128, "UsV16c", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_cvtb2mask256, "UiV32c", "ncV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_cvtmask2b128, "V16cUs", "ncV:128:", "avx512bw,avx512vl") @@ -1562,21 +1567,21 @@ TARGET_BUILTIN(__builtin_ia32_cvtd2mask128, "UcV4i", "ncV:128:", "avx512dq,avx51 TARGET_BUILTIN(__builtin_ia32_cvtd2mask256, "UcV8i", "ncV:256:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_cvtmask2d128, "V4iUc", "ncV:128:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_cvtmask2d256, "V8iUc", "ncV:256:", "avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_cvtmask2q128, "V2LLiUc", "ncV:128:", "avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_cvtmask2q256, "V4LLiUc", "ncV:256:", "avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2LLi", "ncV:128:", "avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4LLi", "ncV:256:", "avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtmask2q128, "V2OiUc", "ncV:128:", "avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtmask2q256, "V4OiUc", "ncV:256:", "avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2Oi", "ncV:128:", "avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4Oi", "ncV:256:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovsdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovsdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovswb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovsdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovsdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovsqb512_mask, "V16cV8LLiV16cUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovsqb512mem_mask, "vV16c*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovsqd512_mask, "V8iV8LLiV8iUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovsqd512mem_mask, "vV8i*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovsqw512_mask, "V8sV8LLiV8sUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovsqw512mem_mask, "vV8s*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqb512_mask, "V16cV8OiV16cUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqb512mem_mask, "vV16c*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqd512_mask, "V8iV8OiV8iUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqd512mem_mask, "vV8i*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqw512_mask, "V8sV8OiV8sUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqw512mem_mask, "vV8s*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovsdb128_mask, "V16cV4iV16cUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovsdb128mem_mask, "vV16c*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovswb128mem_mask, "vV16c*V8sUc", "nV:128:", "avx512vl,avx512bw") @@ -1587,29 +1592,29 @@ TARGET_BUILTIN(__builtin_ia32_pmovsdw128_mask, "V8sV4iV8sUc", "ncV:128:", "avx51 TARGET_BUILTIN(__builtin_ia32_pmovsdw128mem_mask, "vV8s*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovsdw256_mask, "V8sV8iV8sUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovsdw256mem_mask, "vV8s*V8iUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqb128_mask, "V16cV2LLiV16cUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqb128mem_mask, "vV16c*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqb256_mask, "V16cV4LLiV16cUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqb256mem_mask, "vV16c*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqd128_mask, "V4iV2LLiV4iUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqd128mem_mask, "vV4i*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqd256_mask, "V4iV4LLiV4iUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqd256mem_mask, "vV4i*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqw128_mask, "V8sV2LLiV8sUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqw128mem_mask, "vV8s*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqw256_mask, "V8sV4LLiV8sUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqw256mem_mask, "vV8s*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqb128_mask, "V16cV2OiV16cUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqb128mem_mask, "vV16c*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqb256_mask, "V16cV4OiV16cUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqb256mem_mask, "vV16c*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqd128_mask, "V4iV2OiV4iUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqd128mem_mask, "vV4i*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqd256_mask, "V4iV4OiV4iUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqd256mem_mask, "vV4i*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqw128_mask, "V8sV2OiV8sUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqw128mem_mask, "vV8s*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqw256_mask, "V8sV4OiV8sUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqw256mem_mask, "vV8s*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovusdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovusdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovuswb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovusdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovusdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovusqb512_mask, "V16cV8LLiV16cUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovusqb512mem_mask, "vV16c*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovusqd512_mask, "V8iV8LLiV8iUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovusqd512mem_mask, "vV8i*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovusqw512_mask, "V8sV8LLiV8sUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovusqw512mem_mask, "vV8s*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqb512_mask, "V16cV8OiV16cUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqb512mem_mask, "vV16c*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqd512_mask, "V8iV8OiV8iUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqd512mem_mask, "vV8i*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqw512_mask, "V8sV8OiV8sUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqw512mem_mask, "vV8s*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovusdb128_mask, "V16cV4iV16cUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovusdb128mem_mask, "vV16c*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovuswb128mem_mask, "vV16c*V8sUc", "nV:128:", "avx512vl,avx512bw") @@ -1620,29 +1625,29 @@ TARGET_BUILTIN(__builtin_ia32_pmovusdw128_mask, "V8sV4iV8sUc", "ncV:128:", "avx5 TARGET_BUILTIN(__builtin_ia32_pmovusdw128mem_mask, "vV8s*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovusdw256_mask, "V8sV8iV8sUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovusdw256mem_mask, "vV8s*V8iUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqb128_mask, "V16cV2LLiV16cUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqb128mem_mask, "vV16c*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqb256_mask, "V16cV4LLiV16cUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqb256mem_mask, "vV16c*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqd128_mask, "V4iV2LLiV4iUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqd128mem_mask, "vV4i*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqd256_mask, "V4iV4LLiV4iUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqd256mem_mask, "vV4i*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqw128_mask, "V8sV2LLiV8sUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqw128mem_mask, "vV8s*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqw256_mask, "V8sV4LLiV8sUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqw256mem_mask, "vV8s*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqb128_mask, "V16cV2OiV16cUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqb128mem_mask, "vV16c*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqb256_mask, "V16cV4OiV16cUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqb256mem_mask, "vV16c*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqd128_mask, "V4iV2OiV4iUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqd128mem_mask, "vV4i*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqd256_mask, "V4iV4OiV4iUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqd256mem_mask, "vV4i*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqw128_mask, "V8sV2OiV8sUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqw128mem_mask, "vV8s*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqw256_mask, "V8sV4OiV8sUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqw256mem_mask, "vV8s*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovwb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqb512_mask, "V16cV8LLiV16cUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqb512mem_mask, "vV16c*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqd512_mask, "V8iV8LLiV8iUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqd512mem_mask, "vV8i*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqw512_mask, "V8sV8LLiV8sUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqw512mem_mask, "vV8s*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqb512_mask, "V16cV8OiV16cUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqb512mem_mask, "vV16c*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqd512_mask, "V8iV8OiV8iUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqd512mem_mask, "vV8i*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqw512_mask, "V8sV8OiV8sUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqw512mem_mask, "vV8s*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovdb128_mask, "V16cV4iV16cUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovwb128mem_mask, "vV16c*V8sUc", "nV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovdb128mem_mask, "vV16c*V4iUc", "nV:128:", "avx512vl") @@ -1653,35 +1658,35 @@ TARGET_BUILTIN(__builtin_ia32_pmovdw128_mask, "V8sV4iV8sUc", "ncV:128:", "avx512 TARGET_BUILTIN(__builtin_ia32_pmovdw128mem_mask, "vV8s*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovdw256_mask, "V8sV8iV8sUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovdw256mem_mask, "vV8s*V8iUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqb128_mask, "V16cV2LLiV16cUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqb128mem_mask, "vV16c*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqb256_mask, "V16cV4LLiV16cUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqb256mem_mask, "vV16c*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqd128_mask, "V4iV2LLiV4iUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqd128mem_mask, "vV4i*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqd256mem_mask, "vV4i*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqw128_mask, "V8sV2LLiV8sUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqw128mem_mask, "vV8s*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqw256_mask, "V8sV4LLiV8sUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqw256mem_mask, "vV8s*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqb128_mask, "V16cV2OiV16cUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqb128mem_mask, "vV16c*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqb256_mask, "V16cV4OiV16cUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqb256mem_mask, "vV16c*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqd128_mask, "V4iV2OiV4iUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqd128mem_mask, "vV4i*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqd256mem_mask, "vV4i*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqw128_mask, "V8sV2OiV8sUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqw128mem_mask, "vV8s*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqw256_mask, "V8sV4OiV8sUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqw256mem_mask, "vV8s*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_extractf32x8_mask, "V8fV16fIiV8fUc", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_extractf64x2_512_mask, "V2dV8dIiV2dUc", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_extracti32x8_mask, "V8iV16iIiV8iUc", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_extracti64x2_512_mask, "V2LLiV8LLiIiV2LLiUc", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_extracti64x2_512_mask, "V2OiV8OiIiV2OiUc", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_extracti32x4_mask, "V4iV16iIiV4iUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_extracti64x4_mask, "V4LLiV8LLiIiV4LLiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_extracti64x4_mask, "V4OiV8OiIiV4OiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_extractf64x2_256_mask, "V2dV4dIiV2dUc", "ncV:256:", "avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_extracti64x2_256_mask, "V2LLiV4LLiIiV2LLiUc", "ncV:256:", "avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_extracti64x2_256_mask, "V2OiV4OiIiV2OiUc", "ncV:256:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_extractf32x4_256_mask, "V4fV8fIiV4fUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_extracti32x4_256_mask, "V4iV8iIiV4iUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_insertf32x8, "V16fV16fV8fIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_insertf64x2_512, "V8dV8dV2dIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_inserti32x8, "V16iV16iV8iIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_inserti64x2_512, "V8LLiV8LLiV2LLiIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_inserti64x2_512, "V8OiV8OiV2OiIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_insertf64x4, "V8dV8dV4dIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_inserti64x4, "V8LLiV8LLiV4LLiIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_inserti64x4, "V8OiV8OiV4OiIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_insertf64x2_256, "V4dV4dV2dIi", "ncV:256:", "avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_inserti64x2_256, "V4LLiV4LLiV2LLiIi", "ncV:256:", "avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_inserti64x2_256, "V4OiV4OiV2OiIi", "ncV:256:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_insertf32x4_256, "V8fV8fV4fIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_inserti32x4_256, "V8iV8iV4iIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_insertf32x4, "V16fV16fV4fIi", "ncV:512:", "avx512f") @@ -1703,10 +1708,10 @@ TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask3, "V2dV2dV2dV2dUcIi", "ncV:128:", " TARGET_BUILTIN(__builtin_ia32_vfmsubsd3_mask3, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vfmsubss3_mask3, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_permdf512, "V8dV8dIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_permdi512, "V8LLiV8LLiIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_permdi512, "V8OiV8OiIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_permvarhi512, "V32sV32sV32s", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_permvardf512, "V8dV8dV8LLi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_permvardi512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_permvardf512, "V8dV8dV8Oi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_permvardi512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_permvarsf512, "V16fV16fV16i", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_permvarsi512, "V16iV16iV16i", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_permvarqi512, "V64cV64cV64c", "ncV:512:", "avx512vbmi") @@ -1714,8 +1719,8 @@ TARGET_BUILTIN(__builtin_ia32_permvarqi128, "V16cV16cV16c", "ncV:128:", "avx512v TARGET_BUILTIN(__builtin_ia32_permvarqi256, "V32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl") TARGET_BUILTIN(__builtin_ia32_permvarhi128, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_permvarhi256, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl") -TARGET_BUILTIN(__builtin_ia32_permvardf256, "V4dV4dV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_permvardi256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_permvardf256, "V4dV4dV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_permvardi256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_fpclasspd128_mask, "UcV2dIiUc", "ncV:128:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_fpclasspd256_mask, "UcV4dIiUc", "ncV:256:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_fpclassps128_mask, "UcV4fIiUc", "ncV:128:", "avx512dq,avx512vl") @@ -1727,87 +1732,87 @@ TARGET_BUILTIN(__builtin_ia32_fpclassss_mask, "UcV4fIiUc", "ncV:128:", "avx512dq TARGET_BUILTIN(__builtin_ia32_kaddqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kaddhi, "UsUsUs", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kaddsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kadddi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kadddi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kandqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kandhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kandsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kanddi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kanddi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kandnqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kandnhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kandnsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kandndi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kandndi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_korqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_korhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_korsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kordi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kordi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kortestcqi, "iUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kortestzqi, "iUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kortestchi, "iUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kortestzhi, "iUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kortestcsi, "iUiUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kortestzsi, "iUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kortestcdi, "iULLiULLi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kortestzdi, "iULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kortestcdi, "iUOiUOi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kortestzdi, "iUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_ktestcqi, "iUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_ktestzqi, "iUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_ktestchi, "iUsUs", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_ktestzhi, "iUsUs", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_ktestcsi, "iUiUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_ktestzsi, "iUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_ktestcdi, "iULLiULLi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_ktestzdi, "iULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_ktestcdi, "iUOiUOi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_ktestzdi, "iUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kunpckhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kxnorqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kxnorhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kxnorsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kxnordi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kxnordi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kxorqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kxorhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kxorsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kxordi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kxordi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kshiftliqi, "UcUcIUi", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kshiftlihi, "UsUsIUi", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kshiftlisi, "UiUiIUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kshiftlidi, "ULLiULLiIUi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kshiftlidi, "UOiUOiIUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kshiftriqi, "UcUcIUi", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kshiftrihi, "UsUsIUi", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kshiftrisi, "UiUiIUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kshiftridi, "ULLiULLiIUi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kshiftridi, "UOiUOiIUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kmovb, "UcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kmovw, "UsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kmovd, "UiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kmovq, "ULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kmovq, "UOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_palignr512, "V64cV64cV64cIi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_dbpsadbw128, "V8sV16cV16cIi", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_dbpsadbw256, "V16sV32cV32cIi", "ncV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_dbpsadbw512, "V32sV64cV64cIi", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_psadbw512, "V8LLiV64cV64c", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_psadbw512, "V8OiV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_compressdf512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_compressdi512_mask, "V8LLiV8LLiV8LLiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_compressdi512_mask, "V8OiV8OiV8OiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_compresshi512_mask, "V32sV32sV32sUi", "ncV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_compressqi512_mask, "V64cV64cV64cULLi", "ncV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_compressqi512_mask, "V64cV64cV64cUOi", "ncV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_compresssf512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_compresssi512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_cmpsd_mask, "UcV2dV2dIiUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_cmpss_mask, "UcV4fV4fIiUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pshufd512, "V16iV16iIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_expanddf512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_expanddi512_mask, "V8LLiV8LLiV8LLiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_expanddi512_mask, "V8OiV8OiV8OiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_expandhi512_mask, "V32sV32sV32sUi", "ncV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_expandqi512_mask, "V64cV64cV64cULLi", "ncV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_expandqi512_mask, "V64cV64cV64cUOi", "ncV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_expandloaddf512_mask, "V8dV8dC*V8dUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_expandloaddi512_mask, "V8LLiV8LLiC*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_expandloaddi512_mask, "V8OiV8OiC*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_expandloadhi512_mask, "V32sV32sC*V32sUi", "nV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_expandloadqi512_mask, "V64cV64cC*V64cULLi", "nV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_expandloadqi512_mask, "V64cV64cC*V64cUOi", "nV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_expandloadsf512_mask, "V16fV16fC*V16fUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_expandloadsi512_mask, "V16iV16iC*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_expandsf512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_expandsi512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_cvtps2pd512_mask, "V8dV8fV8dUcIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_compressstoredf512_mask, "vV8d*V8dUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_compressstoredi512_mask, "vV8LLi*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_compressstoredi512_mask, "vV8Oi*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_compressstorehi512_mask, "vV32s*V32sUi", "nV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_compressstoreqi512_mask, "vV64c*V64cULLi", "nV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_compressstoreqi512_mask, "vV64c*V64cUOi", "nV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_compressstoresf512_mask, "vV16f*V16fUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_compressstoresi512_mask, "vV16i*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtph2ps_mask, "V4fV8sV4fUc", "ncV:128:", "avx512vl") @@ -1825,19 +1830,38 @@ TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512, "V64cV64cV64c", "ncV:512:", "av TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128, "V16cV16cV16c", "ncV:128:", "avx512vbmi,avx512vl") TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256, "V32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl") +// bf16 intrinsics +TARGET_BUILTIN(__builtin_ia32_cvtne2ps2bf16_128, "V8sV4fV4f", "ncV:128:", "avx512bf16,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtne2ps2bf16_256, "V16sV8fV8f", "ncV:256:", "avx512bf16,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtne2ps2bf16_512, "V32sV16fV16f", "ncV:512:", "avx512bf16") +TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_128_mask, "V8sV4fV8sUc", "ncV:128:", "avx512bf16,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_256_mask, "V8sV8fV8sUc", "ncV:256:", "avx512bf16,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_512_mask, "V16sV16fV16sUs", "ncV:512:", "avx512bf16") +TARGET_BUILTIN(__builtin_ia32_dpbf16ps_128, "V4fV4fV4iV4i", "ncV:128:", "avx512bf16,avx512vl") +TARGET_BUILTIN(__builtin_ia32_dpbf16ps_256, "V8fV8fV8iV8i", "ncV:256:", "avx512bf16,avx512vl") +TARGET_BUILTIN(__builtin_ia32_dpbf16ps_512, "V16fV16fV16iV16i", "ncV:512:", "avx512bf16") +TARGET_BUILTIN(__builtin_ia32_cvtsbf162ss_32, "fUs", "nc", "avx512bf16") + +TARGET_BUILTIN(__builtin_ia32_vp2intersect_q_512, "vV8OiV8OiUc*Uc*", "nV:512:", "avx512vp2intersect") +TARGET_BUILTIN(__builtin_ia32_vp2intersect_q_256, "vV4OiV4OiUc*Uc*", "nV:256:", "avx512vp2intersect,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vp2intersect_q_128, "vV2OiV2OiUc*Uc*", "nV:128:", "avx512vp2intersect,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vp2intersect_d_512, "vV16iV16iUs*Us*", "nV:512:", "avx512vp2intersect") +TARGET_BUILTIN(__builtin_ia32_vp2intersect_d_256, "vV8iV8iUc*Uc*", "nV:256:", "avx512vp2intersect,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vp2intersect_d_128, "vV4iV4iUc*Uc*", "nV:128:", "avx512vp2intersect,avx512vl") + // generic select intrinsics TARGET_BUILTIN(__builtin_ia32_selectb_128, "V16cUsV16cV16c", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_selectb_256, "V32cUiV32cV32c", "ncV:256:", "avx512bw,avx512vl") -TARGET_BUILTIN(__builtin_ia32_selectb_512, "V64cULLiV64cV64c", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_selectb_512, "V64cUOiV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_selectw_128, "V8sUcV8sV8s", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_selectw_256, "V16sUsV16sV16s", "ncV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_selectw_512, "V32sUiV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_selectd_128, "V4iUcV4iV4i", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_selectd_256, "V8iUcV8iV8i", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_selectd_512, "V16iUsV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_selectq_128, "V2LLiUcV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_selectq_256, "V4LLiUcV4LLiV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_selectq_512, "V8LLiUcV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_selectq_128, "V2OiUcV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_selectq_256, "V4OiUcV4OiV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_selectq_512, "V8OiUcV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_selectps_128, "V4fUcV4fV4f", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_selectps_256, "V8fUcV8fV8f", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_selectps_512, "V16fUsV16fV16f", "ncV:512:", "avx512f") @@ -1872,6 +1896,10 @@ TARGET_BUILTIN(__builtin_ia32_ptwrite32, "vUi", "n", "ptwrite") // INVPCID TARGET_BUILTIN(__builtin_ia32_invpcid, "vUiv*", "nc", "invpcid") +// ENQCMD +TARGET_BUILTIN(__builtin_ia32_enqcmd, "Ucv*vC*", "n", "enqcmd") +TARGET_BUILTIN(__builtin_ia32_enqcmds, "Ucv*vC*", "n", "enqcmd") + // MSVC TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") diff --git a/include/clang/Basic/BuiltinsX86_64.def b/include/clang/Basic/BuiltinsX86_64.def index 5e8cce5c6e5e..56051af55e7d 100644 --- a/include/clang/Basic/BuiltinsX86_64.def +++ b/include/clang/Basic/BuiltinsX86_64.def @@ -1,9 +1,8 @@ //===--- 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -44,65 +43,65 @@ TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h" TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "cx16") -TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "") -TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "") -TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "ncV:128:", "sse") -TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "ncV:128:", "sse") -TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "LLiV2d", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_movnti64, "vLLi*LLi", "n", "sse2") -TARGET_BUILTIN(__builtin_ia32_vec_ext_v2di, "LLiV2LLiIi", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_vec_set_v2di, "V2LLiV2LLiLLiIi", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "nc", "sse4.2") -TARGET_BUILTIN(__builtin_ia32_vec_ext_v4di, "LLiV4LLiIi", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_vec_set_v4di, "V4LLiV4LLiLLiIi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "UOi", "n", "") +TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vUOi", "n", "") +TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "OiV4f", "ncV:128:", "sse") +TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "OiV4f", "ncV:128:", "sse") +TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "OiV2d", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "OiV2d", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_movnti64, "vOi*Oi", "n", "sse2") +TARGET_BUILTIN(__builtin_ia32_vec_ext_v2di, "OiV2OiIi", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_vec_set_v2di, "V2OiV2OiOiIi", "ncV:128:", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_crc32di, "UOiUOiUOi", "nc", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_vec_ext_v4di, "OiV4OiIi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_vec_set_v4di, "V4OiV4OiOiIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_rdfsbase32, "Ui", "n", "fsgsbase") -TARGET_BUILTIN(__builtin_ia32_rdfsbase64, "ULLi", "n", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_rdfsbase64, "UOi", "n", "fsgsbase") TARGET_BUILTIN(__builtin_ia32_rdgsbase32, "Ui", "n", "fsgsbase") -TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "n", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "UOi", "n", "fsgsbase") TARGET_BUILTIN(__builtin_ia32_wrfsbase32, "vUi", "n", "fsgsbase") -TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "n", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vUOi", "n", "fsgsbase") TARGET_BUILTIN(__builtin_ia32_wrgsbase32, "vUi", "n", "fsgsbase") -TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "n", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vUOi", "n", "fsgsbase") TARGET_BUILTIN(__builtin_ia32_fxrstor64, "vv*", "n", "fxsr") TARGET_BUILTIN(__builtin_ia32_fxsave64, "vv*", "n", "fxsr") -TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "n", "xsave") -TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "n", "xsave") -TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "n", "xsaveopt") -TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "n", "xsaves") -TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "n", "xsavec") -TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "n", "xsaves") -TARGET_BUILTIN(__builtin_ia32_incsspq, "vULLi", "n", "shstk") -TARGET_BUILTIN(__builtin_ia32_rdsspq, "ULLiULLi", "n", "shstk") -TARGET_BUILTIN(__builtin_ia32_wrssq, "vULLiv*", "n", "shstk") -TARGET_BUILTIN(__builtin_ia32_wrussq, "vULLiv*", "n", "shstk") -TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "n", "") -TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "n", "") -TARGET_BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "n", "rdrnd") -TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "n", "rdseed") -TARGET_BUILTIN(__builtin_ia32_lzcnt_u64, "ULLiULLi", "nc", "lzcnt") -TARGET_BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "nc", "bmi") -TARGET_BUILTIN(__builtin_ia32_tzcnt_u64, "ULLiULLi", "nc", "") -TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "nc", "bmi2") -TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "nc", "bmi2") -TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "nc", "bmi2") -TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "nc", "tbm") -TARGET_BUILTIN(__builtin_ia32_lwpins64, "UcULLiUiUi", "n", "lwp") -TARGET_BUILTIN(__builtin_ia32_lwpval64, "vULLiUiUi", "n", "lwp") -TARGET_BUILTIN(__builtin_ia32_vcvtsd2si64, "LLiV2dIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "ULLiV2dIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "LLiV4fIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvtss2usi64, "ULLiV4fIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvttsd2si64, "LLiV2dIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi64, "ULLiV2dIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvttss2si64, "LLiV4fIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvttss2usi64, "ULLiV4fIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_cvtsi2sd64, "V2dV2dLLiIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fLLiIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dULLiIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fULLiIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*UOi", "n", "xsave") +TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*UOi", "n", "xsave") +TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*UOi", "n", "xsaveopt") +TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*UOi", "n", "xsaves") +TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*UOi", "n", "xsavec") +TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*UOi", "n", "xsaves") +TARGET_BUILTIN(__builtin_ia32_incsspq, "vUOi", "n", "shstk") +TARGET_BUILTIN(__builtin_ia32_rdsspq, "UOiUOi", "n", "shstk") +TARGET_BUILTIN(__builtin_ia32_wrssq, "vUOiv*", "n", "shstk") +TARGET_BUILTIN(__builtin_ia32_wrussq, "vUOiv*", "n", "shstk") +TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcUOiUOiUOi*", "n", "") +TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcUOiUOiUOi*", "n", "") +TARGET_BUILTIN(__builtin_ia32_rdrand64_step, "UiUOi*", "n", "rdrnd") +TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiUOi*", "n", "rdseed") +TARGET_BUILTIN(__builtin_ia32_lzcnt_u64, "UOiUOi", "nc", "lzcnt") +TARGET_BUILTIN(__builtin_ia32_bextr_u64, "UOiUOiUOi", "nc", "bmi") +TARGET_BUILTIN(__builtin_ia32_tzcnt_u64, "UOiUOi", "nc", "") +TARGET_BUILTIN(__builtin_ia32_bzhi_di, "UOiUOiUOi", "nc", "bmi2") +TARGET_BUILTIN(__builtin_ia32_pdep_di, "UOiUOiUOi", "nc", "bmi2") +TARGET_BUILTIN(__builtin_ia32_pext_di, "UOiUOiUOi", "nc", "bmi2") +TARGET_BUILTIN(__builtin_ia32_bextri_u64, "UOiUOiIUOi", "nc", "tbm") +TARGET_BUILTIN(__builtin_ia32_lwpins64, "UcUOiUiUi", "n", "lwp") +TARGET_BUILTIN(__builtin_ia32_lwpval64, "vUOiUiUi", "n", "lwp") +TARGET_BUILTIN(__builtin_ia32_vcvtsd2si64, "OiV2dIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "UOiV2dIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "OiV4fIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtss2usi64, "UOiV4fIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttsd2si64, "OiV2dIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi64, "UOiV2dIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttss2si64, "OiV4fIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttss2usi64, "UOiV4fIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtsi2sd64, "V2dV2dOiIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fOiIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dUOiIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fUOiIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_directstore_u64, "vULi*ULi", "n", "movdiri") -TARGET_BUILTIN(__builtin_ia32_ptwrite64, "vULLi", "n", "ptwrite") +TARGET_BUILTIN(__builtin_ia32_ptwrite64, "vUOi", "n", "ptwrite") #undef BUILTIN #undef TARGET_BUILTIN diff --git a/include/clang/Basic/BuiltinsXCore.def b/include/clang/Basic/BuiltinsXCore.def index 672d20578a63..c99b7ced1351 100644 --- a/include/clang/Basic/BuiltinsXCore.def +++ b/include/clang/Basic/BuiltinsXCore.def @@ -1,9 +1,8 @@ //===--- BuiltinsXCore.def - XCore 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/CapturedStmt.h b/include/clang/Basic/CapturedStmt.h index 324e1b1d3d09..029e1144eaf7 100644 --- a/include/clang/Basic/CapturedStmt.h +++ b/include/clang/Basic/CapturedStmt.h @@ -1,9 +1,8 @@ //===--- CapturedStmt.h - Types for CapturedStmts ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/CharInfo.h b/include/clang/Basic/CharInfo.h index e6c5e90d346c..8577475fab06 100644 --- a/include/clang/Basic/CharInfo.h +++ b/include/clang/Basic/CharInfo.h @@ -1,9 +1,8 @@ //===--- clang/Basic/CharInfo.h - Classifying ASCII Characters --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/CodeGenOptions.def b/include/clang/Basic/CodeGenOptions.def index ed2387b9a2e2..cd7a84548765 100644 --- a/include/clang/Basic/CodeGenOptions.def +++ b/include/clang/Basic/CodeGenOptions.def @@ -1,9 +1,8 @@ //===--- CodeGenOptions.def - Code generation option database ----- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -62,6 +61,7 @@ CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new ///< pass manager. CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled. +CODEGENOPT(EnableDebugEntryValues, 1, 0) ///< Emit call site parameter dbg info CODEGENOPT(IndirectTlsSegRefs, 1, 0) ///< Set when -mno-tls-direct-seg-refs ///< is specified. CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls. @@ -225,6 +225,7 @@ CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition. CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report is enabled. +CODEGENOPT(TimeTrace , 1, 0) ///< Set when -ftime-trace is enabled. CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled. CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled. CODEGENOPT(NoUseJumpTables , 1, 0) ///< Set when -fno-jump-tables is enabled. @@ -260,8 +261,6 @@ CODEGENOPT(DebugExplicitImport, 1, 0) ///< Whether or not debug info should ///< contain explicit imports for ///< anonymous namespaces -ENUM_CODEGENOPT(SplitDwarfMode, DwarfFissionKind, 2, NoFission) ///< DWARF fission mode to use. - CODEGENOPT(SplitDwarfInlining, 1, 1) ///< Whether to include inlining info in the ///< skeleton CU to allow for symbolication ///< of inline stack frames without .dwo files. diff --git a/include/clang/Basic/CodeGenOptions.h b/include/clang/Basic/CodeGenOptions.h index ec6eda7fb788..4e9025d2fea9 100644 --- a/include/clang/Basic/CodeGenOptions.h +++ b/include/clang/Basic/CodeGenOptions.h @@ -1,9 +1,8 @@ //===--- CodeGenOptions.h ---------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -54,6 +53,7 @@ public: enum VectorLibrary { NoLibrary, // Don't use any vector library. Accelerate, // Use the Accelerate framework. + MASSV, // IBM MASS vector library. SVML // Intel short vector math library. }; @@ -71,8 +71,6 @@ public: LocalExecTLSModel }; - enum DwarfFissionKind { NoFission, SplitFileFission, SingleFileFission }; - /// Clang versions with different platform ABI conformance. enum class ClangABI { /// Attempt to be ABI-compatible with code generated by Clang 3.8.x @@ -101,6 +99,7 @@ public: ProfileClangInstr, // Clang instrumentation to generate execution counts // to use with PGO. ProfileIRInstr, // IR level PGO instrumentation in LLVM. + ProfileCSIRInstr, // IR level PGO context sensitive instrumentation in LLVM. }; enum EmbedBitcodeKind { @@ -184,10 +183,13 @@ public: /// file, for example with -save-temps. std::string MainFileName; - /// The name for the split debug info file that we'll break out. This is used - /// in the backend for setting the name in the skeleton cu. + /// The name for the split debug info file used for the DW_AT_[GNU_]dwo_name + /// attribute in the skeleton CU. std::string SplitDwarfFile; + /// Output filename for the split debug info, not used in the skeleton CU. + std::string SplitDwarfOutput; + /// The name of the relocation model to use. llvm::Reloc::Model RelocationModel; @@ -204,8 +206,8 @@ public: /// A list of linker options to embed in the object file. std::vector LinkerOptions; - /// Name of the profile file to use as output for -fprofile-instr-generate - /// and -fprofile-generate. + /// Name of the profile file to use as output for -fprofile-instr-generate, + /// -fprofile-generate, and -fcs-profile-generate. std::string InstrProfileOutput; /// Name of the profile file to use with -fprofile-sample-use. @@ -238,6 +240,17 @@ public: /// records. std::string OptRecordFile; + /// The regex that filters the passes that should be saved to the optimization + /// records. + std::string OptRecordPasses; + + /// The format used for serializing remarks (default: YAML) + std::string OptRecordFormat; + + /// The name of the partition that symbols are assigned to, specified with + /// -fsymbol-partition (see https://lld.llvm.org/Partitions.html). + std::string SymbolPartition; + /// 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 @@ -288,6 +301,9 @@ public: std::vector DefaultFunctionAttrs; + /// List of dynamic shared object files to be loaded as pass plugins. + std::vector PassPlugins; + public: // Define accessors/mutators for code generation options of enumeration type. #define CODEGENOPT(Name, Bits, Default) @@ -316,6 +332,11 @@ public: return getProfileInstr() == ProfileIRInstr; } + /// Check if CS IR level profile instrumentation is on. + bool hasProfileCSIRInstr() const { + return getProfileInstr() == ProfileCSIRInstr; + } + /// Check if Clang profile use is on. bool hasProfileClangUse() const { return getProfileUse() == ProfileClangInstr; @@ -323,9 +344,12 @@ public: /// Check if IR level profile use is on. bool hasProfileIRUse() const { - return getProfileUse() == ProfileIRInstr; + return getProfileUse() == ProfileIRInstr || + getProfileUse() == ProfileCSIRInstr; } + /// Check if CSIR profile use is on. + bool hasProfileCSIRUse() const { return getProfileUse() == ProfileCSIRInstr; } }; } // end namespace clang diff --git a/include/clang/Basic/CommentOptions.h b/include/clang/Basic/CommentOptions.h index 6cc9cf6b199c..7d142fc32f51 100644 --- a/include/clang/Basic/CommentOptions.h +++ b/include/clang/Basic/CommentOptions.h @@ -1,9 +1,8 @@ //===- CommentOptions.h - Options for parsing comments ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/Cuda.h b/include/clang/Basic/Cuda.h index 0575e703338e..ef5d24dcf888 100644 --- a/include/clang/Basic/Cuda.h +++ b/include/clang/Basic/Cuda.h @@ -1,9 +1,8 @@ //===--- Cuda.h - Utilities for compiling CUDA code ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -12,6 +11,7 @@ namespace llvm { class StringRef; +class VersionTuple; } // namespace llvm namespace clang { @@ -25,12 +25,12 @@ enum class CudaVersion { CUDA_91, CUDA_92, CUDA_100, - LATEST = CUDA_100, + CUDA_101, + LATEST = CUDA_101, }; const char *CudaVersionToString(CudaVersion V); - -// No string -> CudaVersion conversion function because there's no canonical -// spelling of the various CUDA versions. +// Input is "Major.Minor" +CudaVersion CudaStringToVersion(llvm::StringRef S); enum class CudaArch { UNKNOWN, @@ -64,7 +64,11 @@ enum class CudaArch { GFX902, GFX904, GFX906, + GFX908, GFX909, + GFX1010, + GFX1011, + GFX1012, LAST, }; const char *CudaArchToString(CudaArch A); @@ -104,6 +108,17 @@ CudaVersion MinVersionForCudaArch(CudaArch A); /// Get the latest CudaVersion that supports the given CudaArch. CudaVersion MaxVersionForCudaArch(CudaArch A); +// Various SDK-dependent features that affect CUDA compilation +enum class CudaFeature { + // CUDA-9.2+ uses a new API for launching kernels. + CUDA_USES_NEW_LAUNCH, + // CUDA-10.1+ needs explicit end of GPU binary registration. + CUDA_USES_FATBIN_REGISTER_END, +}; + +bool CudaFeatureEnabled(llvm::VersionTuple, CudaFeature); +bool CudaFeatureEnabled(CudaVersion, CudaFeature); + } // namespace clang #endif diff --git a/include/clang/Basic/DebugInfoOptions.h b/include/clang/Basic/DebugInfoOptions.h index f3be0fe52d31..91d3332103e9 100644 --- a/include/clang/Basic/DebugInfoOptions.h +++ b/include/clang/Basic/DebugInfoOptions.h @@ -1,9 +1,8 @@ //===--- DebugInfoOptions.h - Debug Info Emission Types ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index a184b480f7c0..2d3fa6b6147f 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -41,6 +41,7 @@ def Named : Decl<"named declarations", 1>; def IndirectField : DDecl; def Binding : DDecl; def OMPDeclareReduction : DDecl, DeclContext; + def OMPDeclareMapper : DDecl, DeclContext; def Declarator : DDecl; def Field : DDecl; def ObjCIvar : DDecl; @@ -69,6 +70,7 @@ def Named : Decl<"named declarations", 1>; def TypeAliasTemplate : DDecl; def TemplateTemplateParm : DDecl