Merge ^/vendor/lvm-project/master up to its last change (upstream commit

e26a78e70), and resolve conflicts.
This commit is contained in:
Dimitry Andric 2020-01-24 22:00:03 +00:00
commit 480093f444
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/clang1000-import/; revision=357095
3290 changed files with 149410 additions and 74906 deletions

View File

@ -2,7 +2,9 @@
.arcconfig
.clang-format
.clang-tidy
.git-blame-ignore-revs
.gitignore
CONTRIBUTING.md
README.md
clang/.arcconfig
clang/.clang-format
@ -70,6 +72,7 @@ clang/lib/Tooling/DependencyScanning/CMakeLists.txt
clang/lib/Tooling/Inclusions/CMakeLists.txt
clang/lib/Tooling/Refactoring/CMakeLists.txt
clang/lib/Tooling/Syntax/CMakeLists.txt
clang/lib/Tooling/Transformer/CMakeLists.txt
clang/runtime/
clang/test/
clang/tools/CMakeLists.txt
@ -92,6 +95,7 @@ clang/tools/clang-format-vs/
clang/tools/clang-fuzzer/
clang/tools/clang-import-test/
clang/tools/clang-offload-bundler/
clang/tools/clang-offload-wrapper/
clang/tools/clang-refactor/
clang/tools/clang-rename/
clang/tools/clang-scan-deps/
@ -159,9 +163,11 @@ compiler-rt/lib/fuzzer/scripts/
compiler-rt/lib/fuzzer/standalone/
compiler-rt/lib/fuzzer/tests/
compiler-rt/lib/gwp_asan/CMakeLists.txt
compiler-rt/lib/gwp_asan/scripts/
compiler-rt/lib/gwp_asan/tests/
compiler-rt/lib/hwasan/.clang-format
compiler-rt/lib/hwasan/CMakeLists.txt
compiler-rt/lib/hwasan/scripts/
compiler-rt/lib/interception/.clang-format
compiler-rt/lib/interception/CMakeLists.txt
compiler-rt/lib/interception/tests/
@ -180,6 +186,7 @@ compiler-rt/lib/sanitizer_common/scripts/
compiler-rt/lib/sanitizer_common/tests/
compiler-rt/lib/scudo/CMakeLists.txt
compiler-rt/lib/scudo/standalone/CMakeLists.txt
compiler-rt/lib/scudo/standalone/benchmarks/
compiler-rt/lib/scudo/standalone/tests/
compiler-rt/lib/stats/CMakeLists.txt
compiler-rt/lib/tsan/.clang-format
@ -196,10 +203,12 @@ compiler-rt/lib/ubsan_minimal/CMakeLists.txt
compiler-rt/lib/xray/CMakeLists.txt
compiler-rt/lib/xray/tests/
compiler-rt/test/
compiler-rt/tools/
compiler-rt/unittests/
compiler-rt/utils/
compiler-rt/www/
debuginfo-tests/
libc/
libclc/
libcxx/.arcconfig
libcxx/.clang-format
@ -217,6 +226,7 @@ libcxx/include/CMakeLists.txt
libcxx/include/__config_site.in
libcxx/include/support/
libcxx/lib/
libcxx/src/CMakeLists.txt
libcxx/src/support/solaris/
libcxx/src/support/win32/
libcxx/test/
@ -230,9 +240,21 @@ libunwind/cmake/
libunwind/docs/
libunwind/src/CMakeLists.txt
libunwind/test/
lld/CMakeLists.txt
lld/COFF/CMakeLists.txt
lld/Common/CMakeLists.txt
lld/ELF/CMakeLists.txt
lld/MinGW/
lld/cmake/
lld/docs/CMakeLists.txt
lld/lib/CMakeLists.txt
lld/lib/Core/CMakeLists.txt
lld/lib/Driver/CMakeLists.txt
lld/lib/ReaderWriter/CMakeLists.txt
lld/lib/ReaderWriter/MachO/CMakeLists.txt
lld/lib/ReaderWriter/YAML/CMakeLists.txt
lld/test/
lld/tools/lld/CMakeLists.txt
lld/unittests/
lld/utils/
lld/wasm/
@ -241,7 +263,7 @@ lldb/.clang-format
lldb/.gitignore
lldb/CMakeLists.txt
lldb/CODE_OWNERS.txt
lldb/INSTALL.txt
lldb/bindings/
lldb/cmake/
lldb/docs/.htaccess
lldb/docs/CMakeLists.txt
@ -259,14 +281,10 @@ lldb/docs/structured_data/
lldb/docs/testsuite/
lldb/docs/use/
lldb/examples/
lldb/include/lldb/Host/Config.h
lldb/include/lldb/Host/android/
lldb/include/lldb/Host/linux/
lldb/include/lldb/Host/macosx/
lldb/include/lldb/Host/windows/
lldb/lit/
lldb/lldb.xcodeproj/
lldb/lldb.xcworkspace/
lldb/packages/
lldb/resources/
lldb/scripts/
@ -288,6 +306,7 @@ lldb/source/Plugins/ABI/CMakeLists.txt
lldb/source/Plugins/ABI/MacOSX-arm/CMakeLists.txt
lldb/source/Plugins/ABI/MacOSX-arm64/CMakeLists.txt
lldb/source/Plugins/ABI/MacOSX-i386/CMakeLists.txt
lldb/source/Plugins/ABI/SysV-arc/CMakeLists.txt
lldb/source/Plugins/ABI/SysV-arm/CMakeLists.txt
lldb/source/Plugins/ABI/SysV-arm64/CMakeLists.txt
lldb/source/Plugins/ABI/SysV-hexagon/CMakeLists.txt
@ -377,6 +396,7 @@ lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt
lldb/source/Plugins/Process/mach-core/
lldb/source/Plugins/Process/minidump/CMakeLists.txt
lldb/source/Plugins/ScriptInterpreter/CMakeLists.txt
lldb/source/Plugins/ScriptInterpreter/Lua/CMakeLists.txt
lldb/source/Plugins/ScriptInterpreter/None/CMakeLists.txt
lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
lldb/source/Plugins/StructuredData/CMakeLists.txt
@ -405,11 +425,9 @@ lldb/tools/darwin-debug/
lldb/tools/darwin-threads/
lldb/tools/debugserver/
lldb/tools/driver/CMakeLists.txt
lldb/tools/driver/lldb-Info.plist
lldb/tools/driver/lldb-Info.plist.in
lldb/tools/intel-features/
lldb/tools/lldb-instr/CMakeLists.txt
lldb/tools/lldb-mi/CMakeLists.txt
lldb/tools/lldb-mi/lldb-Info.plist
lldb/tools/lldb-perf/
lldb/tools/lldb-server/CMakeLists.txt
lldb/tools/lldb-test/
@ -417,14 +435,10 @@ lldb/tools/lldb-vscode/
lldb/unittests/
lldb/use_lldb_suite_root.py
lldb/utils/TableGen/CMakeLists.txt
lldb/utils/git-svn/
lldb/utils/lit-cpuid/
lldb/utils/lldb-dotest/
lldb/utils/lui/
lldb/utils/misc/
lldb/utils/sync-source/
lldb/utils/test/
lldb/utils/vim-lldb/
llgo/
llvm/.arcconfig
llvm/.clang-format
@ -477,6 +491,8 @@ llvm/lib/CodeGen/MIRParser/LLVMBuild.txt
llvm/lib/CodeGen/README.txt
llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt
llvm/lib/CodeGen/SelectionDAG/LLVMBuild.txt
llvm/lib/DWARFLinker/CMakeLists.txt
llvm/lib/DWARFLinker/LLVMBuild.txt
llvm/lib/DebugInfo/CMakeLists.txt
llvm/lib/DebugInfo/CodeView/CMakeLists.txt
llvm/lib/DebugInfo/CodeView/LLVMBuild.txt
@ -507,10 +523,16 @@ llvm/lib/ExecutionEngine/OProfileJIT/CMakeLists.txt
llvm/lib/ExecutionEngine/OProfileJIT/LLVMBuild.txt
llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
llvm/lib/ExecutionEngine/Orc/LLVMBuild.txt
llvm/lib/ExecutionEngine/OrcError/CMakeLists.txt
llvm/lib/ExecutionEngine/OrcError/LLVMBuild.txt
llvm/lib/ExecutionEngine/PerfJITEvents/CMakeLists.txt
llvm/lib/ExecutionEngine/PerfJITEvents/LLVMBuild.txt
llvm/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
llvm/lib/ExecutionEngine/RuntimeDyld/LLVMBuild.txt
llvm/lib/Frontend/CMakeLists.txt
llvm/lib/Frontend/LLVMBuild.txt
llvm/lib/Frontend/OpenMP/CMakeLists.txt
llvm/lib/Frontend/OpenMP/LLVMBuild.txt
llvm/lib/FuzzMutate/CMakeLists.txt
llvm/lib/FuzzMutate/LLVMBuild.txt
llvm/lib/Fuzzer/
@ -713,6 +735,14 @@ llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt
llvm/lib/Target/SystemZ/MCTargetDesc/LLVMBuild.txt
llvm/lib/Target/SystemZ/TargetInfo/CMakeLists.txt
llvm/lib/Target/SystemZ/TargetInfo/LLVMBuild.txt
llvm/lib/Target/VE/CMakeLists.txt
llvm/lib/Target/VE/InstPrinter/CMakeLists.txt
llvm/lib/Target/VE/InstPrinter/LLVMBuild.txt
llvm/lib/Target/VE/LLVMBuild.txt
llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt
llvm/lib/Target/VE/MCTargetDesc/LLVMBuild.txt
llvm/lib/Target/VE/TargetInfo/CMakeLists.txt
llvm/lib/Target/VE/TargetInfo/LLVMBuild.txt
llvm/lib/Target/WebAssembly/AsmParser/CMakeLists.txt
llvm/lib/Target/WebAssembly/AsmParser/LLVMBuild.txt
llvm/lib/Target/WebAssembly/CMakeLists.txt
@ -762,6 +792,8 @@ llvm/lib/ToolDrivers/llvm-lib/CMakeLists.txt
llvm/lib/ToolDrivers/llvm-lib/LLVMBuild.txt
llvm/lib/Transforms/AggressiveInstCombine/CMakeLists.txt
llvm/lib/Transforms/AggressiveInstCombine/LLVMBuild.txt
llvm/lib/Transforms/CFGuard/CMakeLists.txt
llvm/lib/Transforms/CFGuard/LLVMBuild.txt
llvm/lib/Transforms/CMakeLists.txt
llvm/lib/Transforms/Coroutines/CMakeLists.txt
llvm/lib/Transforms/Coroutines/LLVMBuild.txt
@ -835,6 +867,7 @@ llvm/tools/llvm-exegesis/
llvm/tools/llvm-extract/CMakeLists.txt
llvm/tools/llvm-extract/LLVMBuild.txt
llvm/tools/llvm-go/
llvm/tools/llvm-ifs/
llvm/tools/llvm-isel-fuzzer/
llvm/tools/llvm-itanium-demangle-fuzzer/
llvm/tools/llvm-jitlink/
@ -871,6 +904,7 @@ llvm/tools/llvm-profdata/LLVMBuild.txt
llvm/tools/llvm-rc/
llvm/tools/llvm-readobj/CMakeLists.txt
llvm/tools/llvm-readobj/LLVMBuild.txt
llvm/tools/llvm-reduce/
llvm/tools/llvm-rtdyld/CMakeLists.txt
llvm/tools/llvm-rtdyld/LLVMBuild.txt
llvm/tools/llvm-shlib/
@ -894,6 +928,7 @@ llvm/tools/remarks-shlib/
llvm/tools/sancov/
llvm/tools/sanstats/
llvm/tools/verify-uselistorder/
llvm/tools/vfabi-demangle-fuzzer/
llvm/tools/xcode-toolchain/
llvm/tools/yaml2obj/
llvm/unittests/
@ -910,12 +945,14 @@ llvm/utils/Misc/
llvm/utils/PerfectShuffle/
llvm/utils/Reviewing/
llvm/utils/TableGen/CMakeLists.txt
llvm/utils/TableGen/GlobalISel/CMakeLists.txt
llvm/utils/TableGen/LLVMBuild.txt
llvm/utils/TableGen/tdtags
llvm/utils/Target/
llvm/utils/UpdateCMakeLists.pl
llvm/utils/UpdateTestChecks/
llvm/utils/abtest.py
llvm/utils/add_argument_names.py
llvm/utils/benchmark/
llvm/utils/bisect
llvm/utils/bisect-skip-count
@ -953,6 +990,7 @@ llvm/utils/llvm-build/
llvm/utils/llvm-compilers-check
llvm/utils/llvm-gisel-cov.py
llvm/utils/llvm-lit/
llvm/utils/llvm-locstats/
llvm/utils/llvm-native-gxx
llvm/utils/llvm.grm
llvm/utils/llvmdo
@ -980,6 +1018,7 @@ llvm/utils/vim/
llvm/utils/vscode/
llvm/utils/wciia.py
llvm/utils/yaml-bench/
mlir/
openmp/.arcconfig
openmp/.gitignore
openmp/CMakeLists.txt
@ -994,6 +1033,7 @@ openmp/runtime/doc/
openmp/runtime/src/CMakeLists.txt
openmp/runtime/test/
openmp/runtime/tools/
openmp/tools/
openmp/www/
parallel-libs/
polly/

View File

@ -14,13 +14,12 @@
#ifndef LLVM_CLANG_C_BUILDSYSTEM_H
#define LLVM_CLANG_C_BUILDSYSTEM_H
#include "clang-c/Platform.h"
#include "clang-c/CXErrorCode.h"
#include "clang-c/CXString.h"
#include "clang-c/ExternC.h"
#include "clang-c/Platform.h"
#ifdef __cplusplus
extern "C" {
#endif
LLVM_CLANG_C_EXTERN_C_BEGIN
/**
* \defgroup BUILD_SYSTEM Build system utilities
@ -148,9 +147,7 @@ CINDEX_LINKAGE void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor);
* @}
*/
#ifdef __cplusplus
}
#endif
LLVM_CLANG_C_EXTERN_C_END
#endif /* CLANG_C_BUILD_SYSTEM_H */

View File

@ -15,12 +15,11 @@
#ifndef LLVM_CLANG_C_CXCOMPILATIONDATABASE_H
#define LLVM_CLANG_C_CXCOMPILATIONDATABASE_H
#include "clang-c/Platform.h"
#include "clang-c/CXString.h"
#include "clang-c/ExternC.h"
#include "clang-c/Platform.h"
#ifdef __cplusplus
extern "C" {
#endif
LLVM_CLANG_C_EXTERN_C_BEGIN
/** \defgroup COMPILATIONDB CompilationDatabase functions
* \ingroup CINDEX
@ -169,8 +168,7 @@ clang_CompileCommand_getMappedSourceContent(CXCompileCommand, unsigned I);
* @}
*/
#ifdef __cplusplus
}
#endif
LLVM_CLANG_C_EXTERN_C_END
#endif

View File

@ -14,11 +14,10 @@
#ifndef LLVM_CLANG_C_CXERRORCODE_H
#define LLVM_CLANG_C_CXERRORCODE_H
#include "clang-c/ExternC.h"
#include "clang-c/Platform.h"
#ifdef __cplusplus
extern "C" {
#endif
LLVM_CLANG_C_EXTERN_C_BEGIN
/**
* Error codes returned by libclang routines.
@ -57,8 +56,7 @@ enum CXErrorCode {
CXError_ASTReadError = 4
};
#ifdef __cplusplus
}
#endif
LLVM_CLANG_C_EXTERN_C_END
#endif

View File

@ -14,11 +14,10 @@
#ifndef LLVM_CLANG_C_CXSTRING_H
#define LLVM_CLANG_C_CXSTRING_H
#include "clang-c/ExternC.h"
#include "clang-c/Platform.h"
#ifdef __cplusplus
extern "C" {
#endif
LLVM_CLANG_C_EXTERN_C_BEGIN
/**
* \defgroup CINDEX_STRING String manipulation routines
@ -64,8 +63,7 @@ CINDEX_LINKAGE void clang_disposeStringSet(CXStringSet *set);
* @}
*/
#ifdef __cplusplus
}
#endif
LLVM_CLANG_C_EXTERN_C_END
#endif

View File

@ -15,11 +15,10 @@
#ifndef LLVM_CLANG_C_DOCUMENTATION_H
#define LLVM_CLANG_C_DOCUMENTATION_H
#include "clang-c/ExternC.h"
#include "clang-c/Index.h"
#ifdef __cplusplus
extern "C" {
#endif
LLVM_CLANG_C_EXTERN_C_BEGIN
/**
* \defgroup CINDEX_COMMENT Comment introspection
@ -182,7 +181,12 @@ enum CXCommentInlineCommandRenderKind {
* Command argument should be rendered emphasized (typically italic
* font).
*/
CXCommentInlineCommandRenderKind_Emphasized
CXCommentInlineCommandRenderKind_Emphasized,
/**
* Command argument should not be rendered (since it only defines an anchor).
*/
CXCommentInlineCommandRenderKind_Anchor
};
/**
@ -545,10 +549,7 @@ CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment);
* @}
*/
#ifdef __cplusplus
}
#endif
LLVM_CLANG_C_EXTERN_C_END
#endif /* CLANG_C_DOCUMENTATION_H */

View File

@ -0,0 +1,39 @@
/*===- clang-c/ExternC.h - Wrapper for 'extern "C"' ---------------*- 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 *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This file defines an 'extern "C"' wrapper. *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_CLANG_C_EXTERN_C_H
#define LLVM_CLANG_C_EXTERN_C_H
#ifdef __clang__
#define LLVM_CLANG_C_STRICT_PROTOTYPES_BEGIN \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic error \"-Wstrict-prototypes\"")
#define LLVM_CLANG_C_STRICT_PROTOTYPES_END _Pragma("clang diagnostic pop")
#else
#define LLVM_CLANG_C_STRICT_PROTOTYPES_BEGIN
#define LLVM_CLANG_C_STRICT_PROTOTYPES_END
#endif
#ifdef __cplusplus
#define LLVM_CLANG_C_EXTERN_C_BEGIN \
extern "C" { \
LLVM_CLANG_C_STRICT_PROTOTYPES_BEGIN
#define LLVM_CLANG_C_EXTERN_C_END \
LLVM_CLANG_C_STRICT_PROTOTYPES_END \
}
#else
#define LLVM_CLANG_C_EXTERN_C_BEGIN LLVM_CLANG_C_STRICT_PROTOTYPES_BEGIN
#define LLVM_CLANG_C_EXTERN_C_END LLVM_CLANG_C_STRICT_PROTOTYPES_END
#endif
#endif

View File

@ -10,9 +10,9 @@
#ifndef LLVM_CLANG_C_FATAL_ERROR_HANDLER_H
#define LLVM_CLANG_C_FATAL_ERROR_HANDLER_H
#ifdef __cplusplus
extern "C" {
#endif
#include "clang-c/ExternC.h"
LLVM_CLANG_C_EXTERN_C_BEGIN
/**
* Installs error handler that prints error message to stderr and calls abort().
@ -27,7 +27,6 @@ void clang_install_aborting_llvm_fatal_error_handler(void);
*/
void clang_uninstall_llvm_fatal_error_handler(void);
#ifdef __cplusplus
}
#endif
LLVM_CLANG_C_EXTERN_C_END
#endif

View File

@ -18,10 +18,11 @@
#include <time.h>
#include "clang-c/Platform.h"
#include "clang-c/BuildSystem.h"
#include "clang-c/CXErrorCode.h"
#include "clang-c/CXString.h"
#include "clang-c/BuildSystem.h"
#include "clang-c/ExternC.h"
#include "clang-c/Platform.h"
/**
* The version constants for the libclang API.
@ -51,9 +52,7 @@
CINDEX_VERSION_MAJOR, \
CINDEX_VERSION_MINOR)
#ifdef __cplusplus
extern "C" {
#endif
LLVM_CLANG_C_EXTERN_C_BEGIN
/** \defgroup CINDEX libclang: C Interface to Clang
*
@ -2567,8 +2566,15 @@ enum CXCursorKind {
*/
CXCursor_OMPMasterTaskLoopSimdDirective = 283,
/** OpenMP parallel master taskloop simd directive.
*/
CXCursor_OMPParallelMasterTaskLoopSimdDirective = 284,
CXCursor_LastStmt = CXCursor_OMPMasterTaskLoopSimdDirective,
/** OpenMP parallel master directive.
*/
CXCursor_OMPParallelMasterDirective = 285,
CXCursor_LastStmt = CXCursor_OMPParallelMasterDirective,
/**
* Cursor that represents the translation unit itself.
@ -6771,7 +6777,6 @@ CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T,
* @}
*/
#ifdef __cplusplus
}
#endif
LLVM_CLANG_C_EXTERN_C_END
#endif

View File

@ -14,9 +14,9 @@
#ifndef LLVM_CLANG_C_PLATFORM_H
#define LLVM_CLANG_C_PLATFORM_H
#ifdef __cplusplus
extern "C" {
#endif
#include "clang-c/ExternC.h"
LLVM_CLANG_C_EXTERN_C_BEGIN
/* MSVC DLL import/export. */
#ifdef _MSC_VER
@ -39,7 +39,6 @@ extern "C" {
#endif
#endif
#ifdef __cplusplus
}
#endif
LLVM_CLANG_C_EXTERN_C_END
#endif

View File

@ -0,0 +1,177 @@
//===--- ASTConcept.h - Concepts Related AST Data Structures ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file provides AST data structures related to concepts.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_ASTCONCEPT_H
#define LLVM_CLANG_AST_ASTCONCEPT_H
#include "clang/AST/Expr.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include <string>
#include <utility>
namespace clang {
class ConceptDecl;
/// \brief The result of a constraint satisfaction check, containing the
/// necessary information to diagnose an unsatisfied constraint.
struct ConstraintSatisfaction {
using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>;
bool IsSatisfied = false;
/// \brief Pairs of unsatisfied atomic constraint expressions along with the
/// substituted constraint expr, if the template arguments could be
/// substituted into them, or a diagnostic if substitution resulted in an
/// invalid expression.
llvm::SmallVector<std::pair<const Expr *, Detail>, 4> Details;
// This can leak if used in an AST node, use ASTConstraintSatisfaction
// instead.
void *operator new(size_t bytes, ASTContext &C) = delete;
};
/// Pairs of unsatisfied atomic constraint expressions along with the
/// substituted constraint expr, if the template arguments could be
/// substituted into them, or a diagnostic if substitution resulted in
/// an invalid expression.
using UnsatisfiedConstraintRecord =
std::pair<const Expr *,
llvm::PointerUnion<Expr *,
std::pair<SourceLocation, StringRef> *>>;
/// \brief The result of a constraint satisfaction check, containing the
/// necessary information to diagnose an unsatisfied constraint.
///
/// This is safe to store in an AST node, as opposed to ConstraintSatisfaction.
struct ASTConstraintSatisfaction final :
llvm::TrailingObjects<ASTConstraintSatisfaction,
UnsatisfiedConstraintRecord> {
std::size_t NumRecords;
bool IsSatisfied : 1;
const UnsatisfiedConstraintRecord *begin() const {
return getTrailingObjects<UnsatisfiedConstraintRecord>();
}
const UnsatisfiedConstraintRecord *end() const {
return getTrailingObjects<UnsatisfiedConstraintRecord>() + NumRecords;
}
ASTConstraintSatisfaction(const ASTContext &C,
const ConstraintSatisfaction &Satisfaction);
static ASTConstraintSatisfaction *
Create(const ASTContext &C, const ConstraintSatisfaction &Satisfaction);
};
/// \brief Common data class for constructs that reference concepts with
/// template arguments.
class ConceptReference {
protected:
// \brief The optional nested name specifier used when naming the concept.
NestedNameSpecifierLoc NestedNameSpec;
/// \brief The location of the template keyword, if specified when naming the
/// concept.
SourceLocation TemplateKWLoc;
/// \brief The concept name used.
DeclarationNameInfo ConceptName;
/// \brief The declaration found by name lookup when the expression was
/// created.
/// Can differ from NamedConcept when, for example, the concept was found
/// through a UsingShadowDecl.
NamedDecl *FoundDecl;
/// \brief The concept named.
ConceptDecl *NamedConcept;
/// \brief The template argument list source info used to specialize the
/// concept.
const ASTTemplateArgumentListInfo *ArgsAsWritten;
public:
ConceptReference(NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
ConceptDecl *NamedConcept,
const ASTTemplateArgumentListInfo *ArgsAsWritten) :
NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {}
ConceptReference() : NestedNameSpec(), TemplateKWLoc(), ConceptName(),
FoundDecl(nullptr), NamedConcept(nullptr), ArgsAsWritten(nullptr) {}
const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
return NestedNameSpec;
}
const DeclarationNameInfo &getConceptNameInfo() const { return ConceptName; }
SourceLocation getConceptNameLoc() const {
return getConceptNameInfo().getLoc();
}
SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
NamedDecl *getFoundDecl() const {
return FoundDecl;
}
ConceptDecl *getNamedConcept() const {
return NamedConcept;
}
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
return ArgsAsWritten;
}
/// \brief Whether or not template arguments were explicitly specified in the
/// concept reference (they might not be in type constraints, for example)
bool hasExplicitTemplateArgs() const {
return ArgsAsWritten != nullptr;
}
};
class TypeConstraint : public ConceptReference {
/// \brief The immediately-declared constraint expression introduced by this
/// type-constraint.
Expr *ImmediatelyDeclaredConstraint = nullptr;
public:
TypeConstraint(NestedNameSpecifierLoc NNS,
DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
ConceptDecl *NamedConcept,
const ASTTemplateArgumentListInfo *ArgsAsWritten,
Expr *ImmediatelyDeclaredConstraint) :
ConceptReference(NNS, /*TemplateKWLoc=*/SourceLocation(), ConceptNameInfo,
FoundDecl, NamedConcept, ArgsAsWritten),
ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint) {}
/// \brief Get the immediately-declared constraint expression introduced by
/// this type-constraint, that is - the constraint expression that is added to
/// the associated constraints of the enclosing declaration in practice.
Expr *getImmediatelyDeclaredConstraint() const {
return ImmediatelyDeclaredConstraint;
}
void print(llvm::raw_ostream &OS, PrintingPolicy Policy) const;
};
} // clang
#endif // LLVM_CLANG_AST_ASTCONCEPT_H

View File

@ -102,6 +102,11 @@ class ASTConsumer {
/// modified by the introduction of an implicit zero initializer.
virtual void CompleteTentativeDefinition(VarDecl *D) {}
/// CompleteExternalDeclaration - Callback invoked at the end of a translation
/// unit to notify the consumer that the given external declaration should be
/// completed.
virtual void CompleteExternalDeclaration(VarDecl *D) {}
/// Callback invoked when an MSInheritanceAttr has been attached to a
/// CXXRecordDecl.
virtual void AssignInheritanceModel(CXXRecordDecl *RD) {}

View File

@ -22,7 +22,6 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
@ -96,6 +95,7 @@ class CXXRecordDecl;
class DiagnosticsEngine;
class Expr;
class FixedPointSemantics;
class GlobalDecl;
class MangleContext;
class MangleNumberingContext;
class MaterializeTemporaryExpr;
@ -113,9 +113,11 @@ class ObjCPropertyDecl;
class ObjCPropertyImplDecl;
class ObjCProtocolDecl;
class ObjCTypeParamDecl;
struct ParsedTargetAttr;
class Preprocessor;
class Stmt;
class StoredDeclsMap;
class TargetAttr;
class TemplateDecl;
class TemplateParameterList;
class TemplateTemplateParmDecl;
@ -124,6 +126,7 @@ class UnresolvedSetIterator;
class UsingShadowDecl;
class VarTemplateDecl;
class VTableContextBase;
struct BlockVarCopyInit;
namespace Builtin {
@ -145,6 +148,10 @@ class Context;
} // namespace interp
namespace serialization {
template <class> class AbstractTypeReader;
} // namespace serialization
struct TypeInfo {
uint64_t Width = 0;
unsigned Align = 0;
@ -158,22 +165,6 @@ struct TypeInfo {
/// Holds long-lived AST nodes (such as types and decls) that can be
/// referred to throughout the semantic analysis of a file.
class ASTContext : public RefCountedBase<ASTContext> {
public:
/// Copy initialization expr of a __block variable and a boolean flag that
/// indicates whether the expression can throw.
struct BlockVarCopyInit {
BlockVarCopyInit() = default;
BlockVarCopyInit(Expr *CopyExpr, bool CanThrow)
: ExprAndFlag(CopyExpr, CanThrow) {}
void setExprAndFlag(Expr *CopyExpr, bool CanThrow) {
ExprAndFlag.setPointerAndInt(CopyExpr, CanThrow);
}
Expr *getCopyExpr() const { return ExprAndFlag.getPointer(); }
bool canThrow() const { return ExprAndFlag.getInt(); }
llvm::PointerIntPair<Expr *, 1, bool> ExprAndFlag;
};
private:
friend class NestedNameSpecifier;
mutable SmallVector<Type *, 0> Types;
@ -272,12 +263,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Mapping from __block VarDecls to BlockVarCopyInit.
llvm::DenseMap<const VarDecl *, BlockVarCopyInit> BlockVarCopyInits;
/// 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<const MaterializeTemporaryExpr *, APValue *>
MaterializedTemporaryValues;
/// Used to cleanups APValues stored in the AST.
mutable llvm::SmallVector<APValue *, 0> APValueCleanups;
@ -298,12 +283,16 @@ class ASTContext : public RefCountedBase<ASTContext> {
TemplateTemplateParmDecl *getParam() const { return Parm; }
void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Parm); }
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) {
Profile(ID, C, Parm);
}
static void Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &C,
TemplateTemplateParmDecl *Parm);
};
mutable llvm::FoldingSet<CanonicalTemplateTemplateParm>
mutable llvm::ContextualFoldingSet<CanonicalTemplateTemplateParm,
const ASTContext&>
CanonTemplateTemplateParms;
TemplateTemplateParmDecl *
@ -435,6 +424,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
friend class ASTDeclReader;
friend class ASTReader;
friend class ASTWriter;
template <class> friend class serialization::AbstractTypeReader;
friend class CXXRecordDecl;
/// A mapping to contain the template or declaration that
@ -575,7 +565,17 @@ class ASTContext : public RefCountedBase<ASTContext> {
clang::PrintingPolicy PrintingPolicy;
std::unique_ptr<interp::Context> InterpContext;
ast_type_traits::TraversalKind Traversal = ast_type_traits::TK_AsIs;
public:
ast_type_traits::TraversalKind getTraversalKind() const { return Traversal; }
void setTraversalKind(ast_type_traits::TraversalKind TK) { Traversal = TK; }
const Expr *traverseIgnored(const Expr *E) const;
Expr *traverseIgnored(Expr *E) const;
ast_type_traits::DynTypedNode
traverseIgnored(const ast_type_traits::DynTypedNode &N) const;
IdentifierTable &Idents;
SelectorTable &Selectors;
Builtin::Context &BuiltinInfo;
@ -1162,6 +1162,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// attribute.
QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const;
/// Remove the existing address space on the type if it is a pointer size
/// address space and return the type with qualifiers intact.
QualType removePtrSizeAddrSpace(QualType T) const;
/// Return the uniqued reference to the type for a \c restrict
/// qualified type.
///
@ -1216,6 +1220,15 @@ class ASTContext : public RefCountedBase<ASTContext> {
const FunctionProtoType::ExceptionSpecInfo &ESI,
bool AsWritten = false);
/// Get a function type and produce the equivalent function type where
/// pointer size address spaces in the return type and parameter tyeps are
/// replaced with the default address space.
QualType getFunctionTypeWithoutPtrSizes(QualType T);
/// Determine whether two function types are the same, ignoring pointer sizes
/// in the return type and parameter types.
bool hasSameFunctionTypeIgnoringPtrSizes(QualType T, QualType U);
/// Return the uniqued reference to the type for a complex
/// number with the specified element type.
QualType getComplexType(QualType T) const;
@ -2827,16 +2840,20 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// index of the parameter when it exceeds the size of the normal bitfield.
unsigned getParameterIndex(const ParmVarDecl *D) const;
/// Get the storage for the constant value of a materialized temporary
/// of static storage duration.
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;
/// Parses the target attributes passed in, and returns only the ones that are
/// valid feature names.
ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const;
void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
const FunctionDecl *) const;
void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
GlobalDecl GD) const;
//===--------------------------------------------------------------------===//
// Statistics
//===--------------------------------------------------------------------===//
@ -3007,7 +3024,7 @@ OPT_LIST(V)
std::vector<Decl *> TraversalScope;
class ParentMap;
std::unique_ptr<ParentMap> Parents;
std::map<ast_type_traits::TraversalKind, std::unique_ptr<ParentMap>> Parents;
std::unique_ptr<VTableContextBase> VTContext;
@ -3051,6 +3068,22 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
return Ctx.Selectors.getSelector(1, &II);
}
class TraversalKindScope {
ASTContext &Ctx;
ast_type_traits::TraversalKind TK = ast_type_traits::TK_AsIs;
public:
TraversalKindScope(ASTContext &Ctx,
llvm::Optional<ast_type_traits::TraversalKind> ScopeTK)
: Ctx(Ctx) {
TK = Ctx.getTraversalKind();
if (ScopeTK)
Ctx.setTraversalKind(*ScopeTK);
}
~TraversalKindScope() { Ctx.setTraversalKind(TK); }
};
} // namespace clang
// operator new and delete aren't allowed inside namespaces.

View File

@ -26,6 +26,10 @@ class Type;
#define TYPE(DERIVED, BASE) class DERIVED##Type;
#include "clang/AST/TypeNodes.inc"
class CXXCtorInitializer;
class OMPClause;
#define OPENMP_CLAUSE(KIND, CLASSNAME) class CLASSNAME;
#include "clang/Basic/OpenMPKinds.def"
} // end namespace clang

View File

@ -60,8 +60,12 @@ class TypeSourceInfo;
static char ID;
ImportError() : Error(Unknown) { }
ImportError(const ImportError &Other) : Error(Other.Error) { }
ImportError() : Error(Unknown) {}
ImportError(const ImportError &Other) : Error(Other.Error) {}
ImportError &operator=(const ImportError &Other) {
Error = Other.Error;
return *this;
}
ImportError(ErrorKind Error) : Error(Error) { }
std::string toString() const;

View File

@ -64,6 +64,17 @@ inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) {
dyn_cast<CXXMethodDecl>(DC));
}
inline bool isGenericLambdaCallOperatorOrStaticInvokerSpecialization(
DeclContext *DC) {
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC);
if (!MD) return false;
const CXXRecordDecl *LambdaClass = MD->getParent();
if (LambdaClass && LambdaClass->isGenericLambda())
return (isLambdaCallOperator(MD) || MD->isLambdaStaticInvoker()) &&
MD->isFunctionTemplateSpecialization();
return false;
}
// This returns the parent DeclContext ensuring that the correct
// parent DeclContext is returned for Lambdas

View File

@ -65,6 +65,9 @@ class ASTNodeTraverser
/// not already been loaded.
bool Deserialize = false;
ast_type_traits::TraversalKind Traversal =
ast_type_traits::TraversalKind::TK_AsIs;
NodeDelegateType &getNodeDelegate() {
return getDerived().doGetNodeDelegate();
}
@ -74,6 +77,8 @@ class ASTNodeTraverser
void setDeserialize(bool D) { Deserialize = D; }
bool getDeserialize() const { return Deserialize; }
void SetTraversalKind(ast_type_traits::TraversalKind TK) { Traversal = TK; }
void Visit(const Decl *D) {
getNodeDelegate().AddChild([=] {
getNodeDelegate().Visit(D);
@ -97,8 +102,23 @@ class ASTNodeTraverser
});
}
void Visit(const Stmt *S, StringRef Label = {}) {
void Visit(const Stmt *Node, StringRef Label = {}) {
getNodeDelegate().AddChild(Label, [=] {
const Stmt *S = Node;
if (auto *E = dyn_cast_or_null<Expr>(S)) {
switch (Traversal) {
case ast_type_traits::TK_AsIs:
break;
case ast_type_traits::TK_IgnoreImplicitCastsAndParentheses:
S = E->IgnoreParenImpCasts();
break;
case ast_type_traits::TK_IgnoreUnlessSpelledInSource:
S = E->IgnoreUnlessSpelledInSource();
break;
}
}
getNodeDelegate().Visit(S);
if (!S) {
@ -108,9 +128,12 @@ class ASTNodeTraverser
ConstStmtVisitor<Derived>::Visit(S);
// Some statements have custom mechanisms for dumping their children.
if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S)) {
if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S))
return;
if (isa<LambdaExpr>(S) &&
Traversal == ast_type_traits::TK_IgnoreUnlessSpelledInSource)
return;
}
for (const Stmt *SubStmt : S->children())
Visit(SubStmt);
@ -361,6 +384,9 @@ class ASTNodeTraverser
for (const auto *Parameter : D->parameters())
Visit(Parameter);
if (const Expr *TRC = D->getTrailingRequiresClause())
Visit(TRC);
if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
for (const auto *I : C->inits())
Visit(I);
@ -511,6 +537,10 @@ class ASTNodeTraverser
}
void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
if (const auto *TC = D->getTypeConstraint())
if (TC->hasExplicitTemplateArgs())
for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
dumpTemplateArgumentLoc(ArgLoc);
if (D->hasDefaultArgument())
Visit(D->getDefaultArgument(), SourceRange(),
D->getDefaultArgStorage().getInheritedFrom(),
@ -518,6 +548,8 @@ class ASTNodeTraverser
}
void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
if (const auto *TC = D->getPlaceholderTypeConstraint())
Visit(TC->getImmediatelyDeclaredConstraint());
if (D->hasDefaultArgument())
Visit(D->getDefaultArgument(), SourceRange(),
D->getDefaultArgStorage().getInheritedFrom(),
@ -620,13 +652,29 @@ class ASTNodeTraverser
Visit(E->getControllingExpr());
Visit(E->getControllingExpr()->getType()); // FIXME: remove
for (const auto &Assoc : E->associations()) {
for (const auto Assoc : E->associations()) {
Visit(Assoc);
}
}
void VisitLambdaExpr(const LambdaExpr *Node) {
Visit(Node->getLambdaClass());
if (Traversal == ast_type_traits::TK_IgnoreUnlessSpelledInSource) {
for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) {
const auto *C = Node->capture_begin() + I;
if (!C->isExplicit())
continue;
if (Node->isInitCapture(C))
Visit(C->getCapturedVar());
else
Visit(Node->capture_init_begin()[I]);
}
dumpTemplateParameters(Node->getTemplateParameterList());
for (const auto *P : Node->getCallOperator()->parameters())
Visit(P);
Visit(Node->getBody());
} else {
return Visit(Node->getLambdaClass());
}
}
void VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {

View File

@ -16,10 +16,7 @@
#define LLVM_CLANG_AST_ASTTYPETRAITS_H
#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"
#include "clang/Basic/LLVM.h"
@ -46,7 +43,10 @@ enum TraversalKind {
/// Will not traverse implicit casts and parentheses.
/// Corresponds to Expr::IgnoreParenImpCasts()
TK_IgnoreImplicitCastsAndParentheses
TK_IgnoreImplicitCastsAndParentheses,
/// Ignore AST nodes not written in the source
TK_IgnoreUnlessSpelledInSource
};
/// Kind identifier.

View File

@ -0,0 +1,263 @@
//==--- AbstractBasiceReader.h - Abstract basic value deserialization -----===//
//
// 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 CLANG_AST_ABSTRACTBASICREADER_H
#define CLANG_AST_ABSTRACTBASICREADER_H
#include "clang/AST/DeclTemplate.h"
namespace clang {
namespace serialization {
template <class T>
inline T makeNullableFromOptional(const Optional<T> &value) {
return (value ? *value : T());
}
template <class T>
inline T *makePointerFromOptional(Optional<T *> value) {
return (value ? *value : nullptr);
}
// PropertyReader is a class concept that requires the following method:
// BasicReader find(llvm::StringRef propertyName);
// where BasicReader is some class conforming to the BasicReader concept.
// An abstract AST-node reader is created with a PropertyReader and
// performs a sequence of calls like so:
// propertyReader.find(propertyName).read##TypeName()
// to read the properties of the node it is deserializing.
// BasicReader is a class concept that requires methods like:
// ValueType read##TypeName();
// where TypeName is the name of a PropertyType node from PropertiesBase.td
// and ValueType is the corresponding C++ type name. The read method may
// require one or more buffer arguments.
//
// In addition to the concrete type names, BasicReader is expected to
// implement these methods:
//
// template <class EnumType>
// void writeEnum(T value);
//
// Reads an enum value from the current property. EnumType will always
// be an enum type. Only necessary if the BasicReader doesn't provide
// type-specific readers for all the enum types.
//
// template <class ValueType>
// Optional<ValueType> writeOptional();
//
// Reads an optional value from the current property.
//
// template <class ValueType>
// ArrayRef<ValueType> readArray(llvm::SmallVectorImpl<ValueType> &buffer);
//
// Reads an array of values from the current property.
//
// PropertyReader readObject();
//
// Reads an object from the current property; the returned property
// reader will be subjected to a sequence of property reads and then
// discarded before any other properties are reader from the "outer"
// property reader (which need not be the same type). The sub-reader
// will be used as if with the following code:
//
// {
// auto &&widget = W.find("widget").readObject();
// auto kind = widget.find("kind").readWidgetKind();
// auto declaration = widget.find("declaration").readDeclRef();
// return Widget(kind, declaration);
// }
// ReadDispatcher does type-based forwarding to one of the read methods
// on the BasicReader passed in:
//
// template <class ValueType>
// struct ReadDispatcher {
// template <class BasicReader, class... BufferTypes>
// static ValueType read(BasicReader &R, BufferTypes &&...);
// };
// BasicReaderBase provides convenience implementations of the read methods
// for EnumPropertyType and SubclassPropertyType types that just defer to
// the "underlying" implementations (for UInt32 and the base class,
// respectively).
//
// template <class Impl>
// class BasicReaderBase {
// protected:
// BasicReaderBase(ASTContext &ctx);
// Impl &asImpl();
// public:
// ASTContext &getASTContext();
// ...
// };
// The actual classes are auto-generated; see ClangASTPropertiesEmitter.cpp.
#include "clang/AST/AbstractBasicReader.inc"
/// DataStreamBasicReader provides convenience implementations for many
/// BasicReader methods based on the assumption that the
/// ultimate reader implementation is based on a variable-length stream
/// of unstructured data (like Clang's module files). It is designed
/// to pair with DataStreamBasicWriter.
///
/// This class can also act as a PropertyReader, implementing find("...")
/// by simply forwarding to itself.
///
/// Unimplemented methods:
/// readBool
/// readUInt32
/// readUInt64
/// readIdentifier
/// readSelector
/// readSourceLocation
/// readQualType
/// readStmtRef
/// readDeclRef
template <class Impl>
class DataStreamBasicReader : public BasicReaderBase<Impl> {
protected:
using BasicReaderBase<Impl>::asImpl;
DataStreamBasicReader(ASTContext &ctx) : BasicReaderBase<Impl>(ctx) {}
public:
using BasicReaderBase<Impl>::getASTContext;
/// Implement property-find by ignoring it. We rely on properties being
/// serialized and deserialized in a reliable order instead.
Impl &find(const char *propertyName) {
return asImpl();
}
template <class T>
T readEnum() {
return T(asImpl().readUInt32());
}
// Implement object reading by forwarding to this, collapsing the
// structure into a single data stream.
Impl &readObject() { return asImpl(); }
template <class T>
llvm::ArrayRef<T> readArray(llvm::SmallVectorImpl<T> &buffer) {
assert(buffer.empty());
uint32_t size = asImpl().readUInt32();
buffer.reserve(size);
for (uint32_t i = 0; i != size; ++i) {
buffer.push_back(ReadDispatcher<T>::read(asImpl()));
}
return buffer;
}
template <class T, class... Args>
llvm::Optional<T> readOptional(Args &&...args) {
return UnpackOptionalValue<T>::unpack(
ReadDispatcher<T>::read(asImpl(), std::forward<Args>(args)...));
}
llvm::APSInt readAPSInt() {
bool isUnsigned = asImpl().readBool();
llvm::APInt value = asImpl().readAPInt();
return llvm::APSInt(std::move(value), isUnsigned);
}
llvm::APInt readAPInt() {
unsigned bitWidth = asImpl().readUInt32();
unsigned numWords = llvm::APInt::getNumWords(bitWidth);
llvm::SmallVector<uint64_t, 4> data;
for (uint32_t i = 0; i != numWords; ++i)
data.push_back(asImpl().readUInt64());
return llvm::APInt(bitWidth, numWords, &data[0]);
}
Qualifiers readQualifiers() {
static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint32_t),
"update this if the value size changes");
uint32_t value = asImpl().readUInt32();
return Qualifiers::fromOpaqueValue(value);
}
FunctionProtoType::ExceptionSpecInfo
readExceptionSpecInfo(llvm::SmallVectorImpl<QualType> &buffer) {
FunctionProtoType::ExceptionSpecInfo esi;
esi.Type = ExceptionSpecificationType(asImpl().readUInt32());
if (esi.Type == EST_Dynamic) {
esi.Exceptions = asImpl().template readArray<QualType>(buffer);
} else if (isComputedNoexcept(esi.Type)) {
esi.NoexceptExpr = asImpl().readExprRef();
} else if (esi.Type == EST_Uninstantiated) {
esi.SourceDecl = asImpl().readFunctionDeclRef();
esi.SourceTemplate = asImpl().readFunctionDeclRef();
} else if (esi.Type == EST_Unevaluated) {
esi.SourceDecl = asImpl().readFunctionDeclRef();
}
return esi;
}
FunctionProtoType::ExtParameterInfo readExtParameterInfo() {
static_assert(sizeof(FunctionProtoType::ExtParameterInfo().getOpaqueValue())
<= sizeof(uint32_t),
"opaque value doesn't fit into uint32_t");
uint32_t value = asImpl().readUInt32();
return FunctionProtoType::ExtParameterInfo::getFromOpaqueValue(value);
}
NestedNameSpecifier *readNestedNameSpecifier() {
auto &ctx = getASTContext();
// We build this up iteratively.
NestedNameSpecifier *cur = nullptr;
uint32_t depth = asImpl().readUInt32();
for (uint32_t i = 0; i != depth; ++i) {
auto kind = asImpl().readNestedNameSpecifierKind();
switch (kind) {
case NestedNameSpecifier::Identifier:
cur = NestedNameSpecifier::Create(ctx, cur,
asImpl().readIdentifier());
continue;
case NestedNameSpecifier::Namespace:
cur = NestedNameSpecifier::Create(ctx, cur,
asImpl().readNamespaceDeclRef());
continue;
case NestedNameSpecifier::NamespaceAlias:
cur = NestedNameSpecifier::Create(ctx, cur,
asImpl().readNamespaceAliasDeclRef());
continue;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
cur = NestedNameSpecifier::Create(ctx, cur,
kind == NestedNameSpecifier::TypeSpecWithTemplate,
asImpl().readQualType().getTypePtr());
continue;
case NestedNameSpecifier::Global:
cur = NestedNameSpecifier::GlobalSpecifier(ctx);
continue;
case NestedNameSpecifier::Super:
cur = NestedNameSpecifier::SuperSpecifier(ctx,
asImpl().readCXXRecordDeclRef());
continue;
}
llvm_unreachable("bad nested name specifier kind");
}
return cur;
}
};
} // end namespace serialization
} // end namespace clang
#endif

View File

@ -0,0 +1,243 @@
//==--- AbstractBasicWriter.h - Abstract basic value serialization --------===//
//
// 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 CLANG_AST_ABSTRACTBASICWRITER_H
#define CLANG_AST_ABSTRACTBASICWRITER_H
#include "clang/AST/DeclTemplate.h"
namespace clang {
namespace serialization {
template <class T>
inline llvm::Optional<T> makeOptionalFromNullable(const T &value) {
return (value.isNull()
? llvm::Optional<T>()
: llvm::Optional<T>(value));
}
template <class T>
inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
return (value ? llvm::Optional<T*>(value) : llvm::Optional<T*>());
}
// PropertyWriter is a class concept that requires the following method:
// BasicWriter find(llvm::StringRef propertyName);
// where BasicWriter is some class conforming to the BasicWriter concept.
// An abstract AST-node writer is created with a PropertyWriter and
// performs a sequence of calls like so:
// propertyWriter.find(propertyName).write##TypeName(value)
// to write the properties of the node it is serializing.
// BasicWriter is a class concept that requires methods like:
// void write##TypeName(ValueType value);
// where TypeName is the name of a PropertyType node from PropertiesBase.td
// and ValueType is the corresponding C++ type name.
//
// In addition to the concrete property types, BasicWriter is expected
// to implement these methods:
//
// template <class EnumType>
// void writeEnum(T value);
//
// Writes an enum value as the current property. EnumType will always
// be an enum type. Only necessary if the BasicWriter doesn't provide
// type-specific writers for all the enum types.
//
// template <class ValueType>
// void writeOptional(Optional<ValueType> value);
//
// Writes an optional value as the current property.
//
// template <class ValueType>
// void writeArray(ArrayRef<ValueType> value);
//
// Writes an array of values as the current property.
//
// PropertyWriter writeObject();
//
// Writes an object as the current property; the returned property
// writer will be subjected to a sequence of property writes and then
// discarded before any other properties are written to the "outer"
// property writer (which need not be the same type). The sub-writer
// will be used as if with the following code:
//
// {
// auto &&widget = W.find("widget").writeObject();
// widget.find("kind").writeWidgetKind(...);
// widget.find("declaration").writeDeclRef(...);
// }
// WriteDispatcher is a template which does type-based forwarding to one
// of the write methods of the BasicWriter passed in:
//
// template <class ValueType>
// struct WriteDispatcher {
// template <class BasicWriter>
// static void write(BasicWriter &W, ValueType value);
// };
// BasicWriterBase provides convenience implementations of the write
// methods for EnumPropertyType and SubclassPropertyType types that just
// defer to the "underlying" implementations (for UInt32 and the base class,
// respectively).
//
// template <class Impl>
// class BasicWriterBase {
// protected:
// Impl &asImpl();
// public:
// ...
// };
// The actual classes are auto-generated; see ClangASTPropertiesEmitter.cpp.
#include "clang/AST/AbstractBasicWriter.inc"
/// DataStreamBasicWriter provides convenience implementations for many
/// BasicWriter methods based on the assumption that the
/// ultimate writer implementation is based on a variable-length stream
/// of unstructured data (like Clang's module files). It is designed
/// to pair with DataStreamBasicReader.
///
/// This class can also act as a PropertyWriter, implementing find("...")
/// by simply forwarding to itself.
///
/// Unimplemented methods:
/// writeBool
/// writeUInt32
/// writeUInt64
/// writeIdentifier
/// writeSelector
/// writeSourceLocation
/// writeQualType
/// writeStmtRef
/// writeDeclRef
template <class Impl>
class DataStreamBasicWriter : public BasicWriterBase<Impl> {
protected:
using BasicWriterBase<Impl>::asImpl;
public:
/// Implement property-find by ignoring it. We rely on properties being
/// serialized and deserialized in a reliable order instead.
Impl &find(const char *propertyName) {
return asImpl();
}
// Implement object writing by forwarding to this, collapsing the
// structure into a single data stream.
Impl &writeObject() { return asImpl(); }
template <class T>
void writeEnum(T value) {
asImpl().writeUInt32(uint32_t(value));
}
template <class T>
void writeArray(llvm::ArrayRef<T> array) {
asImpl().writeUInt32(array.size());
for (const T &elt : array) {
WriteDispatcher<T>::write(asImpl(), elt);
}
}
template <class T>
void writeOptional(llvm::Optional<T> value) {
WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
}
void writeAPSInt(const llvm::APSInt &value) {
asImpl().writeBool(value.isUnsigned());
asImpl().writeAPInt(value);
}
void writeAPInt(const llvm::APInt &value) {
asImpl().writeUInt32(value.getBitWidth());
const uint64_t *words = value.getRawData();
for (size_t i = 0, e = value.getNumWords(); i != e; ++i)
asImpl().writeUInt64(words[i]);
}
void writeQualifiers(Qualifiers value) {
static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint32_t),
"update this if the value size changes");
asImpl().writeUInt32(value.getAsOpaqueValue());
}
void writeExceptionSpecInfo(
const FunctionProtoType::ExceptionSpecInfo &esi) {
asImpl().writeUInt32(uint32_t(esi.Type));
if (esi.Type == EST_Dynamic) {
asImpl().writeArray(esi.Exceptions);
} else if (isComputedNoexcept(esi.Type)) {
asImpl().writeExprRef(esi.NoexceptExpr);
} else if (esi.Type == EST_Uninstantiated) {
asImpl().writeDeclRef(esi.SourceDecl);
asImpl().writeDeclRef(esi.SourceTemplate);
} else if (esi.Type == EST_Unevaluated) {
asImpl().writeDeclRef(esi.SourceDecl);
}
}
void writeExtParameterInfo(FunctionProtoType::ExtParameterInfo epi) {
static_assert(sizeof(epi.getOpaqueValue()) <= sizeof(uint32_t),
"opaque value doesn't fit into uint32_t");
asImpl().writeUInt32(epi.getOpaqueValue());
}
void writeNestedNameSpecifier(NestedNameSpecifier *NNS) {
// Nested name specifiers usually aren't too long. I think that 8 would
// typically accommodate the vast majority.
SmallVector<NestedNameSpecifier *, 8> nestedNames;
// Push each of the NNS's onto a stack for serialization in reverse order.
while (NNS) {
nestedNames.push_back(NNS);
NNS = NNS->getPrefix();
}
asImpl().writeUInt32(nestedNames.size());
while (!nestedNames.empty()) {
NNS = nestedNames.pop_back_val();
NestedNameSpecifier::SpecifierKind kind = NNS->getKind();
asImpl().writeNestedNameSpecifierKind(kind);
switch (kind) {
case NestedNameSpecifier::Identifier:
asImpl().writeIdentifier(NNS->getAsIdentifier());
continue;
case NestedNameSpecifier::Namespace:
asImpl().writeNamespaceDeclRef(NNS->getAsNamespace());
continue;
case NestedNameSpecifier::NamespaceAlias:
asImpl().writeNamespaceAliasDeclRef(NNS->getAsNamespaceAlias());
continue;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
asImpl().writeQualType(QualType(NNS->getAsType(), 0));
continue;
case NestedNameSpecifier::Global:
// Don't need to write an associated value.
continue;
case NestedNameSpecifier::Super:
asImpl().writeDeclRef(NNS->getAsRecordDecl());
continue;
}
llvm_unreachable("bad nested name specifier kind");
}
}
};
} // end namespace serialization
} // end namespace clang
#endif

View File

@ -0,0 +1,31 @@
//==--- AbstractTypeReader.h - Abstract deserialization for types ---------===//
//
// 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 CLANG_AST_ABSTRACTTYPEREADER_H
#define CLANG_AST_ABSTRACTTYPEREADER_H
#include "clang/AST/Type.h"
#include "clang/AST/AbstractBasicReader.h"
namespace clang {
namespace serialization {
// template <class PropertyReader>
// class AbstractTypeReader {
// public:
// AbstractTypeReader(PropertyReader &W);
// QualType read(Type::TypeClass kind);
// };
//
// The actual class is auto-generated; see ClangASTPropertiesEmitter.cpp.
#include "clang/AST/AbstractTypeReader.inc"
} // end namespace serialization
} // end namespace clang
#endif

View File

@ -0,0 +1,32 @@
//==--- AbstractTypeWriter.h - Abstract serialization for types -----------===//
//
// 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 CLANG_AST_ABSTRACTTYPEWRITER_H
#define CLANG_AST_ABSTRACTTYPEWRITER_H
#include "clang/AST/Type.h"
#include "clang/AST/AbstractBasicWriter.h"
#include "clang/AST/DeclObjC.h"
namespace clang {
namespace serialization {
// template <class PropertyWriter>
// class AbstractTypeWriter {
// public:
// AbstractTypeWriter(PropertyWriter &W);
// void write(QualType type);
// };
//
// The actual class is auto-generated; see ClangASTPropertiesEmitter.cpp.
#include "clang/AST/AbstractTypeWriter.inc"
} // end namespace serialization
} // end namespace clang
#endif

View File

@ -32,83 +32,83 @@
#include <cassert>
namespace clang {
class ASTContext;
class AttributeCommonInfo;
class IdentifierInfo;
class ObjCInterfaceDecl;
class Expr;
class QualType;
class FunctionDecl;
class TypeSourceInfo;
class ASTContext;
class AttributeCommonInfo;
class IdentifierInfo;
class ObjCInterfaceDecl;
class Expr;
class QualType;
class FunctionDecl;
class TypeSourceInfo;
/// Attr - This represents one attribute.
class Attr : public AttributeCommonInfo {
private:
unsigned AttrKind : 16;
class Attr : public AttributeCommonInfo {
private:
unsigned AttrKind : 16;
protected:
/// An index into the spelling list of an
/// attribute defined in Attr.td file.
unsigned Inherited : 1;
unsigned IsPackExpansion : 1;
unsigned Implicit : 1;
// FIXME: These are properties of the attribute kind, not state for this
// instance of the attribute.
unsigned IsLateParsed : 1;
unsigned InheritEvenIfAlreadyPresent : 1;
protected:
/// An index into the spelling list of an
/// attribute defined in Attr.td file.
unsigned Inherited : 1;
unsigned IsPackExpansion : 1;
unsigned Implicit : 1;
// FIXME: These are properties of the attribute kind, not state for this
// instance of the attribute.
unsigned IsLateParsed : 1;
unsigned InheritEvenIfAlreadyPresent : 1;
void *operator new(size_t bytes) noexcept {
llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
}
void operator delete(void *data) noexcept {
llvm_unreachable("Attrs cannot be released with regular 'delete'.");
}
void *operator new(size_t bytes) noexcept {
llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
}
void operator delete(void *data) noexcept {
llvm_unreachable("Attrs cannot be released with regular 'delete'.");
}
public:
// Forward so that the regular new and delete do not hide global ones.
void *operator new(size_t Bytes, ASTContext &C,
size_t Alignment = 8) noexcept {
return ::operator new(Bytes, C, Alignment);
}
void operator delete(void *Ptr, ASTContext &C, size_t Alignment) noexcept {
return ::operator delete(Ptr, C, Alignment);
}
public:
// Forward so that the regular new and delete do not hide global ones.
void *operator new(size_t Bytes, ASTContext &C,
size_t Alignment = 8) noexcept {
return ::operator new(Bytes, C, Alignment);
}
void operator delete(void *Ptr, ASTContext &C, size_t Alignment) noexcept {
return ::operator delete(Ptr, C, Alignment);
}
protected:
Attr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
attr::Kind AK, bool IsLateParsed)
: AttributeCommonInfo(CommonInfo), AttrKind(AK), Inherited(false),
IsPackExpansion(false), Implicit(false), IsLateParsed(IsLateParsed),
InheritEvenIfAlreadyPresent(false) {}
protected:
Attr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
attr::Kind AK, bool IsLateParsed)
: AttributeCommonInfo(CommonInfo), AttrKind(AK), Inherited(false),
IsPackExpansion(false), Implicit(false), IsLateParsed(IsLateParsed),
InheritEvenIfAlreadyPresent(false) {}
public:
attr::Kind getKind() const { return static_cast<attr::Kind>(AttrKind); }
public:
attr::Kind getKind() const { return static_cast<attr::Kind>(AttrKind); }
unsigned getSpellingListIndex() const {
return getAttributeSpellingListIndex();
}
const char *getSpelling() const;
unsigned getSpellingListIndex() const {
return getAttributeSpellingListIndex();
}
const char *getSpelling() const;
SourceLocation getLocation() const { return getRange().getBegin(); }
SourceLocation getLocation() const { return getRange().getBegin(); }
bool isInherited() const { return Inherited; }
bool isInherited() const { return Inherited; }
/// Returns true if the attribute has been implicitly created instead
/// of explicitly written by the user.
bool isImplicit() const { return Implicit; }
void setImplicit(bool I) { Implicit = I; }
/// Returns true if the attribute has been implicitly created instead
/// of explicitly written by the user.
bool isImplicit() const { return Implicit; }
void setImplicit(bool I) { Implicit = I; }
void setPackExpansion(bool PE) { IsPackExpansion = PE; }
bool isPackExpansion() const { return IsPackExpansion; }
void setPackExpansion(bool PE) { IsPackExpansion = PE; }
bool isPackExpansion() const { return IsPackExpansion; }
// Clone this attribute.
Attr *clone(ASTContext &C) const;
// Clone this attribute.
Attr *clone(ASTContext &C) const;
bool isLateParsed() const { return IsLateParsed; }
bool isLateParsed() const { return IsLateParsed; }
// Pretty print this attribute.
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
};
// Pretty print this attribute.
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
};
class TypeAttr : public Attr {
protected:
@ -329,6 +329,18 @@ class ParamIdx {
static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType),
"ParamIdx does not fit its serialization type");
/// Contains information gathered from parsing the contents of TargetAttr.
struct ParsedTargetAttr {
std::vector<std::string> Features;
StringRef Architecture;
StringRef BranchProtection;
bool DuplicateArchitecture = false;
bool operator ==(const ParsedTargetAttr &Other) const {
return DuplicateArchitecture == Other.DuplicateArchitecture &&
Architecture == Other.Architecture && Features == Other.Features;
}
};
#include "clang/AST/Attrs.inc"
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,

View File

@ -372,6 +372,30 @@ class CXXFinalOverriderMap
class CXXIndirectPrimaryBaseSet
: public llvm::SmallSet<const CXXRecordDecl*, 32> {};
inline bool
inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance) {
return Inheritance == MSInheritanceModel::Unspecified;
}
// Only member pointers to functions need a this adjustment, since it can be
// combined with the field offset for data pointers.
inline bool inheritanceModelHasNVOffsetField(bool IsMemberFunction,
MSInheritanceModel Inheritance) {
return IsMemberFunction && Inheritance >= MSInheritanceModel::Multiple;
}
inline bool
inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance) {
return Inheritance >= MSInheritanceModel::Virtual;
}
inline bool inheritanceModelHasOnlyOneField(bool IsMemberFunction,
MSInheritanceModel Inheritance) {
if (IsMemberFunction)
return Inheritance <= MSInheritanceModel::Single;
return Inheritance <= MSInheritanceModel::Multiple;
}
} // namespace clang
#endif // LLVM_CLANG_AST_CXXINHERITANCE_H

View File

@ -94,10 +94,11 @@ class Comment {
unsigned : NumInlineContentCommentBits;
unsigned RenderKind : 2;
unsigned RenderKind : 3;
unsigned CommandID : CommandInfo::NumCommandIDBits;
};
enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 2 +
enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 3 +
CommandInfo::NumCommandIDBits };
class HTMLTagCommentBitfields {
@ -310,7 +311,8 @@ class InlineCommandComment : public InlineContentComment {
RenderNormal,
RenderBold,
RenderMonospaced,
RenderEmphasized
RenderEmphasized,
RenderAnchor
};
protected:

View File

@ -81,12 +81,13 @@ class RecordLikeDeclarationVerbatimLineCommand<string name> :
// InlineCommand
//===----------------------------------------------------------------------===//
def B : InlineCommand<"b">;
def C : InlineCommand<"c">;
def P : InlineCommand<"p">;
def A : InlineCommand<"a">;
def E : InlineCommand<"e">;
def Em : InlineCommand<"em">;
def B : InlineCommand<"b">;
def C : InlineCommand<"c">;
def P : InlineCommand<"p">;
def A : InlineCommand<"a">;
def E : InlineCommand<"e">;
def Em : InlineCommand<"em">;
def Anchor : InlineCommand<"anchor">;
//===----------------------------------------------------------------------===//
// BlockCommand

View File

@ -41,23 +41,30 @@ class NamespaceDecl;
/// partial_ordering, weak_ordering, and strong_ordering are collectively
/// termed the comparison category types.
enum class ComparisonCategoryType : unsigned char {
WeakEquality,
StrongEquality,
PartialOrdering,
WeakOrdering,
StrongOrdering,
First = WeakEquality,
First = PartialOrdering,
Last = StrongOrdering
};
/// Determine the common comparison type, as defined in C++2a
/// [class.spaceship]p4.
inline ComparisonCategoryType commonComparisonType(ComparisonCategoryType A,
ComparisonCategoryType B) {
return A < B ? A : B;
}
/// Get the comparison category that should be used when comparing values of
/// type \c T.
Optional<ComparisonCategoryType> getComparisonCategoryForBuiltinCmp(QualType T);
/// An enumeration representing the possible results of a three-way
/// comparison. These values map onto instances of comparison category types
/// defined in the standard library. e.g. 'std::strong_ordering::less'.
enum class ComparisonCategoryResult : unsigned char {
Equal,
Equivalent,
Nonequivalent,
Nonequal,
Less,
Greater,
Unordered,
@ -125,21 +132,11 @@ class ComparisonCategoryInfo {
return Info;
}
/// True iff the comparison category is an equality comparison.
bool isEquality() const { return !isOrdered(); }
/// True iff the comparison category is a relational comparison.
bool isOrdered() const {
using CCK = ComparisonCategoryType;
return Kind == CCK::PartialOrdering || Kind == CCK::WeakOrdering ||
Kind == CCK::StrongOrdering;
}
/// True iff the comparison is "strong". i.e. it checks equality and
/// not equivalence.
bool isStrong() const {
using CCK = ComparisonCategoryType;
return Kind == CCK::StrongEquality || Kind == CCK::StrongOrdering;
return Kind == CCK::StrongOrdering;
}
/// True iff the comparison is not totally ordered.
@ -153,28 +150,18 @@ class ComparisonCategoryInfo {
/// weak equivalence if needed.
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const {
using CCR = ComparisonCategoryResult;
if (!isStrong()) {
if (Res == CCR::Equal)
return CCR::Equivalent;
if (Res == CCR::Nonequal)
return CCR::Nonequivalent;
}
if (!isStrong() && Res == CCR::Equal)
return CCR::Equivalent;
return Res;
}
const ValueInfo *getEqualOrEquiv() const {
return getValueInfo(makeWeakResult(ComparisonCategoryResult::Equal));
}
const ValueInfo *getNonequalOrNonequiv() const {
assert(isEquality());
return getValueInfo(makeWeakResult(ComparisonCategoryResult::Nonequal));
}
const ValueInfo *getLess() const {
assert(isOrdered());
return getValueInfo(ComparisonCategoryResult::Less);
}
const ValueInfo *getGreater() const {
assert(isOrdered());
return getValueInfo(ComparisonCategoryResult::Greater);
}
const ValueInfo *getUnordered() const {
@ -221,7 +208,6 @@ class ComparisonCategories {
return const_cast<ComparisonCategoryInfo *>(This.lookupInfo(Kind));
}
private:
const ComparisonCategoryInfo *lookupInfoForType(QualType Ty) const;
private:

View File

@ -15,6 +15,7 @@
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContextAllocate.h"
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
@ -59,6 +60,7 @@ class EnumDecl;
class Expr;
class FunctionTemplateDecl;
class FunctionTemplateSpecializationInfo;
class FunctionTypeLoc;
class LabelStmt;
class MemberSpecializationInfo;
class Module;
@ -76,33 +78,6 @@ class TypeLoc;
class UnresolvedSetImpl;
class VarTemplateDecl;
/// A container of type source information.
///
/// A client can read the relevant info using TypeLoc wrappers, e.g:
/// @code
/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
/// TL.getBeginLoc().print(OS, SrcMgr);
/// @endcode
class alignas(8) TypeSourceInfo {
// Contains a memory block after the class, used for type source information,
// allocated by ASTContext.
friend class ASTContext;
QualType Ty;
TypeSourceInfo(QualType ty) : Ty(ty) {}
public:
/// Return the type wrapped by this type source info.
QualType getType() const { return Ty; }
/// Return the TypeLoc wrapper for the type source info.
TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
/// Override the type stored in this TypeSourceInfo. Use with caution!
void overrideType(QualType T) { Ty = T; }
};
/// The top declaration context.
class TranslationUnitDecl : public Decl, public DeclContext {
ASTContext &Ctx;
@ -694,10 +669,12 @@ struct QualifierInfo {
/// Represents a ValueDecl that came out of a declarator.
/// Contains type source information through TypeSourceInfo.
class DeclaratorDecl : public ValueDecl {
// A struct representing both a TInfo and a syntactic qualifier,
// to be used for the (uncommon) case of out-of-line declarations.
// A struct representing a TInfo, a trailing requires-clause and a syntactic
// qualifier, to be used for the (uncommon) case of out-of-line declarations
// and constrained function decls.
struct ExtInfo : public QualifierInfo {
TypeSourceInfo *TInfo;
Expr *TrailingRequiresClause = nullptr;
};
llvm::PointerUnion<TypeSourceInfo *, ExtInfo *> DeclInfo;
@ -764,6 +741,21 @@ class DeclaratorDecl : public ValueDecl {
void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
/// \brief Get the constraint-expression introduced by the trailing
/// requires-clause in the function/member declaration, or null if no
/// requires-clause was provided.
Expr *getTrailingRequiresClause() {
return hasExtInfo() ? getExtInfo()->TrailingRequiresClause
: nullptr;
}
const Expr *getTrailingRequiresClause() const {
return hasExtInfo() ? getExtInfo()->TrailingRequiresClause
: nullptr;
}
void setTrailingRequiresClause(Expr *TrailingRequiresClause);
unsigned getNumTemplateParameterLists() const {
return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
}
@ -777,6 +769,7 @@ class DeclaratorDecl : public ValueDecl {
ArrayRef<TemplateParameterList *> TPLists);
SourceLocation getTypeSpecStartLoc() const;
SourceLocation getTypeSpecEndLoc() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@ -898,6 +891,8 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
DAK_Normal
};
enum { NumScopeDepthOrObjCQualsBits = 7 };
class ParmVarDeclBitfields {
friend class ASTDeclReader;
friend class ParmVarDecl;
@ -924,7 +919,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
/// Otherwise, the number of function parameter scopes enclosing
/// the function parameter scope in which this parameter was
/// declared.
unsigned ScopeDepthOrObjCQuals : 7;
unsigned ScopeDepthOrObjCQuals : NumScopeDepthOrObjCQualsBits;
/// The number of parameters preceding this parameter in the
/// function parameter scope in which it was declared.
@ -1524,8 +1519,8 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
/// need not have a usable destructor at all.
bool isNoDestroy(const ASTContext &) const;
/// Do we need to emit an exit-time destructor for this variable, and if so,
/// what kind?
/// Would the destruction of this variable have any effect, and if so, what
/// kind?
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const;
// Implement isa/cast/dyncast/etc.
@ -1649,6 +1644,10 @@ class ParmVarDecl : public VarDecl {
return ParmVarDeclBits.ScopeDepthOrObjCQuals;
}
static constexpr unsigned getMaxFunctionScopeDepth() {
return (1u << NumScopeDepthOrObjCQualsBits) - 1;
}
/// Returns the index of this parameter in its prototype or method scope.
unsigned getFunctionScopeIndex() const {
return getParameterIndex();
@ -1805,13 +1804,37 @@ class FunctionDecl : public DeclaratorDecl,
TK_DependentFunctionTemplateSpecialization
};
/// Stashed information about a defaulted function definition whose body has
/// not yet been lazily generated.
class DefaultedFunctionInfo final
: llvm::TrailingObjects<DefaultedFunctionInfo, DeclAccessPair> {
friend TrailingObjects;
unsigned NumLookups;
public:
static DefaultedFunctionInfo *Create(ASTContext &Context,
ArrayRef<DeclAccessPair> Lookups);
/// Get the unqualified lookup results that should be used in this
/// defaulted function definition.
ArrayRef<DeclAccessPair> getUnqualifiedLookups() const {
return {getTrailingObjects<DeclAccessPair>(), NumLookups};
}
};
private:
/// A new[]'d array of pointers to VarDecls for the formal
/// parameters of this function. This is null if a prototype or if there are
/// no formals.
ParmVarDecl **ParamInfo = nullptr;
LazyDeclStmtPtr Body;
/// The active member of this union is determined by
/// FunctionDeclBits.HasDefaultedFunctionInfo.
union {
/// The body of the function.
LazyDeclStmtPtr Body;
/// Information about a future defaulted function definition.
DefaultedFunctionInfo *DefaultedInfo;
};
unsigned ODRHash;
@ -1836,10 +1859,10 @@ class FunctionDecl : public DeclaratorDecl,
/// FunctionTemplateSpecializationInfo, which contains information about
/// the template being specialized and the template arguments involved in
/// that specialization.
llvm::PointerUnion4<FunctionTemplateDecl *,
MemberSpecializationInfo *,
FunctionTemplateSpecializationInfo *,
DependentFunctionTemplateSpecializationInfo *>
llvm::PointerUnion<FunctionTemplateDecl *,
MemberSpecializationInfo *,
FunctionTemplateSpecializationInfo *,
DependentFunctionTemplateSpecializationInfo *>
TemplateOrSpecialization;
/// Provides source/type location info for the declaration name embedded in
@ -1897,7 +1920,8 @@ class FunctionDecl : public DeclaratorDecl,
FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified,
ConstexprSpecKind ConstexprKind);
ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause = nullptr);
using redeclarable_base = Redeclarable<FunctionDecl>;
@ -1932,11 +1956,12 @@ class FunctionDecl : public DeclaratorDecl,
SourceLocation NLoc, DeclarationName N, QualType T,
TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified = false,
bool hasWrittenPrototype = true,
ConstexprSpecKind ConstexprKind = CSK_unspecified) {
ConstexprSpecKind ConstexprKind = CSK_unspecified,
Expr *TrailingRequiresClause = nullptr) {
DeclarationNameInfo NameInfo(N, NLoc);
return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC,
isInlineSpecified, hasWrittenPrototype,
ConstexprKind);
ConstexprKind, TrailingRequiresClause);
}
static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
@ -1944,7 +1969,8 @@ class FunctionDecl : public DeclaratorDecl,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, StorageClass SC,
bool isInlineSpecified, bool hasWrittenPrototype,
ConstexprSpecKind ConstexprKind);
ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause);
static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@ -1957,6 +1983,14 @@ class FunctionDecl : public DeclaratorDecl,
void setRangeEnd(SourceLocation E) { EndRangeLoc = E; }
/// Returns the location of the ellipsis of a variadic function.
SourceLocation getEllipsisLoc() const {
const auto *FPT = getType()->getAs<FunctionProtoType>();
if (FPT && FPT->isVariadic())
return FPT->getEllipsisLoc();
return SourceLocation();
}
SourceRange getSourceRange() const override LLVM_READONLY;
// Function definitions.
@ -2030,18 +2064,30 @@ class FunctionDecl : public DeclaratorDecl,
///
/// This does not determine whether the function has been defined (e.g., in a
/// previous definition); for that information, use isDefined.
///
/// Note: the function declaration does not become a definition until the
/// parser reaches the definition, if called before, this function will return
/// `false`.
bool isThisDeclarationADefinition() const {
return isDeletedAsWritten() || isDefaulted() || Body || hasSkippedBody() ||
isLateTemplateParsed() || willHaveBody() || hasDefiningAttr();
return isDeletedAsWritten() || isDefaulted() ||
doesThisDeclarationHaveABody() || hasSkippedBody() ||
willHaveBody() || hasDefiningAttr();
}
/// Returns whether this specific declaration of the function has a body.
bool doesThisDeclarationHaveABody() const {
return Body || isLateTemplateParsed();
return (!FunctionDeclBits.HasDefaultedFunctionInfo && Body) ||
isLateTemplateParsed();
}
void setBody(Stmt *B);
void setLazyBody(uint64_t Offset) { Body = Offset; }
void setLazyBody(uint64_t Offset) {
FunctionDeclBits.HasDefaultedFunctionInfo = false;
Body = LazyDeclStmtPtr(Offset);
}
void setDefaultedFunctionInfo(DefaultedFunctionInfo *Info);
DefaultedFunctionInfo *getDefaultedFunctionInfo() const;
/// Whether this function is variadic.
bool isVariadic() const;
@ -2096,6 +2142,16 @@ class FunctionDecl : public DeclaratorDecl,
FunctionDeclBits.IsExplicitlyDefaulted = ED;
}
/// True if this method is user-declared and was not
/// deleted or defaulted on its first declaration.
bool isUserProvided() const {
auto *DeclAsWritten = this;
if (FunctionDecl *Pattern = getTemplateInstantiationPattern())
DeclAsWritten = Pattern;
return !(DeclAsWritten->isDeleted() ||
DeclAsWritten->getCanonicalDecl()->isDefaulted());
}
/// Whether falling off this function implicitly returns null/zero.
/// If a more specific implicit return value is required, front-ends
/// should synthesize the appropriate return statements.
@ -2177,6 +2233,10 @@ class FunctionDecl : public DeclaratorDecl,
bool usesSEHTry() const { return FunctionDeclBits.UsesSEHTry; }
void setUsesSEHTry(bool UST) { FunctionDeclBits.UsesSEHTry = UST; }
/// Indicates the function uses Floating Point constrained intrinsics
bool usesFPIntrin() const { return FunctionDeclBits.UsesFPIntrin; }
void setUsesFPIntrin(bool Val) { FunctionDeclBits.UsesFPIntrin = Val; }
/// Whether this function has been deleted.
///
/// A function that is "deleted" (via the C++0x "= delete" syntax)
@ -2249,6 +2309,9 @@ class FunctionDecl : public DeclaratorDecl,
/// true through IsAligned.
bool isReplaceableGlobalAllocationFunction(bool *IsAligned = nullptr) const;
/// Determine if this function provides an inline implementation of a builtin.
bool isInlineBuiltinDeclaration() const;
/// Determine whether this is a destroying operator delete.
bool isDestroyingOperatorDelete() const;
@ -2312,6 +2375,17 @@ class FunctionDecl : public DeclaratorDecl,
/// the target functionality.
bool isTargetMultiVersion() const;
/// \brief Get the associated-constraints of this function declaration.
/// Currently, this will either be a vector of size 1 containing the
/// trailing-requires-clause or an empty vector.
///
/// Use this instead of getTrailingRequiresClause for concepts APIs that
/// accept an ArrayRef of constraint expressions.
void getAssociatedConstraints(SmallVectorImpl<const Expr *> &AC) const {
if (auto *TRC = getTrailingRequiresClause())
AC.push_back(TRC);
}
void setPreviousDeclaration(FunctionDecl * PrevDecl);
FunctionDecl *getCanonicalDecl() override;
@ -2362,6 +2436,12 @@ class FunctionDecl : public DeclaratorDecl,
/// parameters have default arguments (in C++).
unsigned getMinRequiredArguments() const;
/// Find the source location information for how the type of this function
/// was written. May be absent (for example if the function was declared via
/// a typedef) and may contain a different type from that of the function
/// (for example if the function type was adjusted by an attribute).
FunctionTypeLoc getFunctionTypeLoc() const;
QualType getReturnType() const {
return getType()->castAs<FunctionType>()->getReturnType();
}
@ -2371,6 +2451,12 @@ class FunctionDecl : public DeclaratorDecl,
/// limited representation in the AST.
SourceRange getReturnTypeSourceRange() const;
/// Attempt to compute an informative source range covering the
/// function parameters, including the ellipsis of a variadic function.
/// The source range excludes the parentheses, and is invalid if there are
/// no parameters and no ellipsis.
SourceRange getParametersSourceRange() const;
/// Get the declared return type, which may differ from the actual return
/// type if the return type is deduced.
QualType getDeclaredReturnType() const {

View File

@ -1501,10 +1501,9 @@ class DeclContext {
/// constructor or a destructor.
uint64_t IsTrivialForCall : 1;
/// Used by CXXMethodDecl
uint64_t IsDefaulted : 1;
/// Used by CXXMethodDecl
uint64_t IsExplicitlyDefaulted : 1;
uint64_t HasDefaultedFunctionInfo : 1;
uint64_t HasImplicitReturnZero : 1;
uint64_t IsLateTemplateParsed : 1;
@ -1534,10 +1533,13 @@ class DeclContext {
/// Store the ODRHash after first calculation.
uint64_t HasODRHash : 1;
/// Indicates if the function uses Floating Point Constrained Intrinsics
uint64_t UsesFPIntrin : 1;
};
/// Number of non-inherited bits in FunctionDeclBitfields.
enum { NumFunctionDeclBits = 25 };
enum { NumFunctionDeclBits = 27 };
/// Stores the bits used by CXXConstructorDecl. If modified
/// NumCXXConstructorDeclBits and the accessor
@ -1554,7 +1556,7 @@ class DeclContext {
/// 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 : 23;
uint64_t NumCtorInitializers : 21;
uint64_t IsInheritingConstructor : 1;
/// Whether this constructor has a trail-allocated explicit specifier.
@ -1590,6 +1592,9 @@ class DeclContext {
/// True if this method is the getter or setter for an explicit property.
uint64_t IsPropertyAccessor : 1;
/// True if this method is a synthesized property accessor stub.
uint64_t IsSynthesizedAccessorStub : 1;
/// Method has a definition.
uint64_t IsDefined : 1;

View File

@ -17,7 +17,6 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTUnresolvedSet.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
@ -42,7 +41,6 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
@ -1048,7 +1046,8 @@ class CXXRecordDecl : public RecordDecl {
/// Get all conversion functions visible in current class,
/// including conversion function templates.
llvm::iterator_range<conversion_iterator> getVisibleConversionFunctions();
llvm::iterator_range<conversion_iterator>
getVisibleConversionFunctions() const;
/// Determine whether this class is an aggregate (C++ [dcl.init.aggr]),
/// which is a class with no user-declared constructors, no private
@ -1737,10 +1736,10 @@ class CXXRecordDecl : public RecordDecl {
}
/// Returns the inheritance model used for this record.
MSInheritanceAttr::Spelling getMSInheritanceModel() const;
MSInheritanceModel getMSInheritanceModel() const;
/// Calculate what the inheritance model would be for this class.
MSInheritanceAttr::Spelling calculateInheritanceModel() const;
MSInheritanceModel calculateInheritanceModel() const;
/// In the Microsoft C++ ABI, use zero for the field offset of a null data
/// member pointer if we can guarantee that zero is not a valid field offset,
@ -1748,15 +1747,11 @@ class CXXRecordDecl : public RecordDecl {
/// vfptr at offset zero, so we can use zero for null. If there are multiple
/// fields, we can use zero even if it is a valid field offset because
/// null-ness testing will check the other fields.
bool nullFieldOffsetIsZero() const {
return !MSInheritanceAttr::hasOnlyOneField(/*IsMemberFunction=*/false,
getMSInheritanceModel()) ||
(hasDefinition() && isPolymorphic());
}
bool nullFieldOffsetIsZero() const;
/// Controls when vtordisps will be emitted if this record is used as a
/// virtual base.
MSVtorDispAttr::Mode getMSVtorDispMode() const;
MSVtorDispMode getMSVtorDispMode() const;
/// Determine whether this lambda expression was known to be dependent
/// at the time it was created, even if its context does not appear to be
@ -1788,7 +1783,7 @@ class CXXRecordDecl : public RecordDecl {
};
/// Store information needed for an explicit specifier.
/// used by CXXDeductionGuideDecl, CXXConstructorDecl and CXXConversionDecl.
/// Used by CXXDeductionGuideDecl, CXXConstructorDecl and CXXConversionDecl.
class ExplicitSpecifier {
llvm::PointerIntPair<Expr *, 2, ExplicitSpecKind> ExplicitSpec{
nullptr, ExplicitSpecKind::ResolvedFalse};
@ -1801,20 +1796,22 @@ class ExplicitSpecifier {
const Expr *getExpr() const { return ExplicitSpec.getPointer(); }
Expr *getExpr() { return ExplicitSpec.getPointer(); }
/// Return true if the ExplicitSpecifier isn't defaulted.
/// Determine if the declaration had an explicit specifier of any kind.
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.
/// 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.
/// Determine whether this specifier is known to correspond to an explicit
/// declaration. Returns false if the specifier is absent or has an
/// expression that is value-dependent or evaluates to false.
bool isExplicit() const {
return ExplicitSpec.getInt() == ExplicitSpecKind::ResolvedTrue;
}
/// Return true if the ExplicitSpecifier isn't valid.
/// Determine if the explicit specifier is invalid.
/// This state occurs after a substitution failures.
bool isInvalid() const {
return ExplicitSpec.getInt() == ExplicitSpecKind::Unresolved &&
@ -1822,9 +1819,7 @@ class ExplicitSpecifier {
}
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.
// Retrieve the explicit specifier in the given declaration, if any.
static ExplicitSpecifier getFromDecl(FunctionDecl *Function);
static const ExplicitSpecifier getFromDecl(const FunctionDecl *Function) {
return getFromDecl(const_cast<FunctionDecl *>(Function));
@ -1910,9 +1905,10 @@ class CXXMethodDecl : public FunctionDecl {
SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo, StorageClass SC,
bool isInline, ConstexprSpecKind ConstexprKind,
SourceLocation EndLocation)
SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr)
: FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, isInline,
ConstexprKind) {
ConstexprKind, TrailingRequiresClause) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
}
@ -1923,7 +1919,8 @@ class CXXMethodDecl : public FunctionDecl {
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, StorageClass SC,
bool isInline, ConstexprSpecKind ConstexprKind,
SourceLocation EndLocation);
SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr);
static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@ -2001,16 +1998,6 @@ class CXXMethodDecl : public FunctionDecl {
return const_cast<CXXMethodDecl*>(this)->getMostRecentDecl();
}
/// True if this method is user-declared and was not
/// deleted or defaulted on its first declaration.
bool isUserProvided() const {
auto *DeclAsWritten = this;
if (auto *Pattern = getTemplateInstantiationPattern())
DeclAsWritten = cast<CXXMethodDecl>(Pattern);
return !(DeclAsWritten->isDeleted() ||
DeclAsWritten->getCanonicalDecl()->isDefaulted());
}
void addOverriddenMethod(const CXXMethodDecl *MD);
using method_iterator = const CXXMethodDecl *const *;
@ -2138,8 +2125,8 @@ class CXXCtorInitializer final {
/// Either the base class name/delegating constructor type (stored as
/// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field
/// (IndirectFieldDecl*) being initialized.
llvm::PointerUnion3<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *>
Initializee;
llvm::PointerUnion<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *>
Initializee;
/// The source location for the field name or, for a base initializer
/// pack expansion, the location of the ellipsis.
@ -2378,7 +2365,8 @@ class CXXConstructorDecl final
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool isInline,
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
InheritedConstructor Inherited);
InheritedConstructor Inherited,
Expr *TrailingRequiresClause);
void anchor() override;
@ -2431,7 +2419,8 @@ class CXXConstructorDecl final
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared,
ConstexprSpecKind ConstexprKind,
InheritedConstructor Inherited = InheritedConstructor());
InheritedConstructor Inherited = InheritedConstructor(),
Expr *TrailingRequiresClause = nullptr);
ExplicitSpecifier getExplicitSpecifier() {
return getCanonicalDecl()->getExplicitSpecifierInternal();
@ -2638,9 +2627,11 @@ class CXXDestructorDecl : public CXXMethodDecl {
CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, bool isInline,
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind)
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause = nullptr)
: CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, ConstexprKind, SourceLocation()) {
SC_None, isInline, ConstexprKind, SourceLocation(),
TrailingRequiresClause) {
setImplicit(isImplicitlyDeclared);
}
@ -2652,7 +2643,8 @@ class CXXDestructorDecl : public CXXMethodDecl {
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isImplicitlyDeclared,
ConstexprSpecKind ConstexprKind);
ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause = nullptr);
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);
@ -2691,9 +2683,11 @@ class CXXConversionDecl : public CXXMethodDecl {
CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, bool isInline, ExplicitSpecifier ES,
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation)
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr)
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, ConstexprKind, EndLocation),
SC_None, isInline, ConstexprKind, EndLocation,
TrailingRequiresClause),
ExplicitSpec(ES) {}
void anchor() override;
@ -2709,7 +2703,7 @@ class CXXConversionDecl : public CXXMethodDecl {
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind,
SourceLocation EndLocation);
SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr);
static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
ExplicitSpecifier getExplicitSpecifier() {
@ -2758,15 +2752,8 @@ class LinkageSpecDecl : public Decl, public DeclContext {
/// Represents the language in a linkage specification.
///
/// The values are part of the serialization ABI for
/// ASTs and cannot be changed without altering that ABI. To help
/// ensure a stable ABI for this, we choose the DW_LANG_ encodings
/// from the dwarf standard.
enum LanguageIDs {
lang_c = llvm::dwarf::DW_LANG_C,
lang_cxx = llvm::dwarf::DW_LANG_C_plus_plus,
lang_cxx_11 = llvm::dwarf::DW_LANG_C_plus_plus_11,
lang_cxx_14 = llvm::dwarf::DW_LANG_C_plus_plus_14
};
/// ASTs and cannot be changed without altering that ABI.
enum LanguageIDs { lang_c = 1, lang_cxx = 2 };
private:
/// The source location for the extern keyword.
@ -3052,6 +3039,82 @@ class NamespaceAliasDecl : public NamedDecl,
static bool classofKind(Kind K) { return K == NamespaceAlias; }
};
/// Implicit declaration of a temporary that was materialized by
/// a MaterializeTemporaryExpr and lifetime-extended by a declaration
class LifetimeExtendedTemporaryDecl final
: public Decl,
public Mergeable<LifetimeExtendedTemporaryDecl> {
friend class MaterializeTemporaryExpr;
friend class ASTDeclReader;
Stmt *ExprWithTemporary = nullptr;
/// The declaration which lifetime-extended this reference, if any.
/// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
ValueDecl *ExtendingDecl = nullptr;
unsigned ManglingNumber;
mutable APValue *Value = nullptr;
virtual void anchor();
LifetimeExtendedTemporaryDecl(Expr *Temp, ValueDecl *EDecl, unsigned Mangling)
: Decl(Decl::LifetimeExtendedTemporary, EDecl->getDeclContext(),
EDecl->getLocation()),
ExprWithTemporary(Temp), ExtendingDecl(EDecl),
ManglingNumber(Mangling) {}
LifetimeExtendedTemporaryDecl(EmptyShell)
: Decl(Decl::LifetimeExtendedTemporary, EmptyShell{}) {}
public:
static LifetimeExtendedTemporaryDecl *Create(Expr *Temp, ValueDecl *EDec,
unsigned Mangling) {
return new (EDec->getASTContext(), EDec->getDeclContext())
LifetimeExtendedTemporaryDecl(Temp, EDec, Mangling);
}
static LifetimeExtendedTemporaryDecl *CreateDeserialized(ASTContext &C,
unsigned ID) {
return new (C, ID) LifetimeExtendedTemporaryDecl(EmptyShell{});
}
ValueDecl *getExtendingDecl() { return ExtendingDecl; }
const ValueDecl *getExtendingDecl() const { return ExtendingDecl; }
/// Retrieve the storage duration for the materialized temporary.
StorageDuration getStorageDuration() const;
/// Retrieve the expression to which the temporary materialization conversion
/// was applied. This isn't necessarily the initializer of the temporary due
/// to the C++98 delayed materialization rules, but
/// skipRValueSubobjectAdjustments can be used to find said initializer within
/// the subexpression.
Expr *getTemporaryExpr() { return cast<Expr>(ExprWithTemporary); }
const Expr *getTemporaryExpr() const { return cast<Expr>(ExprWithTemporary); }
unsigned getManglingNumber() const { return ManglingNumber; }
/// Get the storage for the constant value of a materialized temporary
/// of static storage duration.
APValue *getOrCreateValue(bool MayCreate) const;
APValue *getValue() const { return Value; }
// Iterators
Stmt::child_range childrenExpr() {
return Stmt::child_range(&ExprWithTemporary, &ExprWithTemporary + 1);
}
Stmt::const_child_range childrenExpr() const {
return Stmt::const_child_range(&ExprWithTemporary, &ExprWithTemporary + 1);
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
return K == Decl::LifetimeExtendedTemporary;
}
};
/// Represents a shadow declaration introduced into a scope by a
/// (resolved) using declaration.
///

View File

@ -172,6 +172,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
DeclContext *contextDecl, bool isInstance = true,
bool isVariadic = false, bool isPropertyAccessor = false,
bool isSynthesizedAccessorStub = false,
bool isImplicitlyDeclared = false, bool isDefined = false,
ImplementationControl impControl = None,
bool HasRelatedResultType = false);
@ -232,6 +233,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
DeclContext *contextDecl, bool isInstance = true,
bool isVariadic = false, bool isPropertyAccessor = false,
bool isSynthesizedAccessorStub = false,
bool isImplicitlyDeclared = false, bool isDefined = false,
ImplementationControl impControl = None,
bool HasRelatedResultType = false);
@ -408,7 +410,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
/// \return the type for \c self and set \arg selfIsPseudoStrong and
/// \arg selfIsConsumed accordingly.
QualType getSelfType(ASTContext &Context, const ObjCInterfaceDecl *OID,
bool &selfIsPseudoStrong, bool &selfIsConsumed);
bool &selfIsPseudoStrong, bool &selfIsConsumed) const;
ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
@ -436,6 +438,14 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
ObjCMethodDeclBits.IsPropertyAccessor = isAccessor;
}
bool isSynthesizedAccessorStub() const {
return ObjCMethodDeclBits.IsSynthesizedAccessorStub;
}
void setSynthesizedAccessorStub(bool isSynthesizedAccessorStub) {
ObjCMethodDeclBits.IsSynthesizedAccessorStub = isSynthesizedAccessorStub;
}
bool isDefined() const { return ObjCMethodDeclBits.IsDefined; }
void setDefined(bool isDefined) { ObjCMethodDeclBits.IsDefined = isDefined; }
@ -466,6 +476,9 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
ObjCMethodDeclBits.HasSkippedBody = Skipped;
}
/// True if the method is tagged as objc_direct
bool isDirectMethod() const;
/// Returns the property associated with this method's selector.
///
/// Note that even if this particular method is not marked as a property
@ -747,13 +760,14 @@ class ObjCPropertyDecl : public NamedDecl {
/// property attribute rather than a type qualifier.
OBJC_PR_nullability = 0x1000,
OBJC_PR_null_resettable = 0x2000,
OBJC_PR_class = 0x4000
OBJC_PR_class = 0x4000,
OBJC_PR_direct = 0x8000
// Adding a property should change NumPropertyAttrsBits
};
enum {
/// Number of bits fitting all the property attributes.
NumPropertyAttrsBits = 15
NumPropertyAttrsBits = 16
};
enum SetterKind { Assign, Retain, Copy, Weak };
@ -876,6 +890,7 @@ class ObjCPropertyDecl : public NamedDecl {
bool isInstanceProperty() const { return !isClassProperty(); }
bool isClassProperty() const { return PropertyAttributes & OBJC_PR_class; }
bool isDirectProperty() const { return PropertyAttributes & OBJC_PR_direct; }
ObjCPropertyQueryKind getQueryKind() const {
return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class :
@ -2779,6 +2794,11 @@ class ObjCPropertyImplDecl : public Decl {
/// Null for \@dynamic. Required for \@synthesize.
ObjCIvarDecl *PropertyIvarDecl;
/// The getter's definition, which has an empty body if synthesized.
ObjCMethodDecl *GetterMethodDecl = nullptr;
/// The getter's definition, which has an empty body if synthesized.
ObjCMethodDecl *SetterMethodDecl = nullptr;
/// Null for \@dynamic. Non-null if property must be copy-constructed in
/// getter.
Expr *GetterCXXConstructor = nullptr;
@ -2845,6 +2865,12 @@ class ObjCPropertyImplDecl : public Decl {
return IvarLoc.isValid() && IvarLoc != getLocation();
}
ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
void setGetterMethodDecl(ObjCMethodDecl *MD) { GetterMethodDecl = MD; }
ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
void setSetterMethodDecl(ObjCMethodDecl *MD) { SetterMethodDecl = MD; }
Expr *getGetterCXXConstructor() const {
return GetterCXXConstructor;
}

View File

@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
#define LLVM_CLANG_AST_DECLTEMPLATE_H
#include "clang/AST/ASTConcept.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
@ -51,14 +52,15 @@ class NonTypeTemplateParmDecl;
class TemplateDecl;
class TemplateTemplateParmDecl;
class TemplateTypeParmDecl;
class ConceptDecl;
class UnresolvedSetImpl;
class VarTemplateDecl;
class VarTemplatePartialSpecializationDecl;
/// Stores a template parameter of any kind.
using TemplateParameter =
llvm::PointerUnion3<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *,
TemplateTemplateParmDecl *>;
llvm::PointerUnion<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *,
TemplateTemplateParmDecl *>;
NamedDecl *getAsNamedDecl(TemplateParameter P);
@ -81,20 +83,24 @@ class TemplateParameterList final
/// pack.
unsigned ContainsUnexpandedParameterPack : 1;
/// Whether this template parameter list has an associated requires-clause
/// Whether this template parameter list has a requires clause.
unsigned HasRequiresClause : 1;
/// Whether any of the template parameters has constrained-parameter
/// constraint-expression.
unsigned HasConstrainedParameters : 1;
protected:
TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc,
Expr *RequiresClause);
TemplateParameterList(const ASTContext& C, SourceLocation TemplateLoc,
SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
SourceLocation RAngleLoc, Expr *RequiresClause);
size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
return NumParams;
}
size_t numTrailingObjects(OverloadToken<Expr *>) const {
return HasRequiresClause;
return HasRequiresClause ? 1 : 0;
}
public:
@ -158,14 +164,22 @@ class TemplateParameterList final
return ContainsUnexpandedParameterPack;
}
/// Determine whether this template parameter list contains a parameter pack.
bool hasParameterPack() const {
for (const NamedDecl *P : asArray())
if (P->isParameterPack())
return true;
return false;
}
/// The constraint-expression of the associated requires-clause.
Expr *getRequiresClause() {
return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr;
return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
}
/// The constraint-expression of the associated requires-clause.
const Expr *getRequiresClause() const {
return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr;
return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
}
/// \brief All associated constraints derived from this template parameter
@ -208,15 +222,16 @@ class FixedSizeTemplateParameterListStorage
>::type storage;
public:
FixedSizeTemplateParameterListStorage(SourceLocation TemplateLoc,
FixedSizeTemplateParameterListStorage(const ASTContext &C,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
ArrayRef<NamedDecl *> Params,
SourceLocation RAngleLoc,
Expr *RequiresClause)
: FixedSizeStorageOwner(
(assert(N == Params.size()),
assert(HasRequiresClause == static_cast<bool>(RequiresClause)),
new (static_cast<void *>(&storage)) TemplateParameterList(
assert(HasRequiresClause == (RequiresClause != nullptr)),
new (static_cast<void *>(&storage)) TemplateParameterList(C,
TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
};
@ -309,7 +324,7 @@ class DefaultArgStorage {
static_assert(sizeof(Chain) == sizeof(void *) * 2,
"non-pointer argument type?");
llvm::PointerUnion3<ArgType, ParmDecl*, Chain*> ValueOrInherited;
llvm::PointerUnion<ArgType, ParmDecl*, Chain*> ValueOrInherited;
static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
@ -793,9 +808,10 @@ class RedeclarableTemplateDecl : public TemplateDecl,
void loadLazySpecializationsImpl() const;
template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
template <class EntryType, typename ...ProfileArguments>
typename SpecEntryTraits<EntryType>::DeclType*
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
ArrayRef<TemplateArgument> Args, void *&InsertPos);
void *&InsertPos, ProfileArguments &&...ProfileArgs);
template <class Derived, class EntryType>
void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
@ -1147,9 +1163,12 @@ class TemplateParmPosition {
/// \code
/// template<typename T> class vector;
/// \endcode
class TemplateTypeParmDecl : public TypeDecl {
class TemplateTypeParmDecl final : public TypeDecl,
private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
/// Sema creates these on the stack during auto type deduction.
friend class Sema;
friend TrailingObjects;
friend class ASTDeclReader;
/// Whether this template type parameter was declaration with
/// the 'typename' keyword.
@ -1157,6 +1176,22 @@ class TemplateTypeParmDecl : public TypeDecl {
/// If false, it was declared with the 'class' keyword.
bool Typename : 1;
/// Whether this template type parameter has a type-constraint construct.
bool HasTypeConstraint : 1;
/// Whether the type constraint has been initialized. This can be false if the
/// constraint was not initialized yet or if there was an error forming the
/// type constriant.
bool TypeConstraintInitialized : 1;
/// Whether this non-type template parameter is an "expanded"
/// parameter pack, meaning that its type is a pack expansion and we
/// already know the set of types that expansion expands to.
bool ExpandedParameterPack : 1;
/// The number of type parameters in an expanded parameter pack.
unsigned NumExpanded = 0;
/// The default template argument, if any.
using DefArgStorage =
DefaultArgStorage<TemplateTypeParmDecl, TypeSourceInfo *>;
@ -1164,8 +1199,12 @@ class TemplateTypeParmDecl : public TypeDecl {
TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
bool Typename)
: TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename) {}
bool Typename, bool HasTypeConstraint,
Optional<unsigned> NumExpanded)
: TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
ExpandedParameterPack(NumExpanded),
NumExpanded(NumExpanded ? *NumExpanded : 0) {}
public:
static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
@ -1173,15 +1212,24 @@ class TemplateTypeParmDecl : public TypeDecl {
SourceLocation NameLoc,
unsigned D, unsigned P,
IdentifierInfo *Id, bool Typename,
bool ParameterPack);
bool ParameterPack,
bool HasTypeConstraint = false,
Optional<unsigned> NumExpanded = None);
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
unsigned ID);
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
unsigned ID,
bool HasTypeConstraint);
/// Whether this template type parameter was declared with
/// the 'typename' keyword.
///
/// If not, it was declared with the 'class' keyword.
bool wasDeclaredWithTypename() const { return Typename; }
/// If not, it was either declared with the 'class' keyword or with a
/// type-constraint (see hasTypeConstraint()).
bool wasDeclaredWithTypename() const {
return Typename && !HasTypeConstraint;
}
const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
@ -1238,6 +1286,78 @@ class TemplateTypeParmDecl : public TypeDecl {
/// Returns whether this is a parameter pack.
bool isParameterPack() const;
/// Whether this parameter pack is a pack expansion.
///
/// A template type template parameter pack can be a pack expansion if its
/// type-constraint contains an unexpanded parameter pack.
bool isPackExpansion() const {
if (!isParameterPack())
return false;
if (const TypeConstraint *TC = getTypeConstraint())
if (TC->hasExplicitTemplateArgs())
for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
if (ArgLoc.getArgument().containsUnexpandedParameterPack())
return true;
return false;
}
/// Whether this parameter is a template type parameter pack that has a known
/// list of different type-constraints at different positions.
///
/// A parameter pack is an expanded parameter pack when the original
/// parameter pack's type-constraint was itself a pack expansion, and that
/// expansion has already been expanded. For example, given:
///
/// \code
/// template<typename ...Types>
/// struct X {
/// template<convertible_to<Types> ...Convertibles>
/// struct Y { /* ... */ };
/// };
/// \endcode
///
/// The parameter pack \c Convertibles has (convertible_to<Types> && ...) as
/// its type-constraint. When \c Types is supplied with template arguments by
/// instantiating \c X, the instantiation of \c Convertibles becomes an
/// expanded parameter pack. For example, instantiating
/// \c X<int, unsigned int> results in \c Convertibles being an expanded
/// parameter pack of size 2 (use getNumExpansionTypes() to get this number).
bool isExpandedParameterPack() const { return ExpandedParameterPack; }
/// Retrieves the number of parameters in an expanded parameter pack.
unsigned getNumExpansionParameters() const {
assert(ExpandedParameterPack && "Not an expansion parameter pack");
return NumExpanded;
}
/// Returns the type constraint associated with this template parameter (if
/// any).
const TypeConstraint *getTypeConstraint() const {
return TypeConstraintInitialized ? getTrailingObjects<TypeConstraint>() :
nullptr;
}
void setTypeConstraint(NestedNameSpecifierLoc NNS,
DeclarationNameInfo NameInfo, NamedDecl *FoundDecl,
ConceptDecl *CD,
const ASTTemplateArgumentListInfo *ArgsAsWritten,
Expr *ImmediatelyDeclaredConstraint);
/// Determine whether this template parameter has a type-constraint.
bool hasTypeConstraint() const {
return HasTypeConstraint;
}
/// \brief Get the associated-constraints of this template parameter.
/// This will either be the immediately-introduced constraint or empty.
///
/// Use this instead of getConstraintExpression for concepts APIs that
/// accept an ArrayRef of constraint expressions.
void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
if (HasTypeConstraint)
AC.push_back(getTypeConstraint()->getImmediatelyDeclaredConstraint());
}
SourceRange getSourceRange() const override LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
@ -1423,6 +1543,33 @@ class NonTypeTemplateParmDecl final
return TypesAndInfos[I].second;
}
/// Return the type-constraint in the placeholder type of this non-type
/// template parameter (if any).
TypeConstraint *getPlaceholderTypeConstraint() const {
// TODO: Concepts: Implement once we have actual placeholders with type
// constraints.
return nullptr;
}
/// Determine whether this non-type template parameter's type has a
/// placeholder with a type-constraint.
bool hasPlaceholderTypeConstraint() const {
// TODO: Concepts: Implement once we have actual placeholders with type
// constraints.
return false;
}
/// \brief Get the associated-constraints of this template parameter.
/// This will either be a vector of size 1 containing the immediately-declared
/// constraint introduced by the placeholder type, or an empty vector.
///
/// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
/// concepts APIs that accept an ArrayRef of constraint expressions.
void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
if (TypeConstraint *TC = getPlaceholderTypeConstraint())
AC.push_back(TC->getImmediatelyDeclaredConstraint());
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
@ -1557,8 +1704,8 @@ class TemplateTemplateParmDecl final
/// Retrieve the default argument, if any.
const TemplateArgumentLoc &getDefaultArgument() const {
static const TemplateArgumentLoc None;
return DefaultArgument.isSet() ? *DefaultArgument.get() : None;
static const TemplateArgumentLoc NoneLoc;
return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
}
/// Retrieve the location of the default argument, if any.
@ -2056,7 +2203,14 @@ class ClassTemplatePartialSpecializationDecl
->getInjectedSpecializationType();
}
// FIXME: Add Profile support!
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, getTemplateArgs().asArray(), getTemplateParameters(),
getASTContext());
}
static void
Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
TemplateParameterList *TPL, ASTContext &Context);
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@ -2180,7 +2334,8 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
/// Return the partial specialization with the provided arguments if it
/// exists, otherwise return the insertion point.
ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
findPartialSpecialization(ArrayRef<TemplateArgument> Args,
TemplateParameterList *TPL, void *&InsertPos);
/// Insert the specified partial specialization knowing that it is not
/// already in. InsertPos must be obtained from findPartialSpecialization.
@ -2880,6 +3035,15 @@ class VarTemplatePartialSpecializationDecl
return First->InstantiatedFromMember.setInt(true);
}
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, getTemplateArgs().asArray(), getTemplateParameters(),
getASTContext());
}
static void
Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
TemplateParameterList *TPL, ASTContext &Context);
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
@ -2998,7 +3162,8 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
/// Return the partial specialization with the provided arguments if it
/// exists, otherwise return the insertion point.
VarTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
findPartialSpecialization(ArrayRef<TemplateArgument> Args,
TemplateParameterList *TPL, void *&InsertPos);
/// Insert the specified partial specialization knowing that it is not
/// already in. InsertPos must be obtained from findPartialSpecialization.
@ -3067,6 +3232,10 @@ class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
ConstraintExpr->getEndLoc());
}
bool isTypeConcept() const {
return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Concept; }

View File

@ -528,7 +528,7 @@ class DeclarationName {
static int compare(DeclarationName LHS, DeclarationName RHS);
void print(raw_ostream &OS, const PrintingPolicy &Policy);
void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
void dump() const;
};
@ -792,7 +792,7 @@ struct DeclarationNameInfo {
std::string getAsString() const;
/// printName - Print the human-readable name to a stream.
void printName(raw_ostream &OS) const;
void printName(raw_ostream &OS, PrintingPolicy Policy) const;
/// getBeginLoc - Retrieve the location of the first token.
SourceLocation getBeginLoc() const { return NameLoc; }
@ -829,11 +829,7 @@ inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
return PD;
}
inline raw_ostream &operator<<(raw_ostream &OS,
DeclarationNameInfo DNInfo) {
DNInfo.printName(OS);
return OS;
}
raw_ostream &operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo);
} // namespace clang

View File

@ -494,7 +494,13 @@ class Expr : public ValueStmt {
/// that is known to return 0 or 1. This happens for _Bool/bool expressions
/// but also int expressions which are produced by things like comparisons in
/// C.
bool isKnownToHaveBooleanValue() const;
///
/// \param Semantic If true, only return true for expressions that are known
/// to be semantically boolean, which might not be true even for expressions
/// that are known to evaluate to 0/1. For instance, reading an unsigned
/// bit-field with width '1' will evaluate to 0/1, but doesn't necessarily
/// semantically correspond to a bool.
bool isKnownToHaveBooleanValue(bool Semantic = true) const;
/// isIntegerConstantExpr - Return true if this expression is a valid integer
/// constant expression, and, if so, return its value in Result. If not a
@ -756,6 +762,15 @@ class Expr : public ValueStmt {
/// member expression.
static QualType findBoundMemberType(const Expr *expr);
/// Skip past any invisble AST nodes which might surround this
/// statement, such as ExprWithCleanups or ImplicitCastExpr nodes,
/// but also injected CXXMemberExpr and CXXConstructExpr which represent
/// implicit conversions.
Expr *IgnoreUnlessSpelledInSource();
const Expr *IgnoreUnlessSpelledInSource() const {
return const_cast<Expr *>(this)->IgnoreUnlessSpelledInSource();
}
/// Skip past any implicit casts which might surround this expression until
/// reaching a fixed point. Skips:
/// * ImplicitCastExpr
@ -786,6 +801,16 @@ class Expr : public ValueStmt {
return const_cast<Expr *>(this)->IgnoreImplicit();
}
/// Skip past any implicit AST nodes which might surround this expression
/// until reaching a fixed point. Same as IgnoreImplicit, except that it
/// also skips over implicit calls to constructors and conversion functions.
///
/// FIXME: Should IgnoreImplicit do this?
Expr *IgnoreImplicitAsWritten() LLVM_READONLY;
const Expr *IgnoreImplicitAsWritten() const {
return const_cast<Expr *>(this)->IgnoreImplicitAsWritten();
}
/// Skip past any parentheses which might surround this expression until
/// reaching a fixed point. Skips:
/// * ParenExpr
@ -3711,22 +3736,25 @@ class ConditionalOperator : public AbstractConditionalOperator {
friend class ASTStmtReader;
public:
ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs,
SourceLocation CLoc, Expr *rhs,
QualType t, ExprValueKind VK, ExprObjectKind OK)
: AbstractConditionalOperator(ConditionalOperatorClass, t, VK, OK,
// FIXME: the type of the conditional operator doesn't
// depend on the type of the conditional, but the standard
// seems to imply that it could. File a bug!
(lhs->isTypeDependent() || rhs->isTypeDependent()),
(cond->isValueDependent() || lhs->isValueDependent() ||
rhs->isValueDependent()),
(cond->isInstantiationDependent() ||
lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(cond->containsUnexpandedParameterPack() ||
lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack()),
QLoc, CLoc) {
SourceLocation CLoc, Expr *rhs, QualType t,
ExprValueKind VK, ExprObjectKind OK)
: AbstractConditionalOperator(
ConditionalOperatorClass, t, VK, OK,
// The type of the conditional operator depends on the type
// of the conditional to support the GCC vector conditional
// extension. Additionally, [temp.dep.expr] does specify state that
// this should be dependent on ALL sub expressions.
(cond->isTypeDependent() || lhs->isTypeDependent() ||
rhs->isTypeDependent()),
(cond->isValueDependent() || lhs->isValueDependent() ||
rhs->isValueDependent()),
(cond->isInstantiationDependent() ||
lhs->isInstantiationDependent() ||
rhs->isInstantiationDependent()),
(cond->containsUnexpandedParameterPack() ||
lhs->containsUnexpandedParameterPack() ||
rhs->containsUnexpandedParameterPack()),
QLoc, CLoc) {
SubExprs[COND] = cond;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
@ -5594,6 +5622,20 @@ class BlockExpr : public Expr {
}
};
/// Copy initialization expr of a __block variable and a boolean flag that
/// indicates whether the expression can throw.
struct BlockVarCopyInit {
BlockVarCopyInit() = default;
BlockVarCopyInit(Expr *CopyExpr, bool CanThrow)
: ExprAndFlag(CopyExpr, CanThrow) {}
void setExprAndFlag(Expr *CopyExpr, bool CanThrow) {
ExprAndFlag.setPointerAndInt(CopyExpr, CanThrow);
}
Expr *getCopyExpr() const { return ExprAndFlag.getPointer(); }
bool canThrow() const { return ExprAndFlag.getInt(); }
llvm::PointerIntPair<Expr *, 1, bool> ExprAndFlag;
};
/// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2]
/// This AST node provides support for reinterpreting a type to another
/// type of the same size.

View File

@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_EXPRCXX_H
#define LLVM_CLANG_AST_EXPRCXX_H
#include "clang/AST/ASTConcept.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
@ -4421,70 +4422,66 @@ class MaterializeTemporaryExpr : public Expr {
friend class ASTStmtReader;
friend class ASTStmtWriter;
struct ExtraState {
/// The temporary-generating expression whose value will be
/// materialized.
Stmt *Temporary;
/// The declaration which lifetime-extended this reference, if any.
/// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
const ValueDecl *ExtendingDecl;
unsigned ManglingNumber;
};
llvm::PointerUnion<Stmt *, ExtraState *> State;
llvm::PointerUnion<Stmt *, LifetimeExtendedTemporaryDecl *> State;
public:
MaterializeTemporaryExpr(QualType T, Expr *Temporary,
bool BoundToLvalueReference)
: Expr(MaterializeTemporaryExprClass, T,
BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
Temporary->isTypeDependent(), Temporary->isValueDependent(),
Temporary->isInstantiationDependent(),
Temporary->containsUnexpandedParameterPack()),
State(Temporary) {}
bool BoundToLvalueReference,
LifetimeExtendedTemporaryDecl *MTD = nullptr);
MaterializeTemporaryExpr(EmptyShell Empty)
: Expr(MaterializeTemporaryExprClass, Empty) {}
Stmt *getTemporary() const {
return State.is<Stmt *>() ? State.get<Stmt *>()
: State.get<ExtraState *>()->Temporary;
}
/// Retrieve the temporary-generating subexpression whose value will
/// be materialized into a glvalue.
Expr *GetTemporaryExpr() const { return static_cast<Expr *>(getTemporary()); }
Expr *getSubExpr() const {
return cast<Expr>(
State.is<Stmt *>()
? State.get<Stmt *>()
: State.get<LifetimeExtendedTemporaryDecl *>()->getTemporaryExpr());
}
/// Retrieve the storage duration for the materialized temporary.
StorageDuration getStorageDuration() const {
const ValueDecl *ExtendingDecl = getExtendingDecl();
if (!ExtendingDecl)
return SD_FullExpression;
// FIXME: This is not necessarily correct for a temporary materialized
// within a default initializer.
if (isa<FieldDecl>(ExtendingDecl))
return SD_Automatic;
// FIXME: This only works because storage class specifiers are not allowed
// on decomposition declarations.
if (isa<BindingDecl>(ExtendingDecl))
return ExtendingDecl->getDeclContext()->isFunctionOrMethod()
? SD_Automatic
: SD_Static;
return cast<VarDecl>(ExtendingDecl)->getStorageDuration();
return State.is<Stmt *>() ? SD_FullExpression
: State.get<LifetimeExtendedTemporaryDecl *>()
->getStorageDuration();
}
/// Get the storage for the constant value of a materialized temporary
/// of static storage duration.
APValue *getOrCreateValue(bool MayCreate) const {
assert(State.is<LifetimeExtendedTemporaryDecl *>() &&
"the temporary has not been lifetime extended");
return State.get<LifetimeExtendedTemporaryDecl *>()->getOrCreateValue(
MayCreate);
}
LifetimeExtendedTemporaryDecl *getLifetimeExtendedTemporaryDecl() {
return State.dyn_cast<LifetimeExtendedTemporaryDecl *>();
}
const LifetimeExtendedTemporaryDecl *
getLifetimeExtendedTemporaryDecl() const {
return State.dyn_cast<LifetimeExtendedTemporaryDecl *>();
}
/// Get the declaration which triggered the lifetime-extension of this
/// temporary, if any.
const ValueDecl *getExtendingDecl() const {
ValueDecl *getExtendingDecl() {
return State.is<Stmt *>() ? nullptr
: State.get<ExtraState *>()->ExtendingDecl;
: State.get<LifetimeExtendedTemporaryDecl *>()
->getExtendingDecl();
}
const ValueDecl *getExtendingDecl() const {
return const_cast<MaterializeTemporaryExpr *>(this)->getExtendingDecl();
}
void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber);
void setExtendingDecl(ValueDecl *ExtendedBy, unsigned ManglingNumber);
unsigned getManglingNumber() const {
return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber;
return State.is<Stmt *>() ? 0
: State.get<LifetimeExtendedTemporaryDecl *>()
->getManglingNumber();
}
/// Determine whether this materialized temporary is bound to an
@ -4494,11 +4491,11 @@ class MaterializeTemporaryExpr : public Expr {
}
SourceLocation getBeginLoc() const LLVM_READONLY {
return getTemporary()->getBeginLoc();
return getSubExpr()->getBeginLoc();
}
SourceLocation getEndLoc() const LLVM_READONLY {
return getTemporary()->getEndLoc();
return getSubExpr()->getEndLoc();
}
static bool classof(const Stmt *T) {
@ -4507,20 +4504,18 @@ class MaterializeTemporaryExpr : public Expr {
// Iterators
child_range children() {
if (State.is<Stmt *>())
return child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1);
auto ES = State.get<ExtraState *>();
return child_range(&ES->Temporary, &ES->Temporary + 1);
return State.is<Stmt *>()
? child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1)
: State.get<LifetimeExtendedTemporaryDecl *>()->childrenExpr();
}
const_child_range children() const {
if (State.is<Stmt *>())
return const_child_range(State.getAddrOfPtr1(),
State.getAddrOfPtr1() + 1);
auto ES = State.get<ExtraState *>();
return const_child_range(&ES->Temporary, &ES->Temporary + 1);
return State.is<Stmt *>()
? const_child_range(State.getAddrOfPtr1(),
State.getAddrOfPtr1() + 1)
: const_cast<const LifetimeExtendedTemporaryDecl *>(
State.get<LifetimeExtendedTemporaryDecl *>())
->childrenExpr();
}
};
@ -4846,107 +4841,81 @@ class BuiltinBitCastExpr final
///
/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
/// specialization of a concept results in a prvalue of type bool.
class ConceptSpecializationExpr final : public Expr,
class ConceptSpecializationExpr final : public Expr, public ConceptReference,
private llvm::TrailingObjects<ConceptSpecializationExpr,
TemplateArgument> {
friend class ASTStmtReader;
friend TrailingObjects;
public:
using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
// \brief The optional nested name specifier used when naming the concept.
NestedNameSpecifierLoc NestedNameSpec;
/// \brief The location of the template keyword, if specified when naming the
/// concept.
SourceLocation TemplateKWLoc;
/// \brief The location of the concept name in the expression.
SourceLocation ConceptNameLoc;
/// \brief The declaration found by name lookup when the expression was
/// created.
/// Can differ from NamedConcept when, for example, the concept was found
/// through a UsingShadowDecl.
NamedDecl *FoundDecl;
/// \brief The concept named, and whether or not the concept with the given
/// arguments was satisfied when the expression was created.
/// If any of the template arguments are dependent (this expr would then be
/// isValueDependent()), this bit is to be ignored.
llvm::PointerIntPair<ConceptDecl *, 1, bool> NamedConcept;
/// \brief The template argument list source info used to specialize the
/// concept.
const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
protected:
/// \brief The number of template arguments in the tail-allocated list of
/// converted template arguments.
unsigned NumTemplateArgs;
ConceptSpecializationExpr(ASTContext &C, NestedNameSpecifierLoc NNS,
/// \brief Information about the satisfaction of the named concept with the
/// given arguments. If this expression is value dependent, this is to be
/// ignored.
ASTConstraintSatisfaction *Satisfaction;
ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS,
SourceLocation TemplateKWLoc,
SourceLocation ConceptNameLoc, NamedDecl *FoundDecl,
ConceptDecl *NamedConcept,
DeclarationNameInfo ConceptNameInfo,
NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
const ASTTemplateArgumentListInfo *ArgsAsWritten,
ArrayRef<TemplateArgument> ConvertedArgs,
Optional<bool> IsSatisfied);
const ConstraintSatisfaction *Satisfaction);
ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
public:
static ConceptSpecializationExpr *
Create(ASTContext &C, NestedNameSpecifierLoc NNS,
SourceLocation TemplateKWLoc, SourceLocation ConceptNameLoc,
Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
const ASTTemplateArgumentListInfo *ArgsAsWritten,
ArrayRef<TemplateArgument> ConvertedArgs, Optional<bool> IsSatisfied);
ArrayRef<TemplateArgument> ConvertedArgs,
const ConstraintSatisfaction *Satisfaction);
static ConceptSpecializationExpr *
Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
return NestedNameSpec;
}
NamedDecl *getFoundDecl() const {
return FoundDecl;
}
ConceptDecl *getNamedConcept() const {
return NamedConcept.getPointer();
}
ArrayRef<TemplateArgument> getTemplateArguments() const {
return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
NumTemplateArgs);
}
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
return ArgsAsWritten;
}
/// \brief Set new template arguments for this concept specialization.
void setTemplateArguments(const ASTTemplateArgumentListInfo *ArgsAsWritten,
ArrayRef<TemplateArgument> Converted);
void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
/// \brief Whether or not the concept with the given arguments was satisfied
/// when the expression was created. This method assumes that the expression
/// is not dependent!
/// when the expression was created.
/// The expression must not be dependent.
bool isSatisfied() const {
assert(!isValueDependent()
&& "isSatisfied called on a dependent ConceptSpecializationExpr");
return NamedConcept.getInt();
return Satisfaction->IsSatisfied;
}
SourceLocation getConceptNameLoc() const { return ConceptNameLoc; }
SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
/// \brief Get elaborated satisfaction info about the template arguments'
/// satisfaction of the named concept.
/// The expression must not be dependent.
const ASTConstraintSatisfaction &getSatisfaction() const {
assert(!isValueDependent()
&& "getSatisfaction called on dependent ConceptSpecializationExpr");
return *Satisfaction;
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == ConceptSpecializationExprClass;
}
SourceLocation getBeginLoc() const LLVM_READONLY { return ConceptNameLoc; }
SourceLocation getBeginLoc() const LLVM_READONLY {
return ConceptName.getBeginLoc();
}
SourceLocation getEndLoc() const LLVM_READONLY {
return ArgsAsWritten->RAngleLoc;
}

View File

@ -642,7 +642,7 @@ class ObjCPropertyRefExpr : public Expr {
/// the location of the 'super' keyword. When it's an interface,
/// this is that interface.
SourceLocation ReceiverLoc;
llvm::PointerUnion3<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver;
llvm::PointerUnion<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver;
public:
ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,

View File

@ -66,9 +66,8 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
/// whenever we might have added new redeclarations for existing decls.
uint32_t CurrentGeneration = 0;
/// Whether this AST source also provides information for
/// semantic analysis.
bool SemaSource = false;
/// LLVM-style RTTI.
static char ID;
public:
ExternalASTSource() = default;
@ -325,6 +324,12 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
/// LLVM-style RTTI.
/// \{
virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
/// \}
protected:
static DeclContextLookupResult
SetExternalVisibleDeclsForName(const DeclContext *DC,

View File

@ -16,12 +16,13 @@
#define LLVM_CLANG_AST_JSONNODEDUMPER_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTNodeTraverser.h"
#include "clang/AST/ASTDumperUtils.h"
#include "clang/AST/ASTNodeTraverser.h"
#include "clang/AST/AttrVisitor.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/CommentVisitor.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/Mangle.h"
#include "llvm/Support/JSON.h"
namespace clang {
@ -122,9 +123,10 @@ class JSONNodeDumper
const SourceManager &SM;
ASTContext& Ctx;
ASTNameGenerator ASTNameGen;
PrintingPolicy PrintPolicy;
const comments::CommandTraits *Traits;
StringRef LastLocFilename;
StringRef LastLocFilename, LastLocPresumedFilename;
unsigned LastLocLine, LastLocPresumedLine;
using InnerAttrVisitor = ConstAttrVisitor<JSONNodeDumper>;
@ -182,8 +184,9 @@ class JSONNodeDumper
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) {}
: NodeStreamer(OS), SM(SrcMgr), Ctx(Ctx), ASTNameGen(Ctx),
PrintPolicy(PrintPolicy), Traits(Traits), LastLocLine(0),
LastLocPresumedLine(0) {}
void Visit(const Attr *A);
void Visit(const Stmt *Node);

View File

@ -30,6 +30,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
@ -111,7 +112,7 @@ class OMPClauseWithPreInit {
Stmt *PreInit = nullptr;
/// Region that captures the associated stmt.
OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
OpenMPDirectiveKind CaptureRegion = llvm::omp::OMPD_unknown;
protected:
OMPClauseWithPreInit(const OMPClause *This) {
@ -119,7 +120,9 @@ class OMPClauseWithPreInit {
}
/// Set pre-initialization statement for the clause.
void setPreInitStmt(Stmt *S, OpenMPDirectiveKind ThisRegion = OMPD_unknown) {
void
setPreInitStmt(Stmt *S,
OpenMPDirectiveKind ThisRegion = llvm::omp::OMPD_unknown) {
PreInit = S;
CaptureRegion = ThisRegion;
}
@ -432,7 +435,7 @@ class OMPIfClause : public OMPClause, public OMPClauseWithPreInit {
SourceLocation ColonLoc;
/// Directive name modifier for the clause.
OpenMPDirectiveKind NameModifier = OMPD_unknown;
OpenMPDirectiveKind NameModifier = llvm::omp::OMPD_unknown;
/// Name modifier location.
SourceLocation NameModifierLoc;
@ -943,7 +946,7 @@ class OMPProcBindClause : public OMPClause {
SourceLocation LParenLoc;
/// A kind of the 'proc_bind' clause.
OpenMPProcBindClauseKind Kind = OMPC_PROC_BIND_unknown;
llvm::omp::ProcBindKind Kind = llvm::omp::OMP_PROC_BIND_unknown;
/// Start location of the kind in source code.
SourceLocation KindKwLoc;
@ -951,7 +954,7 @@ class OMPProcBindClause : public OMPClause {
/// Set kind of the clause.
///
/// \param K Kind of clause.
void setProcBindKind(OpenMPProcBindClauseKind K) { Kind = K; }
void setProcBindKind(llvm::omp::ProcBindKind K) { Kind = K; }
/// Set clause kind location.
///
@ -967,7 +970,7 @@ class OMPProcBindClause : public OMPClause {
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
OMPProcBindClause(OpenMPProcBindClauseKind A, SourceLocation ALoc,
OMPProcBindClause(llvm::omp::ProcBindKind A, SourceLocation ALoc,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
: OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
@ -984,7 +987,7 @@ class OMPProcBindClause : public OMPClause {
SourceLocation getLParenLoc() const { return LParenLoc; }
/// Returns kind of the clause.
OpenMPProcBindClauseKind getProcBindKind() const { return Kind; }
llvm::omp::ProcBindKind getProcBindKind() const { return Kind; }
/// Returns location of clause kind.
SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; }
@ -2150,6 +2153,13 @@ class OMPLastprivateClause final
friend OMPVarListClause;
friend TrailingObjects;
/// Optional lastprivate kind, e.g. 'conditional', if specified by user.
OpenMPLastprivateModifier LPKind;
/// Optional location of the lasptrivate kind, if specified by user.
SourceLocation LPKindLoc;
/// Optional colon location, if specified by user.
SourceLocation ColonLoc;
/// Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
@ -2157,10 +2167,13 @@ class OMPLastprivateClause final
/// \param EndLoc Ending location of the clause.
/// \param N Number of the variables in the clause.
OMPLastprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
SourceLocation EndLoc, OpenMPLastprivateModifier LPKind,
SourceLocation LPKindLoc, SourceLocation ColonLoc,
unsigned N)
: OMPVarListClause<OMPLastprivateClause>(OMPC_lastprivate, StartLoc,
LParenLoc, EndLoc, N),
OMPClauseWithPostUpdate(this) {}
OMPClauseWithPostUpdate(this), LPKind(LPKind), LPKindLoc(LPKindLoc),
ColonLoc(ColonLoc) {}
/// Build an empty clause.
///
@ -2221,6 +2234,13 @@ class OMPLastprivateClause final
return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
}
/// Sets lastprivate kind.
void setKind(OpenMPLastprivateModifier Kind) { LPKind = Kind; }
/// Sets location of the lastprivate kind.
void setKindLoc(SourceLocation Loc) { LPKindLoc = Loc; }
/// Sets colon symbol location.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
public:
/// Creates clause with a list of variables \a VL.
///
@ -2242,6 +2262,9 @@ class OMPLastprivateClause final
/// \endcode
/// Required for proper codegen of final assignment performed by the
/// lastprivate clause.
/// \param LPKind Lastprivate kind, e.g. 'conditional'.
/// \param LPKindLoc Location of the lastprivate kind.
/// \param ColonLoc Location of the ':' symbol if lastprivate kind is used.
/// \param PreInit Statement that must be executed before entering the OpenMP
/// region with this clause.
/// \param PostUpdate Expression that must be executed after exit from the
@ -2250,7 +2273,8 @@ class OMPLastprivateClause final
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,
Stmt *PreInit, Expr *PostUpdate);
OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc,
SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate);
/// Creates an empty clause with the place for \a N variables.
///
@ -2258,6 +2282,13 @@ class OMPLastprivateClause final
/// \param N The number of variables.
static OMPLastprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
/// Lastprivate kind.
OpenMPLastprivateModifier getKind() const { return LPKind; }
/// Returns the location of the lastprivate kind.
SourceLocation getKindLoc() const { return LPKindLoc; }
/// Returns the location of the ':' symbol, if any.
SourceLocation getColonLoc() const { return ColonLoc; }
using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
@ -6240,6 +6271,102 @@ class OMPIsDevicePtrClause final
}
};
/// This represents clause 'nontemporal' in the '#pragma omp ...' directives.
///
/// \code
/// #pragma omp simd nontemporal(a)
/// \endcode
/// In this example directive '#pragma omp simd' has clause 'nontemporal' for
/// the variable 'a'.
class OMPNontemporalClause final
: public OMPVarListClause<OMPNontemporalClause>,
private llvm::TrailingObjects<OMPNontemporalClause, Expr *> {
friend class OMPClauseReader;
friend OMPVarListClause;
friend TrailingObjects;
/// Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param N Number of the variables in the clause.
OMPNontemporalClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPNontemporalClause>(OMPC_nontemporal, StartLoc,
LParenLoc, EndLoc, N) {}
/// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPNontemporalClause(unsigned N)
: OMPVarListClause<OMPNontemporalClause>(
OMPC_nontemporal, SourceLocation(), SourceLocation(),
SourceLocation(), N) {}
/// Get the list of privatied copies if the member expression was captured by
/// one of the privatization clauses.
MutableArrayRef<Expr *> getPrivateRefs() {
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateRefs() const {
return llvm::makeArrayRef(varlist_end(), varlist_size());
}
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 EndLoc Ending location of the clause.
/// \param VL List of references to the variables.
static OMPNontemporalClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL);
/// Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
static OMPNontemporalClause *CreateEmpty(const ASTContext &C, unsigned N);
/// Sets the list of references to private copies created in private clauses.
/// \param VL List of references.
void setPrivateRefs(ArrayRef<Expr *> VL);
child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
}
const_child_range children() const {
auto Children = const_cast<OMPNontemporalClause *>(this)->children();
return const_child_range(Children.begin(), Children.end());
}
child_range private_refs() {
return child_range(reinterpret_cast<Stmt **>(getPrivateRefs().begin()),
reinterpret_cast<Stmt **>(getPrivateRefs().end()));
}
const_child_range private_refs() const {
auto Children = const_cast<OMPNontemporalClause *>(this)->private_refs();
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_nontemporal;
}
};
/// This class implements a simple visitor for OMPClause
/// subclasses.
template<class ImplClass, template <typename> class Ptr, typename RetTy>

View File

@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines the PrinterHelper interface.
// This file defines helper types for AST pretty-printing.
//
//===----------------------------------------------------------------------===//
@ -29,6 +29,16 @@ class PrinterHelper {
virtual bool handledStmt(Stmt* E, raw_ostream& OS) = 0;
};
/// Callbacks to use to customize the behavior of the pretty-printer.
class PrintingCallbacks {
protected:
~PrintingCallbacks() = default;
public:
/// Remap a path to a form suitable for printing.
virtual std::string remapPath(StringRef Path) const { return Path; }
};
/// Describes how types, statements, expressions, and declarations should be
/// printed.
///
@ -50,7 +60,7 @@ struct PrintingPolicy {
MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
MSVCFormatting(false), ConstantsAsWritten(false),
SuppressImplicitBase(false), FullyQualifiedName(false),
RemapFilePaths(false), PrintCanonicalTypes(false) {}
PrintCanonicalTypes(false) {}
/// Adjust this printing policy for cases where it's known that we're
/// printing C++ code (for instance, if AST dumping reaches a C++-only
@ -224,14 +234,11 @@ struct PrintingPolicy {
/// This is the opposite of SuppressScope and thus overrules it.
unsigned FullyQualifiedName : 1;
/// Whether to apply -fdebug-prefix-map to any file paths.
unsigned RemapFilePaths : 1;
/// Whether to print types as written or canonically.
unsigned PrintCanonicalTypes : 1;
/// When RemapFilePaths is true, this function performs the action.
std::function<std::string(StringRef)> remapPath;
/// Callbacks to use to allow the behavior of printing to be customized.
const PrintingCallbacks *Callbacks = nullptr;
};
} // end namespace clang

View File

@ -0,0 +1,495 @@
//==--- PropertiesBase.td - Baseline definitions for AST properties -------===//
//
// 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
//
//===----------------------------------------------------------------------===//
class HasProperties;
/// The type of the property.
class PropertyType<string typeName = ""> {
/// The C++ type name for the type.
string CXXName = !if(!ne(typeName, ""), typeName, NAME);
/// Whether the C++ type should generally be passed around by reference.
bit PassByReference = 0;
/// Whether `const` should be prepended to the type when writing.
bit ConstWhenWriting = 0;
/// Given a value of type Optional<CXXName> bound as 'value', yield a
/// CXXName that can be serialized into a DataStreamTypeWriter.
string PackOptional = "";
/// Given a value of type CXXName bound as 'value' that was deserialized
/// by a DataStreamTypeReader, yield an Optional<CXXName>.
string UnpackOptional = "";
/// A list of types for which buffeers must be passed to the read
/// operations.
list<PropertyType> BufferElementTypes = [];
}
/// Property types that correspond to specific C++ enums.
class EnumPropertyType<string typeName = ""> : PropertyType<typeName> {}
/// Property types that correspond to a specific C++ class.
/// Supports optional values by using the null representation.
class RefPropertyType<string className> : PropertyType<className # "*"> {
let PackOptional =
"value ? *value : nullptr";
let UnpackOptional =
"value ? llvm::Optional<" # CXXName # ">(value) : llvm::None";
}
/// Property types that correspond to a specific subclass of another type.
class SubclassPropertyType<string className, PropertyType base>
: RefPropertyType<className> {
PropertyType Base = base;
string SubclassName = className;
let ConstWhenWriting = base.ConstWhenWriting;
}
/// Property types that support optional values by using their
/// default value.
class DefaultValuePropertyType<string typeName = ""> : PropertyType<typeName> {
let PackOptional =
"value ? *value : " # CXXName # "()";
let UnpackOptional =
"value.isNull() ? llvm::None : llvm::Optional<" # CXXName # ">(value)";
}
/// Property types that correspond to integer types and support optional
/// values by shifting the value over by 1.
class CountPropertyType<string typeName = ""> : PropertyType<typeName> {
let PackOptional =
"value ? *value + 1 : 0";
let UnpackOptional =
"value ? llvm::Optional<" # CXXName # ">(value - 1) : llvm::None";
}
def APInt : PropertyType<"llvm::APInt"> { let PassByReference = 1; }
def APSInt : PropertyType<"llvm::APSInt"> { let PassByReference = 1; }
def ArraySizeModifier : EnumPropertyType<"ArrayType::ArraySizeModifier">;
def AttrKind : EnumPropertyType<"attr::Kind">;
def AutoTypeKeyword : EnumPropertyType;
def Bool : PropertyType<"bool">;
def BuiltinTypeKind : EnumPropertyType<"BuiltinType::Kind">;
def CallingConv : EnumPropertyType;
def DeclarationName : PropertyType;
def DeclarationNameKind : EnumPropertyType<"DeclarationName::NameKind">;
def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
def CXXRecordDeclRef :
SubclassPropertyType<"CXXRecordDecl", DeclRef>;
def FunctionDeclRef :
SubclassPropertyType<"FunctionDecl", DeclRef>;
def NamedDeclRef :
SubclassPropertyType<"NamedDecl", DeclRef>;
def NamespaceDeclRef :
SubclassPropertyType<"NamespaceDecl", DeclRef>;
def NamespaceAliasDeclRef :
SubclassPropertyType<"NamespaceAliasDecl", DeclRef>;
def ObjCProtocolDeclRef :
SubclassPropertyType<"ObjCProtocolDecl", DeclRef>;
def ObjCTypeParamDeclRef :
SubclassPropertyType<"ObjCTypeParamDecl", DeclRef>;
def TagDeclRef :
SubclassPropertyType<"TagDecl", DeclRef>;
def TemplateDeclRef :
SubclassPropertyType<"TemplateDecl", DeclRef>;
def TemplateTypeParmDeclRef :
SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>;
def TemplateTemplateParmDeclRef :
SubclassPropertyType<"TemplateTemplateParmDecl", DeclRef>;
def ValueDeclRef :
SubclassPropertyType<"ValueDecl", DeclRef>;
def ElaboratedTypeKeyword : EnumPropertyType;
def ExtParameterInfo : PropertyType<"FunctionProtoType::ExtParameterInfo">;
def Identifier : RefPropertyType<"IdentifierInfo"> { let ConstWhenWriting = 1; }
def NestedNameSpecifier : PropertyType<"NestedNameSpecifier *">;
def NestedNameSpecifierKind :
EnumPropertyType<"NestedNameSpecifier::SpecifierKind">;
def OverloadedOperatorKind : EnumPropertyType;
def Qualifiers : PropertyType;
def QualType : DefaultValuePropertyType;
def RefQualifierKind : EnumPropertyType;
def Selector : PropertyType;
def SourceLocation : PropertyType;
def StmtRef : RefPropertyType<"Stmt"> { let ConstWhenWriting = 1; }
def ExprRef : SubclassPropertyType<"Expr", StmtRef>;
def TemplateArgument : PropertyType;
def TemplateArgumentKind : EnumPropertyType<"TemplateArgument::ArgKind">;
def TemplateName : DefaultValuePropertyType;
def TemplateNameKind : EnumPropertyType<"TemplateName::NameKind">;
def UInt32 : CountPropertyType<"uint32_t">;
def UInt64 : CountPropertyType<"uint64_t">;
def UnaryTypeTransformKind : EnumPropertyType<"UnaryTransformType::UTTKind">;
def VectorKind : EnumPropertyType<"VectorType::VectorKind">;
def ExceptionSpecInfo : PropertyType<"FunctionProtoType::ExceptionSpecInfo"> {
let BufferElementTypes = [ QualType ];
}
/// Arrays. The corresponding C++ type is ArrayRef of the corresponding
/// C++ type of the element.
class Array<PropertyType element> : PropertyType {
PropertyType Element = element;
let BufferElementTypes = [ element ];
}
/// llvm::Optional<T>. The corresponding C++ type is generally just the
/// corresponding C++ type of the element.
///
/// Optional<Unsigned> may restrict the range of the operand for some
/// serialization clients.
class Optional<PropertyType element> : PropertyType {
PropertyType Element = element;
let PassByReference = element.PassByReference;
}
/// A property of an AST node.
class Property<string name, PropertyType type> {
HasProperties Class;
string Name = name;
PropertyType Type = type;
/// A function for reading the property, expressed in terms of a variable
/// "node".
code Read;
/// Code specifying when this property is available. Can be defined
/// in terms of other properties, in which case this property must be
/// read/written after those properties. Using this will make the
/// value Optional when deserializing.
///
/// FIXME: the emitter doesn't yet force dependent properties to be
/// read/written later; this only works if the properties used in the
/// condition happen to be written first.
code Conditional = "";
}
/// A rule for declaring helper variables when read properties from a
/// value of this type. Note that this means that this code is actually
/// run when *writing* values of this type; however, naming this
/// `ReadHelper` makes the connection to the `Read` operations on the
/// properties much clearer.
class ReadHelper<code _code> {
HasProperties Class;
/// Code which will be run when writing objects of this type before
/// writing any of the properties, specified in terms of a variable
/// `node`.
code Code = _code;
}
/// A rule for creating objects of this type.
class Creator<code create> {
HasProperties Class;
/// A function for creating values of this kind, expressed in terms of a
/// variable `ctx` of type `ASTContext &`. Must also refer to all of the
/// properties by name.
code Create = create;
}
/// A rule which overrides some of the normal rules.
class Override {
HasProperties Class;
/// Properties from base classes that should be ignored.
list<string> IgnoredProperties = [];
}
/// A description of how to break a type into cases. Providing this and
/// an exhaustive list of the cases will cause AbstractBasic{Reader,Writer}
/// to be generated with a default implementation of how to read the
/// type.
///
/// Creator rules for the cases can additionally access a variable
/// `kind` of the KindType.
class PropertyTypeKind<PropertyType type,
PropertyType kindType,
string readCode> {
/// The type for which this describes cases.
PropertyType Type = type;
/// The type of this type's kind enum.
PropertyType KindType = kindType;
/// The property name to use for the kind.
string KindPropertyName = "kind";
/// An expression which reads the kind from a value, expressed in terms
/// of a variable `node`.
string Read = readCode;
}
/// One of the options for representing a particular type.
class PropertyTypeCase<PropertyType type, string name> : HasProperties {
/// The type of which this is a case.
PropertyType Type = type;
/// The name of the case (a value of the type's kind enum).
string Name = name;
}
// Type cases for DeclarationName.
def : PropertyTypeKind<DeclarationName, DeclarationNameKind,
"node.getNameKind()">;
let Class = PropertyTypeCase<DeclarationName, "Identifier"> in {
def : Property<"identifier", Identifier> {
let Read = [{ node.getAsIdentifierInfo() }];
}
def : Creator<[{
return DeclarationName(identifier);
}]>;
}
foreach count = ["Zero", "One", "Multi"] in {
let Class = PropertyTypeCase<DeclarationName, "ObjC"#count#"ArgSelector"> in {
def : Property<"selector", Selector> {
let Read = [{ node.getObjCSelector() }];
}
def : Creator<[{
return DeclarationName(selector);
}]>;
}
}
foreach kind = ["Constructor", "Destructor", "ConversionFunction"] in {
let Class = PropertyTypeCase<DeclarationName, "CXX"#kind#"Name"> in {
def : Property<"type", QualType> {
let Read = [{ node.getCXXNameType() }];
}
def : Creator<[{
return ctx.DeclarationNames.getCXX}]#kind#[{Name(
ctx.getCanonicalType(type));
}]>;
}
}
let Class = PropertyTypeCase<DeclarationName, "CXXDeductionGuideName"> in {
def : Property<"declaration", TemplateDeclRef> {
let Read = [{ node.getCXXDeductionGuideTemplate() }];
}
def : Creator<[{
return ctx.DeclarationNames.getCXXDeductionGuideName(declaration);
}]>;
}
let Class = PropertyTypeCase<DeclarationName, "CXXOperatorName"> in {
def : Property<"operatorKind", OverloadedOperatorKind> {
let Read = [{ node.getCXXOverloadedOperator() }];
}
def : Creator<[{
return ctx.DeclarationNames.getCXXOperatorName(operatorKind);
}]>;
}
let Class = PropertyTypeCase<DeclarationName, "CXXLiteralOperatorName"> in {
def : Property<"identifier", Identifier> {
let Read = [{ node.getCXXLiteralIdentifier() }];
}
def : Creator<[{
return ctx.DeclarationNames.getCXXLiteralOperatorName(identifier);
}]>;
}
let Class = PropertyTypeCase<DeclarationName, "CXXUsingDirective"> in {
def : Creator<[{
return DeclarationName::getUsingDirectiveName();
}]>;
}
// Type cases for TemplateName.
def : PropertyTypeKind<TemplateName, TemplateNameKind, "node.getKind()">;
let Class = PropertyTypeCase<TemplateName, "Template"> in {
def : Property<"declaration", TemplateDeclRef> {
let Read = [{ node.getAsTemplateDecl() }];
}
def : Creator<[{
return TemplateName(declaration);
}]>;
}
let Class = PropertyTypeCase<TemplateName, "OverloadedTemplate"> in {
def : Property<"overloads", Array<NamedDeclRef>> {
let Read = [{ node.getAsOverloadedTemplate()->decls() }];
}
def : Creator<[{
// Copy into an UnresolvedSet to satisfy the interface.
UnresolvedSet<8> overloadSet;
for (auto overload : overloads) {
overloadSet.addDecl(overload);
}
return ctx.getOverloadedTemplateName(overloadSet.begin(),
overloadSet.end());
}]>;
}
let Class = PropertyTypeCase<TemplateName, "AssumedTemplate"> in {
def : Property<"name", DeclarationName> {
let Read = [{ node.getAsAssumedTemplateName()->getDeclName() }];
}
def : Creator<[{
return ctx.getAssumedTemplateName(name);
}]>;
}
let Class = PropertyTypeCase<TemplateName, "QualifiedTemplate"> in {
def : ReadHelper<[{
auto qtn = node.getAsQualifiedTemplateName();
}]>;
def : Property<"qualifier", NestedNameSpecifier> {
let Read = [{ qtn->getQualifier() }];
}
def : Property<"hasTemplateKeyword", Bool> {
let Read = [{ qtn->hasTemplateKeyword() }];
}
def : Property<"declaration", TemplateDeclRef> {
let Read = [{ qtn->getTemplateDecl() }];
}
def : Creator<[{
return ctx.getQualifiedTemplateName(qualifier, hasTemplateKeyword,
declaration);
}]>;
}
let Class = PropertyTypeCase<TemplateName, "DependentTemplate"> in {
def : ReadHelper<[{
auto dtn = node.getAsDependentTemplateName();
}]>;
def : Property<"qualifier", NestedNameSpecifier> {
let Read = [{ dtn->getQualifier() }];
}
def : Property<"identifier", Optional<Identifier>> {
let Read = [{ makeOptionalFromPointer(
dtn->isIdentifier()
? dtn->getIdentifier()
: nullptr) }];
}
def : Property<"operatorKind", OverloadedOperatorKind> {
let Conditional = [{ !identifier }];
let Read = [{ dtn->getOperator() }];
}
def : Creator<[{
if (identifier) {
return ctx.getDependentTemplateName(qualifier, *identifier);
} else {
return ctx.getDependentTemplateName(qualifier, *operatorKind);
}
}]>;
}
let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParm"> in {
def : ReadHelper<[{
auto parm = node.getAsSubstTemplateTemplateParm();
}]>;
def : Property<"parameter", TemplateTemplateParmDeclRef> {
let Read = [{ parm->getParameter() }];
}
def : Property<"replacement", TemplateName> {
let Read = [{ parm->getReplacement() }];
}
def : Creator<[{
return ctx.getSubstTemplateTemplateParm(parameter, replacement);
}]>;
}
let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParmPack"> in {
def : ReadHelper<[{
auto parm = node.getAsSubstTemplateTemplateParmPack();
}]>;
def : Property<"parameterPack", TemplateTemplateParmDeclRef> {
let Read = [{ parm->getParameterPack() }];
}
def : Property<"argumentPack", TemplateArgument> {
let Read = [{ parm->getArgumentPack() }];
}
def : Creator<[{
return ctx.getSubstTemplateTemplateParmPack(parameterPack, argumentPack);
}]>;
}
// Type cases for TemplateArgument.
def : PropertyTypeKind<TemplateArgument, TemplateArgumentKind,
"node.getKind()">;
let Class = PropertyTypeCase<TemplateArgument, "Null"> in {
def : Creator<[{
return TemplateArgument();
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Type"> in {
def : Property<"type", QualType> {
let Read = [{ node.getAsType() }];
}
def : Creator<[{
return TemplateArgument(type);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Declaration"> in {
def : Property<"declaration", ValueDeclRef> {
let Read = [{ node.getAsDecl() }];
}
def : Property<"parameterType", QualType> {
let Read = [{ node.getParamTypeForDecl() }];
}
def : Creator<[{
return TemplateArgument(declaration, parameterType);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "NullPtr"> in {
def : Property<"type", QualType> {
let Read = [{ node.getNullPtrType() }];
}
def : Creator<[{
return TemplateArgument(type, /*nullptr*/ true);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Integral"> in {
def : Property<"value", APSInt> {
let Read = [{ node.getAsIntegral() }];
}
def : Property<"type", QualType> {
let Read = [{ node.getIntegralType() }];
}
def : Creator<[{
return TemplateArgument(ctx, value, type);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Template"> in {
def : Property<"name", TemplateName> {
let Read = [{ node.getAsTemplateOrTemplatePattern() }];
}
def : Creator<[{
return TemplateArgument(name);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "TemplateExpansion"> in {
def : Property<"name", TemplateName> {
let Read = [{ node.getAsTemplateOrTemplatePattern() }];
}
def : Property<"numExpansions", Optional<UInt32>> {
let Read = [{
// Translate unsigned -> uint32_t just in case.
node.getNumTemplateExpansions().map(
[](unsigned i) { return uint32_t(i); })
}];
}
def : Creator<[{
auto numExpansionsUnsigned =
numExpansions.map([](uint32_t i) { return unsigned(i); });
return TemplateArgument(name, numExpansionsUnsigned);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Expression"> in {
def : Property<"expression", ExprRef> {
let Read = [{ node.getAsExpr() }];
}
def : Creator<[{
return TemplateArgument(expression);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Pack"> in {
def : Property<"elements", Array<TemplateArgument>> {
let Read = [{ node.pack_elements() }];
}
def : Creator<[{
// Copy the pack into the ASTContext.
TemplateArgument *ctxElements = new (ctx) TemplateArgument[elements.size()];
for (size_t i = 0, e = elements.size(); i != e; ++i)
ctxElements[i] = elements[i];
return TemplateArgument(llvm::makeArrayRef(ctxElements, elements.size()));
}]>;
}

View File

@ -304,6 +304,11 @@ template <typename Derived> class RecursiveASTVisitor {
bool TraverseSynOrSemInitListExpr(InitListExpr *S,
DataRecursionQueue *Queue = nullptr);
/// Recursively visit a reference to a concept with potential arguments.
///
/// \returns false if the visitation was terminated early, true otherwise.
bool TraverseConceptReference(const ConceptReference &C);
// ---- Methods on Attrs ----
// Visit an attribute.
@ -1162,11 +1167,13 @@ DEF_TRAVERSE_TYPELOC(LValueReferenceType,
DEF_TRAVERSE_TYPELOC(RValueReferenceType,
{ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
// FIXME: location of base class?
// We traverse this in the type case as well, but how is it not reached through
// the pointee type?
DEF_TRAVERSE_TYPELOC(MemberPointerType, {
TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
if (auto *TSI = TL.getClassTInfo())
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
else
TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
})
@ -1435,6 +1442,10 @@ DEF_TRAVERSE_DECL(CapturedDecl, {
DEF_TRAVERSE_DECL(EmptyDecl, {})
DEF_TRAVERSE_DECL(LifetimeExtendedTemporaryDecl, {
TRY_TO(TraverseStmt(D->getTemporaryExpr()));
})
DEF_TRAVERSE_DECL(FileScopeAsmDecl,
{ TRY_TO(TraverseStmt(D->getAsmString())); })
@ -1767,9 +1778,8 @@ DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
// D is the "T" in something like
// template <template <typename> class T> class container { };
TRY_TO(TraverseDecl(D->getTemplatedDecl()));
if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
}
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
})
@ -1781,6 +1791,8 @@ DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
// D is the "T" in something like "template<typename T> class vector;"
if (D->getTypeForDecl())
TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
if (const auto *TC = D->getTypeConstraint())
TRY_TO(TraverseConceptReference(*TC));
if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
})
@ -2024,6 +2036,11 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
}
}
// Visit the trailing requires clause, if any.
if (Expr *TrailingRequiresClause = D->getTrailingRequiresClause()) {
TRY_TO(TraverseStmt(TrailingRequiresClause));
}
if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
// Constructor initializers.
for (auto *I : Ctor->inits()) {
@ -2319,6 +2336,18 @@ bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
return true;
}
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseConceptReference(
const ConceptReference &C) {
TRY_TO(TraverseNestedNameSpecifierLoc(C.getNestedNameSpecifierLoc()));
TRY_TO(TraverseDeclarationNameInfo(C.getConceptNameInfo()));
if (C.hasExplicitTemplateArgs())
TRY_TO(TraverseTemplateArgumentLocsHelper(
C.getTemplateArgsAsWritten()->getTemplateArgs(),
C.getTemplateArgsAsWritten()->NumTemplateArgs));
return true;
}
// If shouldVisitImplicitCode() returns false, this method traverses only the
// syntactic form of InitListExpr.
// If shouldVisitImplicitCode() return true, this method is called once for
@ -2351,7 +2380,7 @@ bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(
// generic associations).
DEF_TRAVERSE_STMT(GenericSelectionExpr, {
TRY_TO(TraverseStmt(S->getControllingExpr()));
for (const GenericSelectionExpr::Association &Assoc : S->associations()) {
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());
@ -2632,10 +2661,16 @@ DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
DEF_TRAVERSE_STMT(CXXFoldExpr, {})
DEF_TRAVERSE_STMT(AtomicExpr, {})
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {
if (S->getLifetimeExtendedTemporaryDecl()) {
TRY_TO(TraverseLifetimeExtendedTemporaryDecl(
S->getLifetimeExtendedTemporaryDecl()));
ShouldVisitChildren = false;
}
})
// For coroutines expressions, traverse either the operand
// as written or the implied calls, depending on what the
// derived class requests.
@ -2671,9 +2706,7 @@ DEF_TRAVERSE_STMT(CoyieldExpr, {
})
DEF_TRAVERSE_STMT(ConceptSpecializationExpr, {
TRY_TO(TraverseTemplateArgumentLocsHelper(
S->getTemplateArgsAsWritten()->getTemplateArgs(),
S->getTemplateArgsAsWritten()->NumTemplateArgs));
TRY_TO(TraverseConceptReference(*S));
})
// These literals (all of them) do not need any action.
@ -2742,6 +2775,9 @@ DEF_TRAVERSE_STMT(OMPParallelForDirective,
DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPParallelMasterDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@ -2814,6 +2850,9 @@ DEF_TRAVERSE_STMT(OMPMasterTaskLoopSimdDirective,
DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopSimdDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPDistributeDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@ -3356,6 +3395,16 @@ bool RecursiveASTVisitor<Derived>::VisitOMPIsDevicePtrClause(
return true;
}
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPNontemporalClause(
OMPNontemporalClause *C) {
TRY_TO(VisitOMPClauseList(C));
for (auto *E : C->private_refs()) {
TRY_TO(TraverseStmt(E));
}
return true;
}
// FIXME: look at the following tricky-seeming exprs to see if we
// need to recurse on anything. These are ones that have methods
// returning decls or qualtypes or nestednamespecifier -- though I'm

View File

@ -1995,6 +1995,10 @@ class IfStmt final
bool isConstexpr() const { return IfStmtBits.IsConstexpr; }
void setConstexpr(bool C) { IfStmtBits.IsConstexpr = C; }
/// If this is an 'if constexpr', determine which substatement will be taken.
/// Otherwise, or if the condition is value-dependent, returns None.
Optional<const Stmt*> getNondiscardedCase(const ASTContext &Ctx) const;
bool isObjCAvailabilityCheck() const;
SourceLocation getBeginLoc() const { return getIfLoc(); }

View File

@ -189,7 +189,7 @@ class CXXFoldExpr {
}
class GenericSelectionExpr {
code Code = [{
for (const GenericSelectionExpr::ConstAssociation &Assoc : S->associations()) {
for (const GenericSelectionExpr::ConstAssociation Assoc : S->associations()) {
addData(Assoc.getType());
}
}];

File diff suppressed because it is too large Load Diff

View File

@ -119,6 +119,10 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
iterator begin() const { return getStorage(); }
iterator end() const { return getStorage() + size(); }
llvm::ArrayRef<NamedDecl*> decls() const {
return llvm::makeArrayRef(begin(), end());
}
};
/// A structure for storing an already-substituted template template
@ -186,8 +190,8 @@ class SubstTemplateTemplateParmPackStorage
/// only be understood in the context of
class TemplateName {
using StorageType =
llvm::PointerUnion4<TemplateDecl *, UncommonTemplateNameStorage *,
QualifiedTemplateName *, DependentTemplateName *>;
llvm::PointerUnion<TemplateDecl *, UncommonTemplateNameStorage *,
QualifiedTemplateName *, DependentTemplateName *>;
StorageType Storage;

View File

@ -346,6 +346,8 @@ class TextNodeDumper
void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
void VisitBlockDecl(const BlockDecl *D);
void VisitConceptDecl(const ConceptDecl *D);
void
VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D);
};
} // namespace clang

View File

@ -66,6 +66,11 @@ enum {
TypeAlignment = 1 << TypeAlignmentInBits
};
namespace serialization {
template <class T> class AbstractTypeReader;
template <class T> class AbstractTypeWriter;
}
} // namespace clang
namespace llvm {
@ -472,7 +477,10 @@ class Qualifiers {
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);
(A == LangAS::opencl_generic && B != LangAS::opencl_constant) ||
// Consider pointer size address spaces to be equivalent to default.
((isPtrSizeAddressSpace(A) || A == LangAS::Default) &&
(isPtrSizeAddressSpace(B) || B == LangAS::Default));
}
/// Returns true if the address space in these qualifiers is equal to or
@ -553,6 +561,8 @@ class Qualifiers {
std::string getAsString() const;
std::string getAsString(const PrintingPolicy &Policy) const;
static std::string getAddrSpaceAsString(LangAS AS);
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const;
void print(raw_ostream &OS, const PrintingPolicy &Policy,
bool appendSpaceIfNonEmpty = false) const;
@ -1046,6 +1056,9 @@ class QualType {
ID.AddPointer(getAsOpaquePtr());
}
/// Check if this type has any address space qualifier.
inline bool hasAddressSpace() const;
/// Return the address space of this type.
inline LangAS getAddressSpace() const;
@ -1842,6 +1855,8 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
public:
friend class ASTReader;
friend class ASTWriter;
template <class T> friend class serialization::AbstractTypeReader;
template <class T> friend class serialization::AbstractTypeWriter;
Type(const Type &) = delete;
Type(Type &&) = delete;
@ -1961,6 +1976,7 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
/// Determine whether this type is an integral or unscoped enumeration type.
bool isIntegralOrUnscopedEnumerationType() const;
bool isUnscopedEnumerationType() const;
/// Floating point categories.
bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
@ -1992,6 +2008,7 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
bool isReferenceType() const;
bool isLValueReferenceType() const;
bool isRValueReferenceType() const;
bool isObjectPointerType() const;
bool isFunctionPointerType() const;
bool isFunctionReferenceType() const;
bool isMemberPointerType() const;
@ -2069,6 +2086,8 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
bool isAlignValT() const; // C++17 std::align_val_t
bool isStdByteType() const; // C++17 std::byte
bool isAtomicType() const; // C11 _Atomic()
bool isUndeducedAutoType() const; // C++11 auto or
// C++14 decltype(auto)
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
bool is##Id##Type() const;
@ -3726,9 +3745,9 @@ class FunctionProtoType final
: public FunctionType,
public llvm::FoldingSetNode,
private llvm::TrailingObjects<
FunctionProtoType, QualType, FunctionType::FunctionTypeExtraBitfields,
FunctionType::ExceptionType, Expr *, FunctionDecl *,
FunctionType::ExtParameterInfo, Qualifiers> {
FunctionProtoType, QualType, SourceLocation,
FunctionType::FunctionTypeExtraBitfields, FunctionType::ExceptionType,
Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers> {
friend class ASTContext; // ASTContext creates these.
friend TrailingObjects;
@ -3739,6 +3758,9 @@ class FunctionProtoType final
// Always present. Note that for the vast majority of FunctionProtoType,
// these will be the only trailing objects.
//
// * Optionally if the function is variadic, the SourceLocation of the
// ellipsis.
//
// * Optionally if some extra data is stored in FunctionTypeExtraBitfields
// (see FunctionTypeExtraBitfields and FunctionTypeBitfields):
// a single FunctionTypeExtraBitfields. Present if and only if
@ -3810,6 +3832,7 @@ class FunctionProtoType final
RefQualifierKind RefQualifier = RQ_None;
ExceptionSpecInfo ExceptionSpec;
const ExtParameterInfo *ExtParameterInfos = nullptr;
SourceLocation EllipsisLoc;
ExtProtoInfo() : Variadic(false), HasTrailingReturn(false) {}
@ -3828,6 +3851,10 @@ class FunctionProtoType final
return getNumParams();
}
unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
return isVariadic();
}
unsigned numTrailingObjects(OverloadToken<FunctionTypeExtraBitfields>) const {
return hasExtraBitfields();
}
@ -3939,20 +3966,11 @@ class FunctionProtoType final
ExtProtoInfo EPI;
EPI.ExtInfo = getExtInfo();
EPI.Variadic = isVariadic();
EPI.EllipsisLoc = getEllipsisLoc();
EPI.HasTrailingReturn = hasTrailingReturn();
EPI.ExceptionSpec.Type = getExceptionSpecType();
EPI.ExceptionSpec = getExceptionSpecInfo();
EPI.TypeQuals = getMethodQuals();
EPI.RefQualifier = getRefQualifier();
if (EPI.ExceptionSpec.Type == EST_Dynamic) {
EPI.ExceptionSpec.Exceptions = exceptions();
} else if (isComputedNoexcept(EPI.ExceptionSpec.Type)) {
EPI.ExceptionSpec.NoexceptExpr = getNoexceptExpr();
} else if (EPI.ExceptionSpec.Type == EST_Uninstantiated) {
EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl();
EPI.ExceptionSpec.SourceTemplate = getExceptionSpecTemplate();
} else if (EPI.ExceptionSpec.Type == EST_Unevaluated) {
EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl();
}
EPI.ExtParameterInfos = getExtParameterInfosOrNull();
return EPI;
}
@ -3983,6 +4001,23 @@ class FunctionProtoType final
/// spec.
bool hasInstantiationDependentExceptionSpec() const;
/// Return all the available information about this type's exception spec.
ExceptionSpecInfo getExceptionSpecInfo() const {
ExceptionSpecInfo Result;
Result.Type = getExceptionSpecType();
if (Result.Type == EST_Dynamic) {
Result.Exceptions = exceptions();
} else if (isComputedNoexcept(Result.Type)) {
Result.NoexceptExpr = getNoexceptExpr();
} else if (Result.Type == EST_Uninstantiated) {
Result.SourceDecl = getExceptionSpecDecl();
Result.SourceTemplate = getExceptionSpecTemplate();
} else if (Result.Type == EST_Unevaluated) {
Result.SourceDecl = getExceptionSpecDecl();
}
return Result;
}
/// Return the number of types in the exception specification.
unsigned getNumExceptions() const {
return getExceptionSpecType() == EST_Dynamic
@ -4040,6 +4075,11 @@ class FunctionProtoType final
/// Whether this function prototype is variadic.
bool isVariadic() const { return FunctionTypeBits.Variadic; }
SourceLocation getEllipsisLoc() const {
return isVariadic() ? *getTrailingObjects<SourceLocation>()
: SourceLocation();
}
/// Determines whether this function prototype contains a
/// parameter pack at the end.
///
@ -4420,6 +4460,7 @@ class DependentUnaryTransformType : public UnaryTransformType,
class TagType : public Type {
friend class ASTReader;
template <class T> friend class serialization::AbstractTypeReader;
/// Stores the TagDecl associated with this type. The decl may point to any
/// TagDecl that declares the entity.
@ -5057,6 +5098,7 @@ class InjectedClassNameType : public Type {
friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not
// currently suitable for AST reading, too much
// interdependencies.
template <class T> friend class serialization::AbstractTypeReader;
CXXRecordDecl *Decl;
@ -5569,7 +5611,7 @@ class ObjCTypeParamType : public Type,
public:
bool isSugared() const { return true; }
QualType desugar() const;
QualType desugar() const { return getCanonicalTypeInternal(); }
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCTypeParam;
@ -5815,6 +5857,7 @@ class ObjCInterfaceType : public ObjCObjectType {
friend class ASTContext; // ASTContext creates these.
friend class ASTReader;
friend class ObjCInterfaceDecl;
template <class T> friend class serialization::AbstractTypeReader;
mutable ObjCInterfaceDecl *Decl;
@ -6136,6 +6179,33 @@ class QualifierCollector : public Qualifiers {
QualType apply(const ASTContext &Context, const Type* T) const;
};
/// A container of type source information.
///
/// A client can read the relevant info using TypeLoc wrappers, e.g:
/// @code
/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
/// TL.getBeginLoc().print(OS, SrcMgr);
/// @endcode
class alignas(8) TypeSourceInfo {
// Contains a memory block after the class, used for type source information,
// allocated by ASTContext.
friend class ASTContext;
QualType Ty;
TypeSourceInfo(QualType ty) : Ty(ty) {}
public:
/// Return the type wrapped by this type source info.
QualType getType() const { return Ty; }
/// Return the TypeLoc wrapper for the type source info.
TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
/// Override the type stored in this TypeSourceInfo. Use with caution!
void overrideType(QualType T) { Ty = T; }
};
// Inline function definitions.
inline SplitQualType SplitQualType::getSingleStepDesugaredType() const {
@ -6260,6 +6330,11 @@ inline void QualType::removeLocalCVRQualifiers(unsigned Mask) {
removeLocalFastQualifiers(Mask);
}
/// Check if this type has any address space qualifier.
inline bool QualType::hasAddressSpace() const {
return getQualifiers().hasAddressSpace();
}
/// Return the address space of this type.
inline LangAS QualType::getAddressSpace() const {
return getQualifiers().getAddressSpace();
@ -6412,6 +6487,16 @@ inline bool Type::isRValueReferenceType() const {
return isa<RValueReferenceType>(CanonicalType);
}
inline bool Type::isObjectPointerType() const {
// Note: an "object pointer type" is not the same thing as a pointer to an
// object type; rather, it is a pointer to an object type or a pointer to cv
// void.
if (const auto *T = getAs<PointerType>())
return !T->getPointeeType()->isFunctionType();
else
return false;
}
inline bool Type::isFunctionPointerType() const {
if (const auto *T = getAs<PointerType>())
return T->getPointeeType()->isFunctionType();
@ -6509,6 +6594,10 @@ inline bool Type::isAtomicType() const {
return isa<AtomicType>(CanonicalType);
}
inline bool Type::isUndeducedAutoType() const {
return isa<AutoType>(CanonicalType);
}
inline bool Type::isObjCQualifiedIdType() const {
if (const auto *OPT = getAs<ObjCObjectPointerType>())
return OPT->isObjCQualifiedIdType();
@ -6810,6 +6899,23 @@ inline const Type *Type::getPointeeOrArrayElementType() const {
return type->getBaseElementTypeUnsafe();
return type;
}
/// Insertion operator for diagnostics. This allows sending address spaces into
/// a diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
LangAS AS) {
DB.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS),
DiagnosticsEngine::ArgumentKind::ak_addrspace);
return DB;
}
/// Insertion operator for partial diagnostics. This allows sending adress
/// spaces into a diagnostic with <<.
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
LangAS AS) {
PD.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS),
DiagnosticsEngine::ArgumentKind::ak_addrspace);
return PD;
}
/// Insertion operator for diagnostics. This allows sending Qualifiers into a
/// diagnostic with <<.

View File

@ -14,8 +14,6 @@
#ifndef LLVM_CLANG_AST_TYPELOC_H
#define LLVM_CLANG_AST_TYPELOC_H
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
@ -33,12 +31,14 @@
namespace clang {
class Attr;
class ASTContext;
class CXXRecordDecl;
class Expr;
class ObjCInterfaceDecl;
class ObjCProtocolDecl;
class ObjCTypeParamDecl;
class ParmVarDecl;
class TemplateTypeParmDecl;
class UnqualTypeLoc;
class UnresolvedUsingTypenameDecl;
@ -173,9 +173,6 @@ class TypeLoc {
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:
@ -707,11 +704,7 @@ class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
/// True if the tag was defined in this type specifier.
bool isDefinition() const {
TagDecl *D = getDecl();
return D->isCompleteDefinition() &&
(D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
}
bool isDefinition() const;
};
/// Wrapper for source info for record types.
@ -881,18 +874,7 @@ class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
return dyn_cast_or_null<T>(getAttr());
}
SourceRange getLocalSourceRange() const {
// Note that this does *not* include the range of the attribute
// enclosure, e.g.:
// __attribute__((foo(bar)))
// ^~~~~~~~~~~~~~~ ~~
// or
// [[foo(bar)]]
// ^~ ~~
// That enclosure doesn't necessarily belong to a single attribute
// anyway.
return getAttr() ? getAttr()->getRange() : SourceRange();
}
SourceRange getLocalSourceRange() const;
void initializeLocal(ASTContext &Context, SourceLocation loc) {
setAttr(nullptr);

View File

@ -0,0 +1,815 @@
//==--- TypeProperties.td - Type property definitions ---------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
include "clang/AST/PropertiesBase.td"
include "clang/Basic/TypeNodes.td"
let Class = ComplexType in {
def : Property<"elementType", QualType> {
let Read = [{ node->getElementType() }];
}
def : Creator<[{ return ctx.getComplexType(elementType); }]>;
}
let Class = PointerType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
}
def : Creator<[{ return ctx.getPointerType(pointeeType); }]>;
}
let Class = AdjustedType in {
def : Property<"originalType", QualType> {
let Read = [{ node->getOriginalType() }];
}
def : Property<"adjustedType", QualType> {
let Read = [{ node->getAdjustedType() }];
}
def : Creator<[{ return ctx.getAdjustedType(originalType, adjustedType); }]>;
}
let Class = DecayedType in {
def : Override {
// We don't need to serialize the adjusted type because we can always
// derive it by decaying the original type.
let IgnoredProperties = [ "adjustedType" ];
}
def : Creator<[{ return ctx.getAdjustedParameterType(originalType); }]>;
}
let Class = BlockPointerType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
}
def : Creator<[{ return ctx.getBlockPointerType(pointeeType); }]>;
}
let Class = ReferenceType in {
def : Property<"pointeeTypeAsWritten", QualType> {
let Read = [{ node->getPointeeTypeAsWritten() }];
}
}
let Class = LValueReferenceType in {
def : Property<"isSpelledAsLValue", Bool> {
let Read = [{ node->isSpelledAsLValue() }];
}
def : Creator<[{
return ctx.getLValueReferenceType(pointeeTypeAsWritten,
isSpelledAsLValue);
}]>;
}
let Class = RValueReferenceType in {
def : Creator<[{
return ctx.getRValueReferenceType(pointeeTypeAsWritten);
}]>;
}
let Class = MemberPointerType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
}
def : Property<"baseType", QualType> {
let Read = [{ QualType(node->getClass(), 0) }];
}
def : Creator<[{
return ctx.getMemberPointerType(pointeeType, baseType.getTypePtr());
}]>;
}
let Class = ArrayType in {
def : Property<"elementType", QualType> {
let Read = [{ node->getElementType() }];
}
def : Property<"sizeModifier", ArraySizeModifier> {
let Read = [{ node->getSizeModifier() }];
}
def : Property<"indexQualifiers", Qualifiers> {
let Read = [{ Qualifiers::fromCVRMask(node->getIndexTypeCVRQualifiers()) }];
}
}
let Class = ConstantArrayType in {
def : Property<"sizeValue", APInt> {
let Read = [{ node->getSize() }];
}
def : Property<"size", ExprRef> {
let Read = [{ node->getSizeExpr() }];
}
def : Creator<[{
return ctx.getConstantArrayType(elementType, sizeValue, size,
sizeModifier,
indexQualifiers.getCVRQualifiers());
}]>;
}
let Class = IncompleteArrayType in {
def : Creator<[{
return ctx.getIncompleteArrayType(elementType, sizeModifier,
indexQualifiers.getCVRQualifiers());
}]>;
}
let Class = VariableArrayType in {
def : Property<"leftBracketLoc", SourceLocation> {
let Read = [{ node->getLBracketLoc() }];
}
def : Property<"rightBracketLoc", SourceLocation> {
let Read = [{ node->getRBracketLoc() }];
}
def : Property<"size", ExprRef> {
let Read = [{ node->getSizeExpr() }];
}
def : Creator<[{
return ctx.getVariableArrayType(elementType, size, sizeModifier,
indexQualifiers.getCVRQualifiers(),
SourceRange(leftBracketLoc,
rightBracketLoc));
}]>;
}
let Class = DependentSizedArrayType in {
def : Property<"size", ExprRef> {
let Read = [{ node->getSizeExpr() }];
}
def : Property<"leftBracketLoc", SourceLocation> {
let Read = [{ node->getLBracketLoc() }];
}
def : Property<"rightBracketLoc", SourceLocation> {
let Read = [{ node->getRBracketLoc() }];
}
def : Creator<[{
return ctx.getDependentSizedArrayType(elementType, size, sizeModifier,
indexQualifiers.getCVRQualifiers(),
SourceRange(leftBracketLoc,
rightBracketLoc));
}]>;
}
let Class = VectorType in {
def : Property<"elementType", QualType> {
let Read = [{ node->getElementType() }];
}
def : Property<"numElements", UInt32> {
let Read = [{ node->getNumElements() }];
}
def : Property<"vectorKind", VectorKind> {
let Read = [{ node->getVectorKind() }];
}
def : Creator<[{
return ctx.getVectorType(elementType, numElements, vectorKind);
}]>;
}
let Class = DependentVectorType in {
def : Property<"elementType", QualType> {
let Read = [{ node->getElementType() }];
}
def : Property<"size", ExprRef> {
let Read = [{ node->getSizeExpr() }];
}
def : Property<"attributeLoc", SourceLocation> {
let Read = [{ node->getAttributeLoc() }];
}
def : Property<"vectorKind", VectorKind> {
let Read = [{ node->getVectorKind() }];
}
def : Creator<[{
return ctx.getDependentVectorType(elementType, size, attributeLoc,
vectorKind);
}]>;
}
let Class = ExtVectorType in {
def : Override {
let IgnoredProperties = [ "vectorKind" ];
}
def : Creator<[{
return ctx.getExtVectorType(elementType, numElements);
}]>;
}
let Class = DependentSizedExtVectorType in {
def : Property<"elementType", QualType> {
let Read = [{ node->getElementType() }];
}
def : Property<"size", ExprRef> {
let Read = [{ node->getSizeExpr() }];
}
def : Property<"attributeLoc", SourceLocation> {
let Read = [{ node->getAttributeLoc() }];
}
def : Creator<[{
return ctx.getDependentSizedExtVectorType(elementType, size, attributeLoc);
}]>;
}
let Class = FunctionType in {
def : Property<"returnType", QualType> {
let Read = [{ node->getReturnType() }];
}
def : Property<"noReturn", Bool> {
let Read = [{ node->getExtInfo().getNoReturn() }];
}
def : Property<"hasRegParm", Bool> {
let Read = [{ node->getExtInfo().getHasRegParm() }];
}
def : Property<"regParm", UInt32> {
let Read = [{ node->getExtInfo().getRegParm() }];
}
def : Property<"callingConvention", CallingConv> {
let Read = [{ node->getExtInfo().getCC() }];
}
def : Property<"producesResult", Bool> {
let Read = [{ node->getExtInfo().getProducesResult() }];
}
def : Property<"noCallerSavedRegs", Bool> {
let Read = [{ node->getExtInfo().getNoCallerSavedRegs() }];
}
def : Property<"noCfCheck", Bool> {
let Read = [{ node->getExtInfo().getNoCfCheck() }];
}
}
let Class = FunctionNoProtoType in {
def : Creator<[{
auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm,
callingConvention, producesResult,
noCallerSavedRegs, noCfCheck);
return ctx.getFunctionNoProtoType(returnType, extInfo);
}]>;
}
let Class = FunctionProtoType in {
def : Property<"variadic", Bool> {
let Read = [{ node->isVariadic() }];
}
def : Property<"trailingReturn", Bool> {
let Read = [{ node->hasTrailingReturn() }];
}
def : Property<"methodQualifiers", Qualifiers> {
let Read = [{ node->getMethodQuals() }];
}
def : Property<"refQualifier", RefQualifierKind> {
let Read = [{ node->getRefQualifier() }];
}
def : Property<"exceptionSpecifier", ExceptionSpecInfo> {
let Read = [{ node->getExceptionSpecInfo() }];
}
def : Property<"parameters", Array<QualType>> {
let Read = [{ node->getParamTypes() }];
}
def : Property<"extParameterInfo", Array<ExtParameterInfo>> {
let Read = [{ node->hasExtParameterInfos()
? node->getExtParameterInfos()
: llvm::ArrayRef<FunctionProtoType::ExtParameterInfo>() }];
}
def : Creator<[{
auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm,
callingConvention, producesResult,
noCallerSavedRegs, noCfCheck);
FunctionProtoType::ExtProtoInfo epi;
epi.ExtInfo = extInfo;
epi.Variadic = variadic;
epi.HasTrailingReturn = trailingReturn;
epi.TypeQuals = methodQualifiers;
epi.RefQualifier = refQualifier;
epi.ExceptionSpec = exceptionSpecifier;
epi.ExtParameterInfos =
extParameterInfo.empty() ? nullptr : extParameterInfo.data();
return ctx.getFunctionType(returnType, parameters, epi);
}]>;
}
let Class = AtomicType in {
def : Property<"valueType", QualType> {
let Read = [{ node->getValueType() }];
}
def : Creator<[{
return ctx.getAtomicType(valueType);
}]>;
}
let Class = UnresolvedUsingType in {
def : Property<"declaration", DeclRef> {
let Read = [{ node->getDecl() }];
}
def : Creator<[{
return ctx.getTypeDeclType(cast<UnresolvedUsingTypenameDecl>(declaration));
}]>;
}
let Class = TypedefType in {
def : Property<"declaration", DeclRef> {
let Read = [{ node->getDecl() }];
}
def : Property<"canonicalType", Optional<QualType>> {
let Read = [{ makeOptionalFromNullable(node->getCanonicalTypeInternal()) }];
}
def : Creator<[{
QualType finalCanonicalType =
canonicalType ? ctx.getCanonicalType(*canonicalType)
: QualType();
return ctx.getTypedefType(cast<TypedefNameDecl>(declaration),
finalCanonicalType);
}]>;
}
let Class = TypeOfExprType in {
def : Property<"expression", ExprRef> {
let Read = [{ node->getUnderlyingExpr() }];
}
def : Creator<[{
return ctx.getTypeOfExprType(expression);
}]>;
}
let Class = TypeOfType in {
def : Property<"underlyingType", QualType> {
let Read = [{ node->getUnderlyingType() }];
}
def : Creator<[{
return ctx.getTypeOfType(underlyingType);
}]>;
}
let Class = DecltypeType in {
def : Property<"underlyingType", QualType> {
let Read = [{ node->getUnderlyingType() }];
}
def : Property<"expression", ExprRef> {
let Read = [{ node->getUnderlyingExpr() }];
}
def : Creator<[{
return ctx.getDecltypeType(expression, underlyingType);
}]>;
}
let Class = UnaryTransformType in {
def : Property<"baseType", QualType> {
let Read = [{ node->getBaseType() }];
}
def : Property<"underlyingType", QualType> {
let Read = [{ node->getUnderlyingType() }];
}
def : Property<"transform", UnaryTypeTransformKind> {
let Read = [{ node->getUTTKind() }];
}
def : Creator<[{
return ctx.getUnaryTransformType(baseType, underlyingType, transform);
}]>;
}
let Class = AutoType in {
def : Property<"deducedType", Optional<QualType>> {
let Read = [{ makeOptionalFromNullable(node->getDeducedType()) }];
}
def : Property<"keyword", AutoTypeKeyword> {
let Read = [{ node->getKeyword() }];
}
// FIXME: better enumerated value
// Only really required when the deduced type is null
def : Property<"dependence", UInt32> {
let Read = [{ !node->getDeducedType().isNull() ? 0 :
node->containsUnexpandedParameterPack() ? 2 :
node->isDependentType() ? 1 : 0 }];
}
def : Creator<[{
return ctx.getAutoType(makeNullableFromOptional(deducedType), keyword,
/*isDependentWithoutDeducedType*/ dependence > 0,
/*isPackWithoutDeducedType*/ dependence > 1);
}]>;
}
let Class = DeducedTemplateSpecializationType in {
def : Property<"templateName", Optional<TemplateName>> {
let Read = [{ makeOptionalFromNullable(node->getTemplateName()) }];
}
def : Property<"deducedType", QualType> {
let Read = [{ node->getDeducedType() }];
}
// Only really required when the deduced type is null
def : Property<"dependent", Bool> {
let Read = [{ !node->getDeducedType().isNull()
? false : node->isDependentType() }];
}
def : Creator<[{
return ctx.getDeducedTemplateSpecializationType(
makeNullableFromOptional(templateName),
deducedType, dependent);
}]>;
}
let Class = TagType in {
def : Property<"dependent", Bool> {
let Read = [{ node->isDependentType() }];
}
def : Property<"declaration", DeclRef> {
// Serializing a reference to the canonical declaration is apparently
// necessary to make module-merging work.
let Read = [{ node->getDecl()->getCanonicalDecl() }];
}
}
let Class = EnumType in {
def : Creator<[{
QualType result = ctx.getEnumType(cast<EnumDecl>(declaration));
const_cast<Type*>(result.getTypePtr())->setDependent(dependent);
return result;
}]>;
}
let Class = RecordType in {
def : Creator<[{
auto record = cast<RecordDecl>(declaration);
QualType result = ctx.getRecordType(record);
const_cast<Type*>(result.getTypePtr())->setDependent(dependent);
return result;
}]>;
}
let Class = ElaboratedType in {
def : Property<"keyword", ElaboratedTypeKeyword> {
let Read = [{ node->getKeyword() }];
}
def : Property<"qualifier", NestedNameSpecifier> {
let Read = [{ node->getQualifier() }];
}
def : Property<"namedType", QualType> {
let Read = [{ node->getNamedType() }];
}
def : Property<"ownedTag", Optional<TagDeclRef>> {
let Read = [{ makeOptionalFromPointer(
const_cast<const TagDecl *>(node->getOwnedTagDecl())) }];
}
def : Creator<[{
return ctx.getElaboratedType(keyword, qualifier, namedType,
makePointerFromOptional(ownedTag));
}]>;
}
let Class = InjectedClassNameType in {
def : Property<"declaration", DeclRef> {
// FIXME: drilling down to the canonical declaration is what the
// existing serialization code was doing, but it's not clear why.
let Read = [{ node->getDecl()->getCanonicalDecl() }];
}
def : Property<"injectedSpecializationType", QualType> {
let Read = [{ node->getInjectedSpecializationType() }];
}
def : Creator<[{
// FIXME: ASTContext::getInjectedClassNameType is not currently suitable
// for AST reading, too much interdependencies.
const Type *T = nullptr;
auto typeDecl = cast<CXXRecordDecl>(declaration);
for (auto *DI = typeDecl; DI; DI = DI->getPreviousDecl()) {
if (const Type *existing = DI->getTypeForDecl()) {
T = existing;
break;
}
}
if (!T) {
T = new (ctx, TypeAlignment)
InjectedClassNameType(typeDecl, injectedSpecializationType);
for (auto *DI = typeDecl; DI; DI = DI->getPreviousDecl())
DI->setTypeForDecl(T);
}
return QualType(T, 0);
}]>;
}
let Class = ParenType in {
def : Property<"innerType", QualType> {
let Read = [{ node->getInnerType() }];
}
def : Creator<[{
return ctx.getParenType(innerType);
}]>;
}
let Class = MacroQualifiedType in {
def : Property<"underlyingType", QualType> {
let Read = [{ node->getUnderlyingType() }];
}
def : Property<"macroIdentifier", Identifier> {
let Read = [{ node->getMacroIdentifier() }];
}
def : Creator<[{
return ctx.getMacroQualifiedType(underlyingType, macroIdentifier);
}]>;
}
let Class = AttributedType in {
def : Property<"modifiedType", QualType> {
let Read = [{ node->getModifiedType() }];
}
def : Property<"equivalentType", QualType> {
let Read = [{ node->getEquivalentType() }];
}
def : Property<"attribute", AttrKind> {
let Read = [{ node->getAttrKind() }];
}
def : Creator<[{
return ctx.getAttributedType(attribute, modifiedType, equivalentType);
}]>;
}
let Class = DependentAddressSpaceType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
}
def : Property<"addressSpace", ExprRef> {
let Read = [{ node->getAddrSpaceExpr() }];
}
def : Property<"attributeLoc", SourceLocation> {
let Read = [{ node->getAttributeLoc() }];
}
def : Creator<[{
return ctx.getDependentAddressSpaceType(pointeeType, addressSpace,
attributeLoc);
}]>;
}
let Class = TemplateSpecializationType in {
def : Property<"dependent", Bool> {
let Read = [{ node->isDependentType() }];
}
def : Property<"templateName", TemplateName> {
let Read = [{ node->getTemplateName() }];
}
def : Property<"templateArguments", Array<TemplateArgument>> {
let Read = [{ node->template_arguments() }];
}
def : Property<"underlyingType", Optional<QualType>> {
let Read = [{
node->isTypeAlias()
? llvm::Optional<QualType>(node->getAliasedType())
: node->isCanonicalUnqualified()
? llvm::None
: llvm::Optional<QualType>(node->getCanonicalTypeInternal())
}];
}
def : Creator<[{
QualType result;
if (!underlyingType.hasValue()) {
result = ctx.getCanonicalTemplateSpecializationType(templateName,
templateArguments);
} else {
result = ctx.getTemplateSpecializationType(templateName,
templateArguments,
*underlyingType);
}
const_cast<Type*>(result.getTypePtr())->setDependent(dependent);
return result;
}]>;
}
let Class = DependentTemplateSpecializationType in {
def : Property<"keyword", ElaboratedTypeKeyword> {
let Read = [{ node->getKeyword() }];
}
def : Property<"qualifier", NestedNameSpecifier> {
let Read = [{ node->getQualifier() }];
}
def : Property<"name", Identifier> {
let Read = [{ node->getIdentifier() }];
}
def : Property<"templateArguments", Array<TemplateArgument>> {
let Read = [{ node->template_arguments() }];
}
def : Creator<[{
return ctx.getDependentTemplateSpecializationType(keyword, qualifier,
name, templateArguments);
}]>;
}
let Class = TemplateTypeParmType in {
def : Property<"depth", UInt32> {
let Read = [{ node->getDepth() }];
}
def : Property<"index", UInt32> {
let Read = [{ node->getIndex() }];
}
def : Property<"isParameterPack", Bool> {
let Read = [{ node->isParameterPack() }];
}
def : Property<"declaration", Optional<TemplateTypeParmDeclRef>> {
let Read = [{ makeOptionalFromPointer(
const_cast<const TemplateTypeParmDecl*>(node->getDecl())) }];
}
def : Creator<[{
return ctx.getTemplateTypeParmType(depth, index, isParameterPack,
makePointerFromOptional(declaration));
}]>;
}
let Class = SubstTemplateTypeParmType in {
def : Property<"replacedParameter", QualType> {
let Read = [{ QualType(node->getReplacedParameter(), 0) }];
}
def : Property<"replacementType", QualType> {
let Read = [{ node->getReplacementType() }];
}
def : Creator<[{
// The call to getCanonicalType here existed in ASTReader.cpp, too.
return ctx.getSubstTemplateTypeParmType(
cast<TemplateTypeParmType>(replacedParameter),
ctx.getCanonicalType(replacementType));
}]>;
}
let Class = PackExpansionType in {
def : Property<"pattern", QualType> {
let Read = [{ node->getPattern() }];
}
def : Property<"numExpansions", Optional<UInt32>> {
let Read = [{ node->getNumExpansions() }];
}
def : Creator<[{
return ctx.getPackExpansionType(pattern, numExpansions);
}]>;
}
let Class = SubstTemplateTypeParmPackType in {
def : Property<"replacedParameter", QualType> {
let Read = [{ QualType(node->getReplacedParameter(), 0) }];
}
def : Property<"replacementPack", TemplateArgument> {
let Read = [{ node->getArgumentPack() }];
}
def : Creator<[{
return ctx.getSubstTemplateTypeParmPackType(
cast<TemplateTypeParmType>(replacedParameter),
replacementPack);
}]>;
}
let Class = BuiltinType in {
def : Property<"kind", BuiltinTypeKind> {
let Read = [{ node->getKind() }];
}
def : Creator<[{
switch (kind) {
#define IMAGE_TYPE(IMGTYPE, ID, SINGLETON_ID, ACCESS, SUFFIX) \
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/Basic/OpenCLImageTypes.def"
#define EXT_OPAQUE_TYPE(EXTTYPE, ID, EXT) \
case BuiltinType::ID: return ctx.ID##Ty;
#include "clang/Basic/OpenCLExtensionTypes.def"
#define SVE_TYPE(NAME, ID, SINGLETON_ID) \
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/Basic/AArch64SVEACLETypes.def"
#define BUILTIN_TYPE(ID, SINGLETON_ID) \
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/AST/BuiltinTypes.def"
}
llvm_unreachable("unreachable builtin case");
}]>;
}
let Class = DependentNameType in {
def : Property<"keyword", ElaboratedTypeKeyword> {
let Read = [{ node->getKeyword() }];
}
def : Property<"qualifier", NestedNameSpecifier> {
let Read = [{ node->getQualifier() }];
}
def : Property<"name", Identifier> {
let Read = [{ node->getIdentifier() }];
}
def : Property<"underlyingType", Optional<QualType>> {
let Read = [{
node->isCanonicalUnqualified()
? llvm::None
: llvm::Optional<QualType>(node->getCanonicalTypeInternal())
}];
}
def : Creator<[{
QualType canon = (underlyingType
? ctx.getCanonicalType(*underlyingType)
: QualType());
return ctx.getDependentNameType(keyword, qualifier, name, canon);
}]>;
}
let Class = ObjCObjectType in {
def : Property<"baseType", QualType> {
let Read = [{ node->getBaseType() }];
}
def : Property<"typeArgsAsWritten", Array<QualType>> {
let Read = [{ node->getTypeArgsAsWritten() }];
}
def : Property<"qualifiers", Array<ObjCProtocolDeclRef>> {
let Read = [{ node->getProtocols() }];
}
def : Property<"isKindOfTypeAsWritten", Bool> {
let Read = [{ node->isKindOfTypeAsWritten() }];
}
def : Creator<[{
return ctx.getObjCObjectType(baseType, typeArgsAsWritten, qualifiers,
isKindOfTypeAsWritten);
}]>;
}
let Class = ObjCInterfaceType in {
// We don't actually want any of the properties of the superclass.
def : Override {
let IgnoredProperties = [ "baseType", "typeArgsAsWritten",
"qualifiers", "isKindOfTypeAsWritten" ];
}
def : Property<"declaration", DeclRef> {
// FIXME: drilling down to the canonical declaration is what the
// existing serialization code was doing, but it's not clear why.
let Read = [{ node->getDecl()->getCanonicalDecl() }];
}
def : Creator<[{
return ctx.getObjCInterfaceType(
cast<ObjCInterfaceDecl>(declaration->getCanonicalDecl()));
}]>;
}
let Class = ObjCTypeParamType in {
def : Property<"declaration", ObjCTypeParamDeclRef> {
let Read = [{ node->getDecl() }];
}
def : Property<"qualifiers", Array<ObjCProtocolDeclRef>> {
let Read = [{ node->getProtocols() }];
}
def : Creator<[{
return ctx.getObjCTypeParamType(declaration, qualifiers);
}]>;
}
let Class = ObjCObjectPointerType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
}
def : Creator<[{
return ctx.getObjCObjectPointerType(pointeeType);
}]>;
}
let Class = PipeType in {
def : Property<"elementType", QualType> {
let Read = [{ node->getElementType() }];
}
def : Property<"isReadOnly", Bool> {
let Read = [{ node->isReadOnly() }];
}
def : Creator<[{
return ctx.getPipeType(elementType, isReadOnly);
}]>;
}

View File

@ -17,6 +17,7 @@
#include "clang/AST/DeclAccessPair.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include <cstddef>
@ -85,6 +86,8 @@ class UnresolvedSetImpl {
const_iterator begin() const { return const_iterator(decls().begin()); }
const_iterator end() const { return const_iterator(decls().end()); }
ArrayRef<DeclAccessPair> pairs() const { return decls(); }
void addDecl(NamedDecl *D) {
addDecl(D, AS_none);
}
@ -125,6 +128,8 @@ class UnresolvedSetImpl {
void append(iterator I, iterator E) { decls().append(I.I, E.I); }
template<typename Iter> void assign(Iter I, Iter E) { decls().assign(I, E); }
DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }

View File

@ -309,6 +309,33 @@ match(MatcherT Matcher, ASTContext &Context) {
return std::move(Callback.Nodes);
}
inline SmallVector<BoundNodes, 1>
matchDynamic(internal::DynTypedMatcher Matcher,
const ast_type_traits::DynTypedNode &Node, ASTContext &Context) {
internal::CollectMatchesCallback Callback;
MatchFinder Finder;
Finder.addDynamicMatcher(Matcher, &Callback);
Finder.match(Node, Context);
return std::move(Callback.Nodes);
}
template <typename NodeT>
SmallVector<BoundNodes, 1> matchDynamic(internal::DynTypedMatcher Matcher,
const NodeT &Node,
ASTContext &Context) {
return matchDynamic(Matcher, ast_type_traits::DynTypedNode::create(Node),
Context);
}
inline SmallVector<BoundNodes, 1>
matchDynamic(internal::DynTypedMatcher Matcher, ASTContext &Context) {
internal::CollectMatchesCallback Callback;
MatchFinder Finder;
Finder.addDynamicMatcher(Matcher, &Callback);
Finder.matchAST(Context);
return std::move(Callback.Nodes);
}
} // end namespace ast_matchers
} // end namespace clang

View File

@ -55,6 +55,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/LambdaCapture.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/OperationKinds.h"
@ -689,6 +690,88 @@ AST_POLYMORPHIC_MATCHER_P(
Builder);
}
/// Causes all nested matchers to be matched with the specified traversal kind.
///
/// Given
/// \code
/// void foo()
/// {
/// int i = 3.0;
/// }
/// \endcode
/// The matcher
/// \code
/// traverse(ast_type_traits::TK_IgnoreImplicitCastsAndParentheses,
/// varDecl(hasInitializer(floatLiteral().bind("init")))
/// )
/// \endcode
/// matches the variable declaration with "init" bound to the "3.0".
template <typename T>
internal::Matcher<T> traverse(ast_type_traits::TraversalKind TK,
const internal::Matcher<T> &InnerMatcher) {
return internal::DynTypedMatcher::constructRestrictedWrapper(
new internal::TraversalMatcher<T>(TK, InnerMatcher),
InnerMatcher.getID().first)
.template unconditionalConvertTo<T>();
}
template <typename T>
internal::BindableMatcher<T>
traverse(ast_type_traits::TraversalKind TK,
const internal::BindableMatcher<T> &InnerMatcher) {
return internal::BindableMatcher<T>(
internal::DynTypedMatcher::constructRestrictedWrapper(
new internal::TraversalMatcher<T>(TK, InnerMatcher),
InnerMatcher.getID().first)
.template unconditionalConvertTo<T>());
}
template <typename... T>
internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>>
traverse(ast_type_traits::TraversalKind TK,
const internal::VariadicOperatorMatcher<T...> &InnerMatcher) {
return internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>>(
TK, InnerMatcher);
}
template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
typename T, typename ToTypes>
internal::TraversalWrapper<
internal::ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>>
traverse(ast_type_traits::TraversalKind TK,
const internal::ArgumentAdaptingMatcherFuncAdaptor<
ArgumentAdapterT, T, ToTypes> &InnerMatcher) {
return internal::TraversalWrapper<
internal::ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T,
ToTypes>>(TK, InnerMatcher);
}
template <template <typename T, typename P1> class MatcherT, typename P1,
typename ReturnTypesF>
internal::TraversalWrapper<
internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>>
traverse(
ast_type_traits::TraversalKind TK,
const internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>
&InnerMatcher) {
return internal::TraversalWrapper<
internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>>(
TK, InnerMatcher);
}
template <template <typename T, typename P1, typename P2> class MatcherT,
typename P1, typename P2, typename ReturnTypesF>
internal::TraversalWrapper<
internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>>
traverse(
ast_type_traits::TraversalKind TK,
const internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>
&InnerMatcher) {
return internal::TraversalWrapper<
internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>>(
TK, InnerMatcher);
}
/// Matches expressions that match InnerMatcher after any implicit AST
/// nodes are stripped off.
///
@ -2458,6 +2541,36 @@ extern const internal::VariadicOperatorMatcherFunc<
2, std::numeric_limits<unsigned>::max()>
allOf;
/// Matches any node regardless of the submatchers.
///
/// However, \c optionally will generate a result binding for each matching
/// submatcher.
///
/// Useful when additional information which may or may not present about a
/// main matching node is desired.
///
/// For example, in:
/// \code
/// class Foo {
/// int bar;
/// }
/// \endcode
/// The matcher:
/// \code
/// cxxRecordDecl(
/// optionally(has(
/// fieldDecl(hasName("bar")).bind("var")
/// ))).bind("record")
/// \endcode
/// will produce a result binding for both "record" and "var".
/// The matcher will produce a "record" binding for even if there is no data
/// member named "bar" in that class.
///
/// Usable as: Any Matcher
extern const internal::VariadicOperatorMatcherFunc<
1, std::numeric_limits<unsigned>::max()>
optionally;
/// Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
///
/// Given
@ -3932,6 +4045,50 @@ AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
return false;
}
/// Matches any capture of a lambda expression.
///
/// Given
/// \code
/// void foo() {
/// int x;
/// auto f = [x](){};
/// }
/// \endcode
/// lambdaExpr(hasAnyCapture(anything()))
/// matches [x](){};
AST_MATCHER_P_OVERLOAD(LambdaExpr, hasAnyCapture, internal::Matcher<VarDecl>,
InnerMatcher, 0) {
for (const LambdaCapture &Capture : Node.captures()) {
if (Capture.capturesVariable()) {
BoundNodesTreeBuilder Result(*Builder);
if (InnerMatcher.matches(*Capture.getCapturedVar(), Finder, &Result)) {
*Builder = std::move(Result);
return true;
}
}
}
return false;
}
/// Matches any capture of 'this' in a lambda expression.
///
/// Given
/// \code
/// struct foo {
/// void bar() {
/// auto f = [this](){};
/// }
/// }
/// \endcode
/// lambdaExpr(hasAnyCapture(cxxThisExpr()))
/// matches [this](){};
AST_MATCHER_P_OVERLOAD(LambdaExpr, hasAnyCapture,
internal::Matcher<CXXThisExpr>, InnerMatcher, 1) {
return llvm::any_of(Node.captures(), [](const LambdaCapture &LC) {
return LC.capturesThis();
});
}
/// Matches a constructor call expression which uses list initialization.
AST_MATCHER(CXXConstructExpr, isListInitialization) {
return Node.isListInitialization();
@ -4272,6 +4429,35 @@ AST_POLYMORPHIC_MATCHER(isConstexpr,
return Node.isConstexpr();
}
/// Matches selection statements with initializer.
///
/// Given:
/// \code
/// void foo() {
/// if (int i = foobar(); i > 0) {}
/// switch (int i = foobar(); i) {}
/// for (auto& a = get_range(); auto& x : a) {}
/// }
/// void bar() {
/// if (foobar() > 0) {}
/// switch (foobar()) {}
/// for (auto& x : get_range()) {}
/// }
/// \endcode
/// ifStmt(hasInitStatement(anything()))
/// matches the if statement in foo but not in bar.
/// switchStmt(hasInitStatement(anything()))
/// matches the switch statement in foo but not in bar.
/// cxxForRangeStmt(hasInitStatement(anything()))
/// matches the range for statement in foo but not in bar.
AST_POLYMORPHIC_MATCHER_P(hasInitStatement,
AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, SwitchStmt,
CXXForRangeStmt),
internal::Matcher<Stmt>, InnerMatcher) {
const Stmt *Init = Node.getInit();
return Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder);
}
/// Matches the condition expression of an if statement, for loop,
/// switch statement or conditional operator.
///
@ -6519,6 +6705,20 @@ AST_MATCHER(NamedDecl, hasExternalFormalLinkage) {
/// void x(int val) {}
/// void y(int val = 0) {}
/// \endcode
///
/// Deprecated. Use hasInitializer() instead to be able to
/// match on the contents of the default argument. For example:
///
/// \code
/// void x(int val = 7) {}
/// void y(int val = 42) {}
/// \endcode
/// parmVarDecl(hasInitializer(integerLiteral(equals(42))))
/// matches the parameter of y
///
/// A matcher such as
/// parmVarDecl(hasInitializer(anything()))
/// is equivalent to parmVarDecl(hasDefaultArgument()).
AST_MATCHER(ParmVarDecl, hasDefaultArgument) {
return Node.hasDefaultArg();
}
@ -6541,7 +6741,7 @@ AST_MATCHER(CXXNewExpr, isArray) {
/// \code
/// MyClass *p1 = new MyClass[10];
/// \endcode
/// cxxNewExpr(hasArraySize(intgerLiteral(equals(10))))
/// cxxNewExpr(hasArraySize(integerLiteral(equals(10))))
/// matches the expression 'new MyClass[10]'.
AST_MATCHER_P(CXXNewExpr, hasArraySize, internal::Matcher<Expr>, InnerMatcher) {
return Node.isArray() && *Node.getArraySize() &&
@ -6621,8 +6821,8 @@ AST_MATCHER_P(Expr, ignoringElidableConstructorCall,
if (CtorExpr->isElidable()) {
if (const auto *MaterializeTemp =
dyn_cast<MaterializeTemporaryExpr>(CtorExpr->getArg(0))) {
return InnerMatcher.matches(*MaterializeTemp->GetTemporaryExpr(),
Finder, Builder);
return InnerMatcher.matches(*MaterializeTemp->getSubExpr(), Finder,
Builder);
}
}
}
@ -6781,7 +6981,9 @@ AST_MATCHER(OMPDefaultClause, isSharedKind) {
/// ``isAllowedToContainClauseKind("OMPC_default").``
AST_MATCHER_P(OMPExecutableDirective, isAllowedToContainClauseKind,
OpenMPClauseKind, CKind) {
return isAllowedClauseForDirective(Node.getDirectiveKind(), CKind);
return isAllowedClauseForDirective(
Node.getDirectiveKind(), CKind,
Finder->getASTContext().getLangOpts().OpenMP);
}
//----------------------------------------------------------------------------//

View File

@ -283,6 +283,10 @@ class DynMatcherInterface
virtual bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const = 0;
virtual llvm::Optional<ast_type_traits::TraversalKind> TraversalKind() const {
return llvm::None;
}
};
/// Generic interface for matchers on an AST node of type T.
@ -359,6 +363,10 @@ class DynTypedMatcher {
/// matches, but doesn't stop at the first match.
VO_EachOf,
/// Matches any node but executes all inner matchers to find result
/// bindings.
VO_Optionally,
/// Matches nodes that do not match the provided matcher.
///
/// Uses the variadic matcher interface, but fails if
@ -371,6 +379,10 @@ class DynTypedMatcher {
ast_type_traits::ASTNodeKind SupportedKind,
std::vector<DynTypedMatcher> InnerMatchers);
static DynTypedMatcher
constructRestrictedWrapper(const DynTypedMatcher &InnerMatcher,
ast_type_traits::ASTNodeKind RestrictKind);
/// Get a "true" matcher for \p NodeKind.
///
/// It only checks that the node is of the right kind.
@ -1002,7 +1014,7 @@ class ASTMatchFinder {
std::is_base_of<QualType, T>::value,
"unsupported type for recursive matching");
return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
Matcher, Builder, Traverse, Bind);
getASTContext(), Matcher, Builder, Traverse, Bind);
}
template <typename T>
@ -1018,7 +1030,7 @@ class ASTMatchFinder {
std::is_base_of<QualType, T>::value,
"unsupported type for recursive matching");
return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node),
Matcher, Builder, Bind);
getASTContext(), Matcher, Builder, Bind);
}
// FIXME: Implement support for BindKind.
@ -1033,24 +1045,26 @@ class ASTMatchFinder {
std::is_base_of<TypeLoc, T>::value,
"type not allowed for recursive matching");
return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node),
Matcher, Builder, MatchMode);
getASTContext(), Matcher, Builder, MatchMode);
}
virtual ASTContext &getASTContext() const = 0;
protected:
virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
const DynTypedMatcher &Matcher,
ASTContext &Ctx, const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
ast_type_traits::TraversalKind Traverse,
BindKind Bind) = 0;
virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
BindKind Bind) = 0;
virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
AncestorMatchMode MatchMode) = 0;
@ -1119,6 +1133,23 @@ using HasDeclarationSupportedTypes =
TemplateSpecializationType, TemplateTypeParmType, TypedefType,
UnresolvedUsingType, ObjCIvarRefExpr>;
template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
typename T, typename ToTypes>
class ArgumentAdaptingMatcherFuncAdaptor {
public:
explicit ArgumentAdaptingMatcherFuncAdaptor(const Matcher<T> &InnerMatcher)
: InnerMatcher(InnerMatcher) {}
using ReturnTypes = ToTypes;
template <typename To> operator Matcher<To>() const {
return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
}
private:
const Matcher<T> InnerMatcher;
};
/// Converts a \c Matcher<T> to a matcher of desired type \c To by
/// "adapting" a \c To into a \c T.
///
@ -1136,32 +1167,60 @@ template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
typename FromTypes = AdaptativeDefaultFromTypes,
typename ToTypes = AdaptativeDefaultToTypes>
struct ArgumentAdaptingMatcherFunc {
template <typename T> class Adaptor {
public:
explicit Adaptor(const Matcher<T> &InnerMatcher)
: InnerMatcher(InnerMatcher) {}
using ReturnTypes = ToTypes;
template <typename To> operator Matcher<To>() const {
return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
}
private:
const Matcher<T> InnerMatcher;
};
template <typename T>
static Adaptor<T> create(const Matcher<T> &InnerMatcher) {
return Adaptor<T>(InnerMatcher);
static ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>
create(const Matcher<T> &InnerMatcher) {
return ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>(
InnerMatcher);
}
template <typename T>
Adaptor<T> operator()(const Matcher<T> &InnerMatcher) const {
ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>
operator()(const Matcher<T> &InnerMatcher) const {
return create(InnerMatcher);
}
};
template <typename T>
class TraversalMatcher : public WrapperMatcherInterface<T> {
ast_type_traits::TraversalKind Traversal;
public:
explicit TraversalMatcher(ast_type_traits::TraversalKind TK,
const Matcher<T> &ChildMatcher)
: TraversalMatcher::WrapperMatcherInterface(ChildMatcher), Traversal(TK) {
}
bool matches(const T &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const override {
return this->InnerMatcher.matches(
ast_type_traits::DynTypedNode::create(Node), Finder, Builder);
}
llvm::Optional<ast_type_traits::TraversalKind>
TraversalKind() const override {
return Traversal;
}
};
template <typename MatcherType> class TraversalWrapper {
public:
TraversalWrapper(ast_type_traits::TraversalKind TK,
const MatcherType &InnerMatcher)
: TK(TK), InnerMatcher(InnerMatcher) {}
template <typename T> operator Matcher<T>() const {
return internal::DynTypedMatcher::constructRestrictedWrapper(
new internal::TraversalMatcher<T>(TK, InnerMatcher),
ast_type_traits::ASTNodeKind::getFromNodeKind<T>())
.template unconditionalConvertTo<T>();
}
private:
ast_type_traits::TraversalKind TK;
MatcherType InnerMatcher;
};
/// A PolymorphicMatcherWithParamN<MatcherT, P1, ..., PN> object can be
/// created from N parameters p1, ..., pN (of type P1, ..., PN) and
/// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN)

View File

@ -164,16 +164,14 @@ class Parser {
/// description of the error.
/// The caller takes ownership of the DynTypedMatcher object returned.
static llvm::Optional<DynTypedMatcher>
parseMatcherExpression(StringRef MatcherCode, Sema *S,
const NamedValueMap *NamedValues,
Diagnostics *Error);
parseMatcherExpression(StringRef &MatcherCode, Sema *S,
const NamedValueMap *NamedValues, Diagnostics *Error);
static llvm::Optional<DynTypedMatcher>
parseMatcherExpression(StringRef MatcherCode, Sema *S,
Diagnostics *Error) {
parseMatcherExpression(StringRef &MatcherCode, Sema *S, Diagnostics *Error) {
return parseMatcherExpression(MatcherCode, S, nullptr, Error);
}
static llvm::Optional<DynTypedMatcher>
parseMatcherExpression(StringRef MatcherCode, Diagnostics *Error) {
parseMatcherExpression(StringRef &MatcherCode, Diagnostics *Error) {
return parseMatcherExpression(MatcherCode, nullptr, Error);
}
@ -189,14 +187,14 @@ class Parser {
/// \param NamedValues A map of precomputed named values. This provides
/// the dictionary for the <NamedValue> rule of the grammar.
/// If null, it is ignored.
static bool parseExpression(StringRef Code, Sema *S,
static bool parseExpression(StringRef &Code, Sema *S,
const NamedValueMap *NamedValues,
VariantValue *Value, Diagnostics *Error);
static bool parseExpression(StringRef Code, Sema *S,
VariantValue *Value, Diagnostics *Error) {
static bool parseExpression(StringRef &Code, Sema *S, VariantValue *Value,
Diagnostics *Error) {
return parseExpression(Code, S, nullptr, Value, Error);
}
static bool parseExpression(StringRef Code, VariantValue *Value,
static bool parseExpression(StringRef &Code, VariantValue *Value,
Diagnostics *Error) {
return parseExpression(Code, nullptr, Value, Error);
}
@ -213,14 +211,14 @@ class Parser {
/// \return The list of completions, which may be empty if there are no
/// available completions or if an error occurred.
static std::vector<MatcherCompletion>
completeExpression(StringRef Code, unsigned CompletionOffset, Sema *S,
completeExpression(StringRef &Code, unsigned CompletionOffset, Sema *S,
const NamedValueMap *NamedValues);
static std::vector<MatcherCompletion>
completeExpression(StringRef Code, unsigned CompletionOffset, Sema *S) {
completeExpression(StringRef &Code, unsigned CompletionOffset, Sema *S) {
return completeExpression(Code, CompletionOffset, S, nullptr);
}
static std::vector<MatcherCompletion>
completeExpression(StringRef Code, unsigned CompletionOffset) {
completeExpression(StringRef &Code, unsigned CompletionOffset) {
return completeExpression(Code, CompletionOffset, nullptr);
}

View File

@ -1248,9 +1248,11 @@ class CFG {
bool AddStaticInitBranches = false;
bool AddCXXNewAllocator = false;
bool AddCXXDefaultInitExprInCtors = false;
bool AddCXXDefaultInitExprInAggregates = false;
bool AddRichCXXConstructors = false;
bool MarkElidedCXXConstructors = false;
bool AddVirtualBaseBranches = false;
bool OmitImplicitValueInitializers = false;
BuildOptions() = default;

View File

@ -0,0 +1,8 @@
#ifndef AST_NODE_TD
#define AST_NODE_TD
class HasProperties;
class ASTNode : HasProperties;
class AttrSubject;
#endif

View File

@ -42,6 +42,11 @@ enum class LangAS : unsigned {
cuda_constant,
cuda_shared,
// Pointer size and extension address spaces.
ptr32_sptr,
ptr32_uptr,
ptr64,
// This denotes the count of language-specific address spaces and also
// the offset added to the target-specific address spaces, which are usually
// specified by address space attributes __attribute__(address_space(n))).
@ -68,6 +73,11 @@ inline LangAS getLangASFromTargetAS(unsigned TargetAS) {
(unsigned)LangAS::FirstTargetAddressSpace);
}
inline bool isPtrSizeAddressSpace(LangAS AS) {
return (AS == LangAS::ptr32_sptr || AS == LangAS::ptr32_uptr ||
AS == LangAS::ptr64);
}
} // namespace clang
#endif // LLVM_CLANG_BASIC_ADDRESSSPACES_H

View File

@ -121,6 +121,11 @@ def GlobalVar : SubsetSubject<Var,
def InlineFunction : SubsetSubject<Function,
[{S->isInlineSpecified()}], "inline functions">;
def FunctionTmpl
: SubsetSubject<Function, [{S->getTemplatedKind() ==
FunctionDecl::TK_FunctionTemplate}],
"function templates">;
// FIXME: this hack is needed because DeclNodes.td defines the base Decl node
// type to be a class, not a definition. This makes it impossible to create an
// attribute subject which accepts a Decl. Normally, this is not a problem,
@ -173,8 +178,8 @@ class FunctionArgument<string name, bit opt = 0, bit fake = 0> : Argument<name,
opt,
fake>;
class NamedArgument<string name, bit opt = 0, bit fake = 0> : Argument<name,
opt,
fake>;
opt,
fake>;
class TypeArgument<string name, bit opt = 0> : Argument<name, opt>;
class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>;
class VariadicUnsignedArgument<string name> : Argument<name, 1>;
@ -296,6 +301,7 @@ def MicrosoftExt : LangOpt<"MicrosoftExt">;
def Borland : LangOpt<"Borland">;
def CUDA : LangOpt<"CUDA">;
def HIP : LangOpt<"HIP">;
def SYCL : LangOpt<"SYCLIsDevice">;
def COnly : LangOpt<"COnly", "!LangOpts.CPlusPlus">;
def CPlusPlus : LangOpt<"CPlusPlus">;
def OpenCL : LangOpt<"OpenCL">;
@ -332,6 +338,7 @@ class TargetArch<list<string> arches> : TargetSpec {
}
def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>;
def TargetAVR : TargetArch<["avr"]>;
def TargetBPF : TargetArch<["bpfel", "bpfeb"]>;
def TargetMips32 : TargetArch<["mips", "mipsel"]>;
def TargetAnyMips : TargetArch<["mips", "mipsel", "mips64", "mips64el"]>;
def TargetMSP430 : TargetArch<["msp430"]>;
@ -594,6 +601,13 @@ def Alias : Attr {
let Documentation = [Undocumented];
}
def ArmMveAlias : InheritableAttr, TargetSpecificAttr<TargetARM> {
let Spellings = [Clang<"__clang_arm_mve_alias">];
let Args = [IdentifierArgument<"BuiltinName">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [ArmMveAliasDocs];
}
def Aligned : InheritableAttr {
let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">,
Keyword<"_Alignas">];
@ -669,6 +683,15 @@ def XRayLogArgs : InheritableAttr {
let Documentation = [XRayDocs];
}
def PatchableFunctionEntry
: InheritableAttr,
TargetSpecificAttr<TargetArch<["aarch64", "x86", "x86_64"]>> {
let Spellings = [GCC<"patchable_function_entry">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>];
let Documentation = [PatchableFunctionEntryDocs];
}
def TLSModel : InheritableAttr {
let Spellings = [GCC<"tls_model">];
let Subjects = SubjectList<[TLSVar], ErrorDiag>;
@ -1048,6 +1071,13 @@ def CUDAShared : InheritableAttr {
let Documentation = [Undocumented];
}
def SYCLKernel : InheritableAttr {
let Spellings = [Clang<"sycl_kernel">];
let Subjects = SubjectList<[FunctionTmpl]>;
let LangOpts = [SYCL];
let Documentation = [SYCLKernelDocs];
}
def C11NoReturn : InheritableAttr {
let Spellings = [Keyword<"_Noreturn">];
let Subjects = SubjectList<[Function], ErrorDiag>;
@ -1099,27 +1129,27 @@ def OpenCLAccess : Attr {
}
def OpenCLPrivateAddressSpace : TypeAttr {
let Spellings = [Keyword<"__private">, Keyword<"private">];
let Spellings = [Keyword<"__private">, Keyword<"private">, Clang<"opencl_private">];
let Documentation = [OpenCLAddressSpacePrivateDocs];
}
def OpenCLGlobalAddressSpace : TypeAttr {
let Spellings = [Keyword<"__global">, Keyword<"global">];
let Spellings = [Keyword<"__global">, Keyword<"global">, Clang<"opencl_global">];
let Documentation = [OpenCLAddressSpaceGlobalDocs];
}
def OpenCLLocalAddressSpace : TypeAttr {
let Spellings = [Keyword<"__local">, Keyword<"local">];
let Spellings = [Keyword<"__local">, Keyword<"local">, Clang<"opencl_local">];
let Documentation = [OpenCLAddressSpaceLocalDocs];
}
def OpenCLConstantAddressSpace : TypeAttr {
let Spellings = [Keyword<"__constant">, Keyword<"constant">];
let Spellings = [Keyword<"__constant">, Keyword<"constant">, Clang<"opencl_constant">];
let Documentation = [OpenCLAddressSpaceConstantDocs];
}
def OpenCLGenericAddressSpace : TypeAttr {
let Spellings = [Keyword<"__generic">, Keyword<"generic">];
let Spellings = [Keyword<"__generic">, Keyword<"generic">, Clang<"opencl_generic">];
let Documentation = [OpenCLAddressSpaceGenericDocs];
}
@ -1571,6 +1601,22 @@ def AMDGPUNumVGPR : InheritableAttr {
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}
def BPFPreserveAccessIndex : InheritableAttr,
TargetSpecificAttr<TargetBPF> {
let Spellings = [Clang<"preserve_access_index">];
let Subjects = SubjectList<[Record], ErrorDiag>;
let Documentation = [BPFPreserveAccessIndexDocs];
let LangOpts = [COnly];
}
def WebAssemblyExportName : InheritableAttr,
TargetSpecificAttr<TargetWebAssembly> {
let Spellings = [Clang<"export_name">];
let Args = [StringArgument<"ExportName">];
let Documentation = [WebAssemblyExportNameDocs];
let Subjects = SubjectList<[Function], ErrorDiag>;
}
def WebAssemblyImportModule : InheritableAttr,
TargetSpecificAttr<TargetWebAssembly> {
let Spellings = [Clang<"import_module">];
@ -1845,6 +1891,20 @@ def ObjCDesignatedInitializer : Attr {
let Documentation = [Undocumented];
}
def ObjCDirect : Attr {
let Spellings = [Clang<"objc_direct">];
let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
let LangOpts = [ObjC];
let Documentation = [ObjCDirectDocs];
}
def ObjCDirectMembers : Attr {
let Spellings = [Clang<"objc_direct_members">];
let Subjects = SubjectList<[ObjCImpl, ObjCCategory], ErrorDiag>;
let LangOpts = [ObjC];
let Documentation = [ObjCDirectMembersDocs];
}
def ObjCRuntimeName : Attr {
let Spellings = [Clang<"objc_runtime_name">];
let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag>;
@ -2119,15 +2179,6 @@ def Target : InheritableAttr {
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [TargetDocs];
let AdditionalMembers = [{
struct ParsedTargetAttr {
std::vector<std::string> Features;
StringRef Architecture;
bool DuplicateArchitecture = false;
bool operator ==(const ParsedTargetAttr &Other) const {
return DuplicateArchitecture == Other.DuplicateArchitecture &&
Architecture == Other.Architecture && Features == Other.Features;
}
};
ParsedTargetAttr parse() const {
return parse(getFeaturesStr());
}
@ -2194,6 +2245,11 @@ def Target : InheritableAttr {
if (Feature.startswith("fpmath=") || Feature.startswith("tune="))
continue;
if (Feature.startswith("branch-protection=")) {
Ret.BranchProtection = Feature.split('=').second.trim();
continue;
}
// While we're here iterating check for a different target cpu.
if (Feature.startswith("arch=")) {
if (!Ret.Architecture.empty())
@ -2860,6 +2916,15 @@ def MSAllocator : InheritableAttr {
let Documentation = [MSAllocatorDocs];
}
def CFGuard : InheritableAttr {
// Currently only the __declspec(guard(nocf)) modifier is supported. In future
// we might also want to support __declspec(guard(suppress)).
let Spellings = [Declspec<"guard">];
let Subjects = SubjectList<[Function]>;
let Args = [EnumArgument<"Guard", "GuardArg", ["nocf"], ["nocf"]>];
let Documentation = [CFGuardDocs];
}
def MSStruct : InheritableAttr {
let Spellings = [GCC<"ms_struct">];
let Subjects = SubjectList<[Record]>;
@ -2928,22 +2993,22 @@ def Win64 : IgnoredAttr {
def Ptr32 : TypeAttr {
let Spellings = [Keyword<"__ptr32">];
let Documentation = [Undocumented];
let Documentation = [Ptr32Docs];
}
def Ptr64 : TypeAttr {
let Spellings = [Keyword<"__ptr64">];
let Documentation = [Undocumented];
let Documentation = [Ptr64Docs];
}
def SPtr : TypeAttr {
let Spellings = [Keyword<"__sptr">];
let Documentation = [Undocumented];
let Documentation = [SPtrDocs];
}
def UPtr : TypeAttr {
let Spellings = [Keyword<"__uptr">];
let Documentation = [Undocumented];
let Documentation = [UPtrDocs];
}
def MSInheritance : InheritableAttr {
@ -2954,25 +3019,9 @@ def MSInheritance : InheritableAttr {
Keyword<"__virtual_inheritance">,
Keyword<"__unspecified_inheritance">];
let AdditionalMembers = [{
static bool hasVBPtrOffsetField(Spelling Inheritance) {
return Inheritance == Keyword_unspecified_inheritance;
}
// Only member pointers to functions need a this adjustment, since it can be
// combined with the field offset for data pointers.
static bool hasNVOffsetField(bool IsMemberFunction, Spelling Inheritance) {
return IsMemberFunction && Inheritance >= Keyword_multiple_inheritance;
}
static bool hasVBTableOffsetField(Spelling Inheritance) {
return Inheritance >= Keyword_virtual_inheritance;
}
static bool hasOnlyOneField(bool IsMemberFunction,
Spelling Inheritance) {
if (IsMemberFunction)
return Inheritance <= Keyword_single_inheritance;
return Inheritance <= Keyword_multiple_inheritance;
MSInheritanceModel getInheritanceModel() const {
// The spelling enum should agree with MSInheritanceModel.
return MSInheritanceModel(getSemanticSpelling());
}
}];
let Documentation = [MSInheritanceDocs];
@ -2985,13 +3034,7 @@ def MSVtorDisp : InheritableAttr {
let SemaHandler = 0;
let AdditionalMembers = [{
enum Mode {
Never,
ForVBaseOverride,
ForVFTable
};
Mode getVtorDispMode() const { return Mode(vdm); }
MSVtorDispMode getVtorDispMode() const { return MSVtorDispMode(vdm); }
}];
let Documentation = [Undocumented];
}
@ -3298,30 +3341,15 @@ def OMPDeclareVariant : InheritableAttr {
let Documentation = [OMPDeclareVariantDocs];
let Args = [
ExprArgument<"VariantFuncRef">,
ExprArgument<"Score">,
EnumArgument<"CtxSelectorSet", "CtxSelectorSetType",
[ "", "implementation"
],
[
"CtxSetUnknown", "CtxSetImplementation"
]>,
EnumArgument<"CtxScore", "ScoreType",
[ "", "score"
],
[
"ScoreUnknown", "ScoreSpecified"
]>,
EnumArgument<"CtxSelector", "CtxSelectorType",
[ "", "vendor"
],
[
"CtxUnknown", "CtxVendor"
]>,
VariadicStringArgument<"ImplVendors">
VariadicExprArgument<"Scores">,
VariadicUnsignedArgument<"CtxSelectorSets">,
VariadicUnsignedArgument<"CtxSelectors">,
VariadicStringArgument<"ImplVendors">,
VariadicStringArgument<"DeviceKinds">
];
let AdditionalMembers = [{
void printScore(raw_ostream & OS, const PrintingPolicy &Policy) const {
if (const Expr *E = getScore()) {
void printScore(raw_ostream & OS, const PrintingPolicy &Policy, unsigned I) const {
if (const Expr *E = *std::next(scores_begin(), I)) {
OS << "score(";
E->printPretty(OS, nullptr, Policy);
OS << "):";
@ -3329,8 +3357,6 @@ def OMPDeclareVariant : InheritableAttr {
}
void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy)
const {
assert(getCtxSelectorSet() != CtxSetUnknown &&
getCtxSelector() != CtxUnknown && "Unknown context selector.");
if (const Expr *E = getVariantFuncRef()) {
OS << "(";
E->printPretty(OS, nullptr, Policy);
@ -3338,27 +3364,63 @@ def OMPDeclareVariant : InheritableAttr {
}
// TODO: add printing of real context selectors.
OS << " match(";
switch (getCtxSelectorSet()) {
case CtxSetImplementation:
OS << "implementation={";
switch (getCtxSelector()) {
case CtxVendor:
OS << "vendor(";
printScore(OS, Policy);
if (implVendors_size() > 0) {
OS << *implVendors(). begin();
for (StringRef VendorName : llvm::drop_begin(implVendors(), 1))
OS << ", " << VendorName;
}
OS << ")";
int Used[OMP_CTX_SET_unknown] = {0};
for (unsigned I = 0, E = ctxSelectorSets_size(); I < E; ++I) {
auto CtxSet = static_cast<OpenMPContextSelectorSetKind>(
*std::next(ctxSelectorSets_begin(), I));
if (Used[CtxSet])
continue;
if (I > 0)
OS << ",";
switch (CtxSet) {
case OMP_CTX_SET_implementation:
OS << "implementation={";
break;
case CtxUnknown:
llvm_unreachable("Unknown context selector.");
case OMP_CTX_SET_device:
OS << "device={";
break;
case OMP_CTX_SET_unknown:
llvm_unreachable("Unknown context selector set.");
}
Used[CtxSet] = 1;
for (unsigned K = I, EK = ctxSelectors_size(); K < EK; ++K) {
auto CtxSetK = static_cast<OpenMPContextSelectorSetKind>(
*std::next(ctxSelectorSets_begin(), K));
if (CtxSet != CtxSetK)
continue;
if (K != I)
OS << ",";
auto Ctx = static_cast<OpenMPContextSelectorKind>(
*std::next(ctxSelectors_begin(), K));
switch (Ctx) {
case OMP_CTX_vendor:
assert(CtxSet == OMP_CTX_SET_implementation &&
"Expected implementation context selector set.");
OS << "vendor(";
printScore(OS, Policy, K);
if (implVendors_size() > 0) {
OS << *implVendors(). begin();
for (StringRef VendorName : llvm::drop_begin(implVendors(), 1))
OS << ", " << VendorName;
}
OS << ")";
break;
case OMP_CTX_kind:
assert(CtxSet == OMP_CTX_SET_device &&
"Expected device context selector set.");
OS << "kind(";
if (deviceKinds_size() > 0) {
OS << *deviceKinds().begin();
for (StringRef KindName : llvm::drop_begin(deviceKinds(), 1))
OS << ", " << KindName;
}
OS << ")";
break;
case OMP_CTX_unknown:
llvm_unreachable("Unknown context selector.");
}
}
OS << "}";
break;
case CtxSetUnknown:
llvm_unreachable("Unknown context selector set.");
}
OS << ")";
}
@ -3420,3 +3482,34 @@ def ObjCExternallyRetained : InheritableAttr {
let Subjects = SubjectList<[NonParmVar, Function, Block, ObjCMethod]>;
let Documentation = [ObjCExternallyRetainedDocs];
}
def NoBuiltin : Attr {
let Spellings = [Clang<"no_builtin">];
let Args = [VariadicStringArgument<"BuiltinNames">];
let Subjects = SubjectList<[Function]>;
let Documentation = [NoBuiltinDocs];
}
// FIXME: This attribute is not inheritable, it will not be propagated to
// redecls. [[clang::lifetimebound]] has the same problems. This should be
// fixed in TableGen (by probably adding a new inheritable flag).
def AcquireHandle : DeclOrTypeAttr {
let Spellings = [Clang<"acquire_handle">];
let Args = [StringArgument<"HandleType">];
let Subjects = SubjectList<[Function, TypedefName, ParmVar]>;
let Documentation = [AcquireHandleDocs];
}
def UseHandle : InheritableParamAttr {
let Spellings = [Clang<"use_handle">];
let Args = [StringArgument<"HandleType">];
let Subjects = SubjectList<[ParmVar]>;
let Documentation = [UseHandleDocs];
}
def ReleaseHandle : InheritableParamAttr {
let Spellings = [Clang<"release_handle">];
let Args = [StringArgument<"HandleType">];
let Subjects = SubjectList<[ParmVar]>;
let Documentation = [ReleaseHandleDocs];
}

View File

@ -253,12 +253,87 @@ any option of a multiversioned function is undefined.
}];
}
def SYCLKernelDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``sycl_kernel`` attribute specifies that a function template will be used
to outline device code and to generate an OpenCL kernel.
Here is a code example of the SYCL program, which demonstrates the compiler's
outlining job:
.. code-block:: c++
int foo(int x) { return ++x; }
using namespace cl::sycl;
queue Q;
buffer<int, 1> a(range<1>{1024});
Q.submit([&](handler& cgh) {
auto A = a.get_access<access::mode::write>(cgh);
cgh.parallel_for<init_a>(range<1>{1024}, [=](id<1> index) {
A[index] = index[0] + foo(42);
});
}
A C++ function object passed to the ``parallel_for`` is called a "SYCL kernel".
A SYCL kernel defines the entry point to the "device part" of the code. The
compiler will emit all symbols accessible from a "kernel". In this code
example, the compiler will emit "foo" function. More details about the
compilation of functions for the device part can be found in the SYCL 1.2.1
specification Section 6.4.
To show to the compiler entry point to the "device part" of the code, the SYCL
runtime can use the ``sycl_kernel`` attribute in the following way:
.. code-block:: c++
namespace cl {
namespace sycl {
class handler {
template <typename KernelName, typename KernelType/*, ...*/>
__attribute__((sycl_kernel)) void sycl_kernel_function(KernelType KernelFuncObj) {
// ...
KernelFuncObj();
}
template <typename KernelName, typename KernelType, int Dims>
void parallel_for(range<Dims> NumWorkItems, KernelType KernelFunc) {
#ifdef __SYCL_DEVICE_ONLY__
sycl_kernel_function<KernelName, KernelType, Dims>(KernelFunc);
#else
// Host implementation
#endif
}
};
} // namespace sycl
} // namespace cl
The compiler will also generate an OpenCL kernel using the function marked with
the ``sycl_kernel`` attribute.
Here is the list of SYCL device compiler expectations with regard to the
function marked with the ``sycl_kernel`` attribute:
- The function must be a template with at least two type template parameters.
The compiler generates an OpenCL kernel and uses the first template parameter
as a unique name for the generated OpenCL kernel. The host application uses
this unique name to invoke the OpenCL kernel generated for the SYCL kernel
specialized by this name and second template parameter ``KernelType`` (which
might be an unnamed function object type).
- The function must have at least one parameter. The first parameter is
required to be a function object type (named or unnamed i.e. lambda). The
compiler uses function object type fields to generate OpenCL kernel
parameters.
- The function must return void. The compiler reuses the body of marked functions to
generate the OpenCL kernel body, and the OpenCL kernel must return `void`.
The SYCL kernel in the previous code sample meets these expectations.
}];
}
def C11NoReturnDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
A function declared as ``_Noreturn`` shall not return to its caller. The
compiler will generate a diagnostic for a function declared as ``_Noreturn``
that appears to be capable of returning to its caller.
that appears to be capable of returning to its caller. Despite being a type
specifier, the ``_Noreturn`` attribute cannot be specified on a function
pointer type.
}];
}
@ -1632,6 +1707,17 @@ The semantics are as follows:
}];
}
def BPFPreserveAccessIndexDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Clang supports the ``__attribute__((preserve_access_index))``
attribute for the BPF target. This attribute may be attached to a
struct or union declaration, where if -g is specified, it enables
preserving struct or union member access debuginfo indicies of this
struct or union, similar to clang ``__builtin_preserve_acceess_index()``.
}];
}
def MipsInterruptDocs : Documentation {
let Category = DocCatFunction;
let Heading = "interrupt (MIPS)";
@ -1793,6 +1879,10 @@ the target with or without a "-mno-" in front corresponding to the absence
of the feature, as well as ``arch="CPU"`` which will change the default "CPU"
for the function.
For AArch64, the attribute also allows the "branch-protection=<args>" option,
where the permissible arguments and their effect on code generation are the same
as for the command-line option ``-mbranch-protection``.
Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2",
"avx", "xop" and largely correspond to the machine specific options handled by
the front end.
@ -2976,6 +3066,7 @@ More details can be found in the OpenCL C language Spec v2.0, Section 6.5.
def OpenCLAddressSpaceGenericDocs : Documentation {
let Category = DocOpenCLAddressSpaces;
let Heading = "__generic, generic, [[clang::opencl_generic]]";
let Content = [{
The generic address space attribute is only available with OpenCL v2.0 and later.
It can be used with pointer types. Variables in global and local scope and
@ -2988,6 +3079,7 @@ spaces.
def OpenCLAddressSpaceConstantDocs : Documentation {
let Category = DocOpenCLAddressSpaces;
let Heading = "__constant, constant, [[clang::opencl_constant]]";
let Content = [{
The constant address space attribute signals that an object is located in
a constant (non-modifiable) memory region. It is available to all work items.
@ -2999,6 +3091,7 @@ have an initializer.
def OpenCLAddressSpaceGlobalDocs : Documentation {
let Category = DocOpenCLAddressSpaces;
let Heading = "__global, global, [[clang::opencl_global]]";
let Content = [{
The global address space attribute specifies that an object is allocated in
global memory, which is accessible by all work items. The content stored in this
@ -3011,6 +3104,7 @@ scope) variables and static local variable as well.
def OpenCLAddressSpaceLocalDocs : Documentation {
let Category = DocOpenCLAddressSpaces;
let Heading = "__local, local, [[clang::opencl_local]]";
let Content = [{
The local address space specifies that an object is allocated in the local (work
group) memory area, which is accessible to all work items in the same work
@ -3023,6 +3117,7 @@ space are allowed. Local address space variables cannot have an initializer.
def OpenCLAddressSpacePrivateDocs : Documentation {
let Category = DocOpenCLAddressSpaces;
let Heading = "__private, private, [[clang::opencl_private]]";
let Content = [{
The private address space specifies that an object is allocated in the private
(work item) memory. Other work items cannot access the same memory area and its
@ -3044,6 +3139,44 @@ Since it is not widely used and has been removed from OpenCL 2.1, it is ignored
by Clang.
}];
}
def Ptr32Docs : Documentation {
let Category = DocCatType;
let Content = [{
The ``__ptr32`` qualifier represents a native pointer on a 32-bit system. On a
64-bit system, a pointer with ``__ptr32`` is extended to a 64-bit pointer. The
``__sptr`` and ``__uptr`` qualifiers can be used to specify whether the pointer
is sign extended or zero extended. This qualifier is enabled under
``-fms-extensions``.
}];
}
def Ptr64Docs : Documentation {
let Category = DocCatType;
let Content = [{
The ``__ptr64`` qualifier represents a native pointer on a 64-bit system. On a
32-bit system, a ``__ptr64`` pointer is truncated to a 32-bit pointer. This
qualifier is enabled under ``-fms-extensions``.
}];
}
def SPtrDocs : Documentation {
let Category = DocCatType;
let Content = [{
The ``__sptr`` qualifier specifies that a 32-bit pointer should be sign
extended when converted to a 64-bit pointer.
}];
}
def UPtrDocs : Documentation {
let Category = DocCatType;
let Content = [{
The ``__uptr`` qualifier specifies that a 32-bit pointer should be zero
extended when converted to a 64-bit pointer.
}];
}
def NullabilityDocs : DocumentationCategory<"Nullability Attributes"> {
let Content = [{
Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``).
@ -3855,6 +3988,18 @@ If a function has neither of these attributes, they become subject to the XRay h
}];
}
def PatchableFunctionEntryDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
``__attribute__((patchable_function_entry(N,M)))`` is used to generate M NOPs
before the function entry and N-M NOPs after the function entry. This attribute
takes precedence over the command line option ``-fpatchable-function-entry=N,M``.
``M`` defaults to 0 if omitted.
Currently, only M=0 is supported.
}];
}
def TransparentUnionDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
@ -3895,6 +4040,104 @@ overheads associated with defining and calling such a method.
}];
}
def ObjCDirectDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
The ``objc_direct`` attribute can be used to mark an Objective-C method as
being *direct*. A direct method is treated statically like an ordinary method,
but dynamically it behaves more like a C function. This lowers some of the costs
associated with the method but also sacrifices some of the ordinary capabilities
of Objective-C methods.
A message send of a direct method calls the implementation directly, as if it
were a C function, rather than using ordinary Objective-C method dispatch. This
is substantially faster and potentially allows the implementation to be inlined,
but it also means the method cannot be overridden in subclasses or replaced
dynamically, as ordinary Objective-C methods can.
Furthermore, a direct method is not listed in the class's method lists. This
substantially reduces the code-size overhead of the method but also means it
cannot be called dynamically using ordinary Objective-C method dispatch at all;
in particular, this means that it cannot override a superclass method or satisfy
a protocol requirement.
Because a direct method cannot be overridden, it is an error to perform
a ``super`` message send of one.
Although a message send of a direct method causes the method to be called
directly as if it were a C function, it still obeys Objective-C semantics in other
ways:
- If the receiver is ``nil``, the message send does nothing and returns the zero value
for the return type.
- A message send of a direct class method will cause the class to be initialized,
including calling the ``+initialize`` method if present.
- The implicit ``_cmd`` parameter containing the method's selector is still defined.
In order to minimize code-size costs, the implementation will not emit a reference
to the selector if the parameter is unused within the method.
Symbols for direct method implementations are implicitly given hidden
visibility, meaning that they can only be called within the same linkage unit.
It is an error to do any of the following:
- declare a direct method in a protocol,
- declare an override of a direct method with a method in a subclass,
- declare an override of a non-direct method with a direct method in a subclass,
- declare a method with different directness in different class interfaces, or
- implement a non-direct method (as declared in any class interface) with a direct method.
If any of these rules would be violated if every method defined in an
``@implementation`` within a single linkage unit were declared in an
appropriate class interface, the program is ill-formed with no diagnostic
required. If a violation of this rule is not diagnosed, behavior remains
well-defined; this paragraph is simply reserving the right to diagnose such
conflicts in the future, not to treat them as undefined behavior.
Additionally, Clang will warn about any ``@selector`` expression that
names a selector that is only known to be used for direct methods.
For the purpose of these rules, a "class interface" includes a class's primary
``@interface`` block, its class extensions, its categories, its declared protocols,
and all the class interfaces of its superclasses.
An Objective-C property can be declared with the ``direct`` property
attribute. If a direct property declaration causes an implicit declaration of
a getter or setter method (that is, if the given method is not explicitly
declared elsewhere), the method is declared to be direct.
Some programmers may wish to make many methods direct at once. In order
to simplify this, the ``objc_direct_members`` attribute is provided; see its
documentation for more information.
}];
}
def ObjCDirectMembersDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
The ``objc_direct_members`` attribute can be placed on an Objective-C
``@interface`` or ``@implementation`` to mark that methods declared
therein should be considered direct by default. See the documentation
for ``objc_direct`` for more information about direct methods.
When ``objc_direct_members`` is placed on an ``@interface`` block, every
method in the block is considered to be declared as direct. This includes any
implicit method declarations introduced by property declarations. If the method
redeclares a non-direct method, the declaration is ill-formed, exactly as if the
method was annotated with the ``objc_direct`` attribute. ``objc_direct_members``
cannot be placed on the primary interface of a class, only on category or class
extension interfaces.
When ``objc_direct_members`` is placed on an ``@implementation`` block,
methods defined in the block are considered to be declared as direct unless
they have been previously declared as non-direct in any interface of the class.
This includes the implicit method definitions introduced by synthesized
properties, including auto-synthesized properties.
}];
}
def SelectAnyDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
@ -3908,10 +4151,25 @@ For more information see
or `msvc documentation <https://docs.microsoft.com/pl-pl/cpp/cpp/selectany>`_.
}]; }
def WebAssemblyExportNameDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Clang supports the ``__attribute__((export_name(<name>)))``
attribute for the WebAssembly target. This attribute may be attached to a
function declaration, where it modifies how the symbol is to be exported
from the linked WebAssembly.
WebAssembly functions are exported via string name. By default when a symbol
is exported, the export name for C/C++ symbols are the same as their C/C++
symbol names. This attribute can be used to override the default behavior, and
request a specific string name be used instead.
}];
}
def WebAssemblyImportModuleDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Clang supports the ``__attribute__((import_module(<module_name>)))``
Clang supports the ``__attribute__((import_module(<module_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.
@ -3921,14 +4179,14 @@ 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.
request a specific module name be used instead.
}];
}
def WebAssemblyImportNameDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Clang supports the ``__attribute__((import_name(<name>)))``
Clang supports the ``__attribute__((import_name(<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.
@ -3938,7 +4196,7 @@ 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.
request a specific field name be used instead.
}];
}
@ -4132,7 +4390,7 @@ 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
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.
@ -4312,6 +4570,26 @@ This attribute does not affect optimizations in any way, unlike GCC's
}];
}
def CFGuardDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Code can indicate CFG checks are not wanted with the ``__declspec(guard(nocf))``
attribute. This directs the compiler to not insert any CFG checks for the entire
function. This approach is typically used only sparingly in specific situations
where the programmer has manually inserted "CFG-equivalent" protection. The
programmer knows that they are calling through some read-only function table
whose address is obtained through read-only memory references and for which the
index is masked to the function table limit. This approach may also be applied
to small wrapper functions that are not inlined and that do nothing more than
make a call through a function pointer. Since incorrect usage of this directive
can compromise the security of CFG, the programmer must be very careful using
the directive. Typically, this usage is limited to very small functions that
only call one function.
`Control Flow Guard documentation <https://docs.microsoft.com/en-us/windows/win32/secbp/pe-metadata>`
}];
}
def HIPPinnedShadowDocs : Documentation {
let Category = DocCatType;
let Content = [{
@ -4344,7 +4622,7 @@ object of type ``T``:
The argument ``T`` is optional and is ignored.
This attribute may be used by analysis tools and has no effect on code
generation.
generation. A ``void`` argument means that the class can own any type.
See Pointer_ for an example.
}];
@ -4370,7 +4648,7 @@ like pointers to an object of type ``T``:
The argument ``T`` is optional and is ignored.
This attribute may be used by analysis tools and has no effect on code
generation.
generation. A ``void`` argument means that the pointer can point to any type.
Example:
When constructing an instance of a class annotated like this (a Pointer) from
@ -4391,3 +4669,123 @@ When the Owner's lifetime ends, it will consider the Pointer to be dangling.
}];
}
def ArmMveAliasDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
This attribute is used in the implementation of the ACLE intrinsics
for the Arm MVE instruction set. It allows the intrinsic functions to
be declared using the names defined in ACLE, and still be recognized
as clang builtins equivalent to the underlying name. For example,
``arm_mve.h`` declares the function ``vaddq_u32`` with
``__attribute__((__clang_arm_mve_alias(__builtin_arm_mve_vaddq_u32)))``,
and similarly, one of the type-overloaded declarations of ``vaddq``
will have the same attribute. This ensures that both functions are
recognized as that clang builtin, and in the latter case, the choice
of which builtin to identify the function as can be deferred until
after overload resolution.
This attribute can only be used to set up the aliases for the MVE
intrinsic functions; it is intended for use only inside ``arm_mve.h``,
and is not a general mechanism for declaring arbitrary aliases for
clang builtin functions.
}];
}
def NoBuiltinDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
.. Note:: This attribute is not yet fully implemented, it is validated but has
no effect on the generated code.
The ``__attribute__((no_builtin))`` is similar to the ``-fno-builtin`` flag
except it is specific to the body of a function. The attribute may also be
applied to a virtual function but has no effect on the behavior of overriding
functions in a derived class.
It accepts one or more strings corresponding to the specific names of the
builtins to disable (e.g. "memcpy", "memset").
If the attribute is used without parameters it will disable all buitins at
once.
.. code-block:: c++
// The compiler is not allowed to add any builtin to foo's body.
void foo(char* data, size_t count) __attribute__((no_builtin)) {
// The compiler is not allowed to convert the loop into
// `__builtin_memset(data, 0xFE, count);`.
for (size_t i = 0; i < count; ++i)
data[i] = 0xFE;
}
// The compiler is not allowed to add the `memcpy` builtin to bar's body.
void bar(char* data, size_t count) __attribute__((no_builtin("memcpy"))) {
// The compiler is allowed to convert the loop into
// `__builtin_memset(data, 0xFE, count);` but cannot generate any
// `__builtin_memcpy`
for (size_t i = 0; i < count; ++i)
data[i] = 0xFE;
}
}];
}
def HandleDocs : DocumentationCategory<"Handle Attributes"> {
let Content = [{
Handles are a way to identify resources like files, sockets, and processes.
They are more opaque than pointers and widely used in system programming. They
have similar risks such as never releasing a resource associated with a handle,
attempting to use a handle that was already released, or trying to release a
handle twice. Using the annotations below it is possible to make the ownership
of the handles clear: whose responsibility is to release them. They can also
aid static analysis tools to find bugs.
}];
}
def AcquireHandleDocs : Documentation {
let Category = HandleDocs;
let Content = [{
If this annotation is on a function or a function type it is assumed to return
a new handle. In case this annotation is on an output parameter,
the function is assumed to fill the corresponding argument with a new
handle.
.. code-block:: c++
// Output arguments from Zircon.
zx_status_t zx_socket_create(uint32_t options,
zx_handle_t __attribute__((acquire_handle)) * out0,
zx_handle_t* out1 [[clang::acquire_handle]]);
// Returned handle.
[[clang::acquire_handle]] int open(const char *path, int oflag, ... );
int open(const char *path, int oflag, ... ) __attribute__((acquire_handle));
}];
}
def UseHandleDocs : Documentation {
let Category = HandleDocs;
let Content = [{
A function taking a handle by value might close the handle. If a function
parameter is annotated with `use_handle` it is assumed to not to change
the state of the handle. It is also assumed to require an open handle to work with.
.. code-block:: c++
zx_status_t zx_port_wait(zx_handle_t handle [[clang::use_handle]],
zx_time_t deadline,
zx_port_packet_t* packet);
}];
}
def ReleaseHandleDocs : Documentation {
let Category = HandleDocs;
let Content = [{
If a function parameter is annotated with `release_handle` it is assumed to
close the handle. It is also assumed to require an open handle to work with.
.. code-block:: c++
zx_status_t zx_handle_close(zx_handle_t handle [[clang::release_handle]]);
}];
}

View File

@ -391,23 +391,23 @@ BUILTIN(__builtin_ctanhf, "XfXf", "Fne")
BUILTIN(__builtin_ctanhl, "XLdXLd", "Fne")
// FP Comparisons.
BUILTIN(__builtin_isgreater , "i.", "Fnc")
BUILTIN(__builtin_isgreaterequal, "i.", "Fnc")
BUILTIN(__builtin_isless , "i.", "Fnc")
BUILTIN(__builtin_islessequal , "i.", "Fnc")
BUILTIN(__builtin_islessgreater , "i.", "Fnc")
BUILTIN(__builtin_isunordered , "i.", "Fnc")
BUILTIN(__builtin_isgreater , "i.", "Fnct")
BUILTIN(__builtin_isgreaterequal, "i.", "Fnct")
BUILTIN(__builtin_isless , "i.", "Fnct")
BUILTIN(__builtin_islessequal , "i.", "Fnct")
BUILTIN(__builtin_islessgreater , "i.", "Fnct")
BUILTIN(__builtin_isunordered , "i.", "Fnct")
// Unary FP classification
BUILTIN(__builtin_fpclassify, "iiiiii.", "Fnc")
BUILTIN(__builtin_isfinite, "i.", "Fnc")
BUILTIN(__builtin_isinf, "i.", "Fnc")
BUILTIN(__builtin_isinf_sign, "i.", "Fnc")
BUILTIN(__builtin_isnan, "i.", "Fnc")
BUILTIN(__builtin_isnormal, "i.", "Fnc")
BUILTIN(__builtin_fpclassify, "iiiiii.", "Fnct")
BUILTIN(__builtin_isfinite, "i.", "Fnct")
BUILTIN(__builtin_isinf, "i.", "Fnct")
BUILTIN(__builtin_isinf_sign, "i.", "Fnct")
BUILTIN(__builtin_isnan, "i.", "Fnct")
BUILTIN(__builtin_isnormal, "i.", "Fnct")
// FP signbit builtins
BUILTIN(__builtin_signbit, "i.", "Fnc")
BUILTIN(__builtin_signbit, "i.", "Fnct")
BUILTIN(__builtin_signbitf, "if", "Fnc")
BUILTIN(__builtin_signbitl, "iLd", "Fnc")
@ -718,6 +718,8 @@ ATOMIC_BUILTIN(__c11_atomic_fetch_sub, "v.", "t")
ATOMIC_BUILTIN(__c11_atomic_fetch_and, "v.", "t")
ATOMIC_BUILTIN(__c11_atomic_fetch_or, "v.", "t")
ATOMIC_BUILTIN(__c11_atomic_fetch_xor, "v.", "t")
ATOMIC_BUILTIN(__c11_atomic_fetch_max, "v.", "t")
ATOMIC_BUILTIN(__c11_atomic_fetch_min, "v.", "t")
BUILTIN(__c11_atomic_thread_fence, "vi", "n")
BUILTIN(__c11_atomic_signal_fence, "vi", "n")
BUILTIN(__c11_atomic_is_lock_free, "iz", "n")
@ -742,6 +744,8 @@ ATOMIC_BUILTIN(__atomic_sub_fetch, "v.", "t")
ATOMIC_BUILTIN(__atomic_and_fetch, "v.", "t")
ATOMIC_BUILTIN(__atomic_or_fetch, "v.", "t")
ATOMIC_BUILTIN(__atomic_xor_fetch, "v.", "t")
ATOMIC_BUILTIN(__atomic_max_fetch, "v.", "t")
ATOMIC_BUILTIN(__atomic_min_fetch, "v.", "t")
ATOMIC_BUILTIN(__atomic_nand_fetch, "v.", "t")
BUILTIN(__atomic_test_and_set, "bvD*i", "n")
BUILTIN(__atomic_clear, "vvD*i", "n")
@ -979,6 +983,8 @@ LIBBUILTIN(longjmp, "vJi", "fr", "setjmp.h", ALL_LANGUAGES)
// when these functions are used in non-GNU mode. PR16138.
LIBBUILTIN(alloca, "v*z", "f", "stdlib.h", ALL_GNU_LANGUAGES)
// POSIX string.h
LIBBUILTIN(memccpy, "v*v*vC*iz", "f", "string.h", ALL_GNU_LANGUAGES)
LIBBUILTIN(mempcpy, "v*v*vC*z", "f", "string.h", ALL_GNU_LANGUAGES)
LIBBUILTIN(stpcpy, "c*c*cC*", "f", "string.h", ALL_GNU_LANGUAGES)
LIBBUILTIN(stpncpy, "c*c*cC*z", "f", "string.h", ALL_GNU_LANGUAGES)
LIBBUILTIN(strdup, "c*cC*", "f", "string.h", ALL_GNU_LANGUAGES)
@ -1470,6 +1476,11 @@ BUILTIN(__builtin_char_memchr, "c*cC*iz", "n")
BUILTIN(__builtin_dump_struct, "ivC*v*", "tn")
BUILTIN(__builtin_preserve_access_index, "v.", "t")
// Alignment builtins (uses custom parsing to support pointers and integers)
BUILTIN(__builtin_is_aligned, "bvC*z", "nct")
BUILTIN(__builtin_align_up, "v*vC*z", "nct")
BUILTIN(__builtin_align_down, "v*vC*z", "nct")
// Safestack builtins
BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn")
BUILTIN(__builtin___get_unsafe_stack_bottom, "v*", "Fn")

View File

@ -25,8 +25,6 @@
namespace clang {
class TargetInfo;
class IdentifierTable;
class ASTContext;
class QualType;
class LangOptions;
enum LanguageID {
@ -224,7 +222,7 @@ class Context {
/// Returns true if this is a libc/libm function without the '__builtin_'
/// prefix.
static bool isBuiltinFunc(const char *Name);
static bool isBuiltinFunc(llvm::StringRef Name);
/// Returns true if this is a builtin that can be redeclared. Returns true
/// for non-builtins.

View File

@ -33,6 +33,8 @@ BUILTIN(__builtin_arm_clrex, "v", "")
// Bit manipulation
BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
BUILTIN(__builtin_arm_rbit64, "WUiWUi", "nc")
BUILTIN(__builtin_arm_cls, "UiZUi", "nc")
BUILTIN(__builtin_arm_cls64, "UiWUi", "nc")
// HINT
BUILTIN(__builtin_arm_nop, "v", "")

View File

@ -115,6 +115,8 @@ BUILTIN(__builtin_arm_smusdx, "iii", "nc")
// Bit manipulation
BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
BUILTIN(__builtin_arm_cls, "UiZUi", "nc")
BUILTIN(__builtin_arm_cls64, "UiWUi", "nc")
// Store and load exclusive
BUILTIN(__builtin_arm_ldrexd, "LLUiv*", "")
@ -164,6 +166,12 @@ BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc")
BUILTIN(__builtin_arm_crc32d, "UiUiLLUi", "nc")
BUILTIN(__builtin_arm_crc32cd, "UiUiLLUi", "nc")
// ARMv8-M Security Extensions a.k.a CMSE
BUILTIN(__builtin_arm_cmse_TT, "Uiv*", "n")
BUILTIN(__builtin_arm_cmse_TTT, "Uiv*", "n")
BUILTIN(__builtin_arm_cmse_TTA, "Uiv*", "n")
BUILTIN(__builtin_arm_cmse_TTAT, "Uiv*", "n")
// HINT
BUILTIN(__builtin_arm_nop, "v", "")
BUILTIN(__builtin_arm_yield, "v", "")
@ -189,6 +197,11 @@ BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc")
BUILTIN(__builtin_arm_wsr64, "vcC*LLUi", "nc")
BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
// Builtins for implementing ACLE MVE intrinsics. (Unlike NEON, these
// don't need to live in a separate BuiltinsMVE.def, because they
// aren't included from both here and BuiltinsAArch64.def.)
#include "clang/Basic/arm_mve_builtins.inc"
// MSVC
LANGBUILTIN(__emit, "vIUiC", "", ALL_MS_LANGUAGES)

View File

@ -98,6 +98,9 @@ TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd1
TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_avgr_u_i8x16, "V16cV16cV16c", "nc", "unimplemented-simd128")
TARGET_BUILTIN(__builtin_wasm_avgr_u_i16x8, "V8sV8sV8s", "nc", "unimplemented-simd128")
TARGET_BUILTIN(__builtin_wasm_bitselect, "V4iV4iV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_any_true_i8x16, "iV16c", "nc", "simd128")
@ -117,6 +120,8 @@ TARGET_BUILTIN(__builtin_wasm_max_f32x4, "V4fV4fV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd128")
TARGET_BUILTIN(__builtin_wasm_max_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd128")
TARGET_BUILTIN(__builtin_wasm_dot_s_i32x4_i16x8, "V4iV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc", "unimplemented-simd128")
TARGET_BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc", "unimplemented-simd128")

View File

@ -365,7 +365,7 @@ TARGET_BUILTIN(__builtin_ia32_pmaddwd128, "V4iV8sV8s", "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_monitor, "vvC*UiUi", "n", "sse3")
TARGET_BUILTIN(__builtin_ia32_mwait, "vUiUi", "n", "sse3")
TARGET_BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "nV:128:", "sse3")
@ -1396,8 +1396,8 @@ TARGET_BUILTIN(__builtin_ia32_psrlw512, "V32sV32sV8s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_psrlwi512, "V32sV32si", "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_movdqa32load128_mask, "V4iV4iC*V4iUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_movdqa32load256_mask, "V8iV8iC*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, "V8OiV8OiC*V8OiUc", "nV:512:", "avx512f")
@ -1418,8 +1418,8 @@ TARGET_BUILTIN(__builtin_ia32_vcomisd, "iV2dV2dIiIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vcomiss, "iV4fV4fIiIi", "ncV:128:", "avx512f")
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*V64cUOi", "nV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_loaddquhi512_mask, "V32sV32sC*V32sUi", "nV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_loaddquqi512_mask, "V64cV64cC*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")
@ -1432,10 +1432,10 @@ TARGET_BUILTIN(__builtin_ia32_getexpsd128_round_mask, "V2dV2dV2dV2dUcIi", "ncV:1
TARGET_BUILTIN(__builtin_ia32_getexpss128_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_getmantsd_round_mask, "V2dV2dV2dIiV2dUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_getmantss_round_mask, "V4fV4fV4fIiV4fUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loaddquhi128_mask, "V8sV8s*V8sUc", "nV:128:", "avx512bw,avx512vl")
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_loaddquhi128_mask, "V8sV8sC*V8sUc", "nV:128:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_loaddquhi256_mask, "V16sV16sC*V16sUs", "nV:256:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_loaddquqi128_mask, "V16cV16cC*V16cUs", "nV:128:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_loaddquqi256_mask, "V32cV32cC*V32cUi", "nV:256:", "avx512bw,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")
@ -1444,20 +1444,20 @@ TARGET_BUILTIN(__builtin_ia32_fixupimmps128_mask, "V4fV4fV4fV4iIiUc", "ncV:128:"
TARGET_BUILTIN(__builtin_ia32_fixupimmps128_maskz, "V4fV4fV4fV4iIiUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_fixupimmps256_mask, "V8fV8fV8fV8iIiUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_fixupimmps256_maskz, "V8fV8fV8fV8iIiUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadapd128_mask, "V2dV2d*V2dUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadsd128_mask, "V2dV2d*V2dUc", "nV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loadapd256_mask, "V4dV4d*V4dUc", "nV:256:", "avx512vl")
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, "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")
TARGET_BUILTIN(__builtin_ia32_loadupd256_mask, "V4dV4d*V4dUc", "nV:256:", "avx512vl")
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_loadapd128_mask, "V2dV2dC*V2dUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadsd128_mask, "V2dV2dC*V2dUc", "nV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loadapd256_mask, "V4dV4dC*V4dUc", "nV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadaps128_mask, "V4fV4fC*V4fUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadss128_mask, "V4fV4fC*V4fUc", "nV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loadaps256_mask, "V8fV8fC*V8fUc", "nV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loaddqudi128_mask, "V2OiV2OiC*V2OiUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loaddqudi256_mask, "V4OiV4OiC*V4OiUc", "nV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loaddqusi128_mask, "V4iV4iC*V4iUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loaddqusi256_mask, "V8iV8iC*V8iUc", "nV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadupd128_mask, "V2dV2dC*V2dUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadupd256_mask, "V4dV4dC*V4dUc", "nV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadups128_mask, "V4fV4fC*V4fUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadups256_mask, "V8fV8fC*V8fUc", "nV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_storedquhi512_mask, "vV32s*V32sUi", "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")
@ -1872,11 +1872,11 @@ TARGET_BUILTIN(__builtin_ia32_selectss_128, "V4fUcV4fV4f", "ncV:128:", "avx512f"
TARGET_BUILTIN(__builtin_ia32_selectsd_128, "V2dUcV2dV2d", "ncV:128:", "avx512f")
// MONITORX/MWAITX
TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "n", "mwaitx")
TARGET_BUILTIN(__builtin_ia32_monitorx, "vvC*UiUi", "n", "mwaitx")
TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "n", "mwaitx")
// WAITPKG
TARGET_BUILTIN(__builtin_ia32_umonitor, "vv*", "n", "waitpkg")
TARGET_BUILTIN(__builtin_ia32_umonitor, "vvC*", "n", "waitpkg")
TARGET_BUILTIN(__builtin_ia32_umwait, "UcUiUiUi", "n", "waitpkg")
TARGET_BUILTIN(__builtin_ia32_tpause, "UcUiUiUi", "n", "waitpkg")

View File

@ -37,6 +37,7 @@ CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) o
CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink
CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
CODEGENOPT(Backchain , 1, 0) ///< -mbackchain
CODEGENOPT(ControlFlowGuardNoChecks , 1, 0) ///< -cfguard-no-checks
CODEGENOPT(ControlFlowGuard , 1, 0) ///< -cfguard
CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files.
CODEGENOPT(CoverageNoFunctionNamesInData, 1, 0) ///< Do not include function names in GCDA files.
@ -96,6 +97,8 @@ CODEGENOPT(CFProtectionBranch , 1, 0) ///< if -fcf-protection is
CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
///< enabled.
CODEGENOPT(StackSizeSection , 1, 0) ///< Set when -fstack-size-section is enabled.
CODEGENOPT(ForceDwarfFrameSection , 1, 0) ///< Set when -fforce-dwarf-frame is
///< enabled.
///< Set when -fxray-always-emit-customevents is enabled.
CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)
@ -107,8 +110,13 @@ CODEGENOPT(XRayAlwaysEmitTypedEvents , 1, 0)
///< XRay instrumentation.
VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)
VALUE_CODEGENOPT(PatchableFunctionEntryCount , 32, 0) ///< Number of NOPs at function entry
CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
CODEGENOPT(CallFEntry , 1, 0) ///< Set when -mfentry is enabled.
CODEGENOPT(MNopMCount , 1, 0) ///< Set when -mnop-mcount is enabled.
CODEGENOPT(RecordMCount , 1, 0) ///< Set when -mrecord-mcount is enabled.
CODEGENOPT(PackedStack , 1, 0) ///< Set when -mpacked-stack is enabled.
CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to
///< be generated.
CODEGENOPT(PrepareForLTO , 1, 0) ///< Set when -flto is enabled on the
@ -135,6 +143,8 @@ CODEGENOPT(FatalWarnings , 1, 0) ///< Set when -Wa,--fatal-warnings is
///< enabled.
CODEGENOPT(NoWarn , 1, 0) ///< Set when -Wa,--no-warn is enabled.
CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled.
CODEGENOPT(NoInlineLineTables, 1, 0) ///< Whether debug info should contain
///< inline line tables.
CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled.
CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf.
CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero
@ -323,6 +333,9 @@ ENUM_CODEGENOPT(VecLib, VectorLibrary, 2, NoLibrary)
/// The default TLS model to use.
ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
/// Bit size of immediate TLS offsets (0 == use the default).
VALUE_CODEGENOPT(TLSSize, 8, 0)
/// Number of path components to strip when emitting checks. (0 == full
/// filename)
VALUE_CODEGENOPT(EmitCheckPathComponentsToStrip, 32, 0)
@ -364,8 +377,8 @@ CODEGENOPT(ForceEmitVTables, 1, 0)
/// Whether to emit an address-significance table into the object file.
CODEGENOPT(Addrsig, 1, 0)
ENUM_CODEGENOPT(SignReturnAddress, SignReturnAddressScope, 2, None)
ENUM_CODEGENOPT(SignReturnAddressKey, SignReturnAddressKeyValue, 1, AKey)
ENUM_CODEGENOPT(SignReturnAddress, SignReturnAddressScope, 2, SignReturnAddressScope::None)
ENUM_CODEGENOPT(SignReturnAddressKey, SignReturnAddressKeyValue, 1, SignReturnAddressKeyValue::AKey)
CODEGENOPT(BranchTargetEnforcement, 1, 0)
/// Whether to emit unused static constants.

View File

@ -16,6 +16,7 @@
#include "clang/Basic/DebugInfoOptions.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/XRayInstr.h"
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Regex.h"
#include "llvm/Target/TargetOptions.h"
@ -109,13 +110,13 @@ class CodeGenOptions : public CodeGenOptionsBase {
Embed_Marker // Embed a marker as a placeholder for bitcode.
};
enum SignReturnAddressScope {
enum class SignReturnAddressScope {
None, // No signing for any function
NonLeaf, // Sign the return address of functions that spill LR
All // Sign the return address of all functions
};
enum SignReturnAddressKeyValue { AKey, BKey };
enum class SignReturnAddressKeyValue { AKey, BKey };
enum class FramePointerKind {
None, // Omit all frame pointers.
@ -163,7 +164,7 @@ class CodeGenOptions : public CodeGenOptionsBase {
std::string FloatABI;
/// The floating-point denormal mode to use.
std::string FPDenormalMode;
llvm::DenormalMode FPDenormalMode = llvm::DenormalMode::Invalid;
/// The float precision limit to use, if non-empty.
std::string LimitFloatPrecision;
@ -356,6 +357,11 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// Check if CSIR profile use is on.
bool hasProfileCSIRUse() const { return getProfileUse() == ProfileCSIRInstr; }
/// Check if type and variable info should be emitted.
bool hasReducedDebugInfo() const {
return getDebugInfo() >= codegenoptions::DebugInfoConstructor;
}
};
} // end namespace clang

View File

@ -1,27 +1,27 @@
class Comment<bit abstract = 0> {
include "clang/Basic/ASTNode.td"
class CommentNode<CommentNode base, bit abstract = 0> : ASTNode {
CommentNode Base = base;
bit Abstract = abstract;
}
class DComment<Comment base, bit abstract = 0> : Comment<abstract> {
Comment Base = base;
}
def Comment : CommentNode<?, 1>;
def InlineContentComment : CommentNode<Comment, 1>;
def TextComment : CommentNode<InlineContentComment>;
def InlineCommandComment : CommentNode<InlineContentComment>;
def HTMLTagComment : CommentNode<InlineContentComment, 1>;
def HTMLStartTagComment : CommentNode<HTMLTagComment>;
def HTMLEndTagComment : CommentNode<HTMLTagComment>;
def InlineContentComment : Comment<1>;
def TextComment : DComment<InlineContentComment>;
def InlineCommandComment : DComment<InlineContentComment>;
def HTMLTagComment : DComment<InlineContentComment, 1>;
def HTMLStartTagComment : DComment<HTMLTagComment>;
def HTMLEndTagComment : DComment<HTMLTagComment>;
def BlockContentComment : CommentNode<Comment, 1>;
def ParagraphComment : CommentNode<BlockContentComment>;
def BlockCommandComment : CommentNode<BlockContentComment>;
def ParamCommandComment : CommentNode<BlockCommandComment>;
def TParamCommandComment : CommentNode<BlockCommandComment>;
def VerbatimBlockComment : CommentNode<BlockCommandComment>;
def VerbatimLineComment : CommentNode<BlockCommandComment>;
def BlockContentComment : Comment<1>;
def ParagraphComment : DComment<BlockContentComment>;
def BlockCommandComment : DComment<BlockContentComment>;
def ParamCommandComment : DComment<BlockCommandComment>;
def TParamCommandComment : DComment<BlockCommandComment>;
def VerbatimBlockComment : DComment<BlockCommandComment>;
def VerbatimLineComment : DComment<BlockCommandComment>;
def VerbatimBlockLineComment : CommentNode<Comment>;
def VerbatimBlockLineComment : Comment;
def FullComment : Comment;
def FullComment : CommentNode<Comment>;

View File

@ -18,24 +18,35 @@ enum DebugInfoFormat {
};
enum DebugInfoKind {
NoDebugInfo, /// Don't generate debug info.
LocTrackingOnly, /// Emit location information but do not generate
/// debug info in the output. This is useful in
/// cases where the backend wants to track source
/// locations for instructions without actually
/// emitting debug info for them (e.g., when -Rpass
/// is used).
DebugDirectivesOnly, /// Emit only debug directives with the line numbers data
DebugLineTablesOnly, /// Emit only debug info necessary for generating
/// line number tables (-gline-tables-only).
LimitedDebugInfo, /// Limit generated debug info to reduce size
/// (-fno-standalone-debug). This emits
/// forward decls for types that could be
/// replaced with forward decls in the source
/// code. For dynamic C++ classes type info
/// is only emitted into the module that
/// contains the classe's vtable.
FullDebugInfo /// Generate complete debug info.
/// Don't generate debug info.
NoDebugInfo,
/// Emit location information but do not generate debug info in the output.
/// This is useful in cases where the backend wants to track source
/// locations for instructions without actually emitting debug info for them
/// (e.g., when -Rpass is used).
LocTrackingOnly,
/// Emit only debug directives with the line numbers data
DebugDirectivesOnly,
/// Emit only debug info necessary for generating line number tables
/// (-gline-tables-only).
DebugLineTablesOnly,
/// Limit generated debug info for classes to reduce size. This emits class
/// type info only where the constructor is emitted, if it is a class that
/// has a constructor.
DebugInfoConstructor,
/// Limit generated debug info to reduce size (-fno-standalone-debug). This
/// emits forward decls for types that could be replaced with forward decls in
/// the source code. For dynamic C++ classes type info is only emitted into
/// the module that contains the classe's vtable.
LimitedDebugInfo,
/// Generate complete debug info.
FullDebugInfo
};
} // end namespace codegenoptions

View File

@ -1,105 +1,104 @@
class AttrSubject;
include "clang/Basic/ASTNode.td"
class Decl<string diagSpelling = "", bit abstract = 0> : AttrSubject {
class DeclNode<DeclNode base, string diagSpelling = "", bit abstract = 0>
: ASTNode, AttrSubject {
DeclNode Base = base;
bit Abstract = abstract;
string DiagSpelling = diagSpelling;
}
class DDecl<Decl base, string diagSpelling = "", bit abstract = 0>
: Decl<diagSpelling, abstract> {
Decl Base = base;
}
class DeclContext {}
def TranslationUnit : Decl, DeclContext;
def PragmaComment : Decl;
def PragmaDetectMismatch : Decl;
def ExternCContext : Decl, DeclContext;
def Named : Decl<"named declarations", 1>;
def Namespace : DDecl<Named, "namespaces">, DeclContext;
def UsingDirective : DDecl<Named>;
def NamespaceAlias : DDecl<Named>;
def Label : DDecl<Named, "labels">;
def Type : DDecl<Named, "types", 1>;
def TypedefName : DDecl<Type, "typedefs", 1>;
def Typedef : DDecl<TypedefName>;
def TypeAlias : DDecl<TypedefName>;
def ObjCTypeParam : DDecl<TypedefName>;
def UnresolvedUsingTypename : DDecl<Type>;
def Tag : DDecl<Type, "tag types", 1>, DeclContext;
def Enum : DDecl<Tag, "enums">;
def Record : DDecl<Tag, "structs, unions, classes">;
def CXXRecord : DDecl<Record, "classes">;
def ClassTemplateSpecialization : DDecl<CXXRecord>;
def Decl : DeclNode<?, "", 1>;
def TranslationUnit : DeclNode<Decl>, DeclContext;
def PragmaComment : DeclNode<Decl>;
def PragmaDetectMismatch : DeclNode<Decl>;
def ExternCContext : DeclNode<Decl>, DeclContext;
def Named : DeclNode<Decl, "named declarations", 1>;
def Namespace : DeclNode<Named, "namespaces">, DeclContext;
def UsingDirective : DeclNode<Named>;
def NamespaceAlias : DeclNode<Named>;
def Label : DeclNode<Named, "labels">;
def Type : DeclNode<Named, "types", 1>;
def TypedefName : DeclNode<Type, "typedefs", 1>;
def Typedef : DeclNode<TypedefName>;
def TypeAlias : DeclNode<TypedefName>;
def ObjCTypeParam : DeclNode<TypedefName>;
def UnresolvedUsingTypename : DeclNode<Type>;
def Tag : DeclNode<Type, "tag types", 1>, DeclContext;
def Enum : DeclNode<Tag, "enums">;
def Record : DeclNode<Tag, "structs, unions, classes">;
def CXXRecord : DeclNode<Record, "classes">;
def ClassTemplateSpecialization : DeclNode<CXXRecord>;
def ClassTemplatePartialSpecialization
: DDecl<ClassTemplateSpecialization>;
def TemplateTypeParm : DDecl<Type>;
def Value : DDecl<Named, "value declarations", 1>;
def EnumConstant : DDecl<Value, "enumerators">;
def UnresolvedUsingValue : DDecl<Value>;
def IndirectField : DDecl<Value>;
def Binding : DDecl<Value>;
def OMPDeclareReduction : DDecl<Value>, DeclContext;
def OMPDeclareMapper : DDecl<Value>, DeclContext;
def Declarator : DDecl<Value, "declarators", 1>;
def Field : DDecl<Declarator, "non-static data members">;
def ObjCIvar : DDecl<Field>;
def ObjCAtDefsField : DDecl<Field>;
def MSProperty : DDecl<Declarator>;
def Function : DDecl<Declarator, "functions">, DeclContext;
def CXXDeductionGuide : DDecl<Function>;
def CXXMethod : DDecl<Function>;
def CXXConstructor : DDecl<CXXMethod>;
def CXXDestructor : DDecl<CXXMethod>;
def CXXConversion : DDecl<CXXMethod>;
def Var : DDecl<Declarator, "variables">;
def VarTemplateSpecialization : DDecl<Var>;
: DeclNode<ClassTemplateSpecialization>;
def TemplateTypeParm : DeclNode<Type>;
def Value : DeclNode<Named, "value declarations", 1>;
def EnumConstant : DeclNode<Value, "enumerators">;
def UnresolvedUsingValue : DeclNode<Value>;
def IndirectField : DeclNode<Value>;
def Binding : DeclNode<Value>;
def OMPDeclareReduction : DeclNode<Value>, DeclContext;
def OMPDeclareMapper : DeclNode<Value>, DeclContext;
def Declarator : DeclNode<Value, "declarators", 1>;
def Field : DeclNode<Declarator, "non-static data members">;
def ObjCIvar : DeclNode<Field>;
def ObjCAtDefsField : DeclNode<Field>;
def MSProperty : DeclNode<Declarator>;
def Function : DeclNode<Declarator, "functions">, DeclContext;
def CXXDeductionGuide : DeclNode<Function>;
def CXXMethod : DeclNode<Function>;
def CXXConstructor : DeclNode<CXXMethod>;
def CXXDestructor : DeclNode<CXXMethod>;
def CXXConversion : DeclNode<CXXMethod>;
def Var : DeclNode<Declarator, "variables">;
def VarTemplateSpecialization : DeclNode<Var>;
def VarTemplatePartialSpecialization
: DDecl<VarTemplateSpecialization>;
def ImplicitParam : DDecl<Var>;
def ParmVar : DDecl<Var, "parameters">;
def Decomposition : DDecl<Var>;
def OMPCapturedExpr : DDecl<Var>;
def NonTypeTemplateParm : DDecl<Declarator>;
def Template : DDecl<Named, "templates", 1>;
def RedeclarableTemplate : DDecl<Template, "redeclarable templates", 1>;
def FunctionTemplate : DDecl<RedeclarableTemplate>;
def ClassTemplate : DDecl<RedeclarableTemplate>;
def VarTemplate : DDecl<RedeclarableTemplate>;
def TypeAliasTemplate : DDecl<RedeclarableTemplate>;
def TemplateTemplateParm : DDecl<Template>;
def BuiltinTemplate : DDecl<Template>;
def Concept : DDecl<Template>;
def Using : DDecl<Named>;
def UsingPack : DDecl<Named>;
def UsingShadow : DDecl<Named>;
def ConstructorUsingShadow : DDecl<UsingShadow>;
def ObjCMethod : DDecl<Named, "Objective-C methods">, DeclContext;
def ObjCContainer : DDecl<Named, "Objective-C containers", 1>, DeclContext;
def ObjCCategory : DDecl<ObjCContainer>;
def ObjCProtocol : DDecl<ObjCContainer, "Objective-C protocols">;
def ObjCInterface : DDecl<ObjCContainer, "Objective-C interfaces">;
: DeclNode<VarTemplateSpecialization>;
def ImplicitParam : DeclNode<Var>;
def ParmVar : DeclNode<Var, "parameters">;
def Decomposition : DeclNode<Var>;
def OMPCapturedExpr : DeclNode<Var>;
def NonTypeTemplateParm : DeclNode<Declarator>;
def Template : DeclNode<Named, "templates", 1>;
def RedeclarableTemplate : DeclNode<Template, "redeclarable templates", 1>;
def FunctionTemplate : DeclNode<RedeclarableTemplate>;
def ClassTemplate : DeclNode<RedeclarableTemplate>;
def VarTemplate : DeclNode<RedeclarableTemplate>;
def TypeAliasTemplate : DeclNode<RedeclarableTemplate>;
def TemplateTemplateParm : DeclNode<Template>;
def BuiltinTemplate : DeclNode<Template>;
def Concept : DeclNode<Template>;
def Using : DeclNode<Named>;
def UsingPack : DeclNode<Named>;
def UsingShadow : DeclNode<Named>;
def ConstructorUsingShadow : DeclNode<UsingShadow>;
def ObjCMethod : DeclNode<Named, "Objective-C methods">, DeclContext;
def ObjCContainer : DeclNode<Named, "Objective-C containers", 1>, DeclContext;
def ObjCCategory : DeclNode<ObjCContainer>;
def ObjCProtocol : DeclNode<ObjCContainer, "Objective-C protocols">;
def ObjCInterface : DeclNode<ObjCContainer, "Objective-C interfaces">;
def ObjCImpl
: DDecl<ObjCContainer, "Objective-C implementation declarations", 1>;
def ObjCCategoryImpl : DDecl<ObjCImpl>;
def ObjCImplementation : DDecl<ObjCImpl>;
def ObjCProperty : DDecl<Named, "Objective-C properties">;
def ObjCCompatibleAlias : DDecl<Named>;
def LinkageSpec : Decl, DeclContext;
def Export : Decl, DeclContext;
def ObjCPropertyImpl : Decl;
def FileScopeAsm : Decl;
def AccessSpec : Decl;
def Friend : Decl;
def FriendTemplate : Decl;
def StaticAssert : Decl;
def Block : Decl<"blocks">, DeclContext;
def Captured : Decl, DeclContext;
def ClassScopeFunctionSpecialization : Decl;
def Import : Decl;
def OMPThreadPrivate : Decl;
def OMPAllocate : Decl;
def OMPRequires : Decl;
def Empty : Decl;
: DeclNode<ObjCContainer, "Objective-C implementation declarations", 1>;
def ObjCCategoryImpl : DeclNode<ObjCImpl>;
def ObjCImplementation : DeclNode<ObjCImpl>;
def ObjCProperty : DeclNode<Named, "Objective-C properties">;
def ObjCCompatibleAlias : DeclNode<Named>;
def LinkageSpec : DeclNode<Decl>, DeclContext;
def Export : DeclNode<Decl>, DeclContext;
def ObjCPropertyImpl : DeclNode<Decl>;
def FileScopeAsm : DeclNode<Decl>;
def AccessSpec : DeclNode<Decl>;
def Friend : DeclNode<Decl>;
def FriendTemplate : DeclNode<Decl>;
def StaticAssert : DeclNode<Decl>;
def Block : DeclNode<Decl, "blocks">, DeclContext;
def Captured : DeclNode<Decl>, DeclContext;
def ClassScopeFunctionSpecialization : DeclNode<Decl>;
def Import : DeclNode<Decl>;
def OMPThreadPrivate : DeclNode<Decl>;
def OMPAllocate : DeclNode<Decl>;
def OMPRequires : DeclNode<Decl>;
def Empty : DeclNode<Decl>;
def LifetimeExtendedTemporary : DeclNode<Decl>;

View File

@ -177,6 +177,9 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
/// IdentifierInfo
ak_identifierinfo,
/// address space
ak_addrspace,
/// Qualifiers
ak_qual,
@ -473,6 +476,9 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
/// Second string argument for the delayed diagnostic.
std::string DelayedDiagArg2;
/// Third string argument for the delayed diagnostic.
std::string DelayedDiagArg3;
/// Optional flag value.
///
/// Some flags accept values, for instance: -Wframe-larger-than=<value> and
@ -874,8 +880,12 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
/// \param Arg2 A string argument that will be provided to the
/// diagnostic. A copy of this string will be stored in the
/// DiagnosticsEngine object itself.
///
/// \param Arg3 A string argument that will be provided to the
/// diagnostic. A copy of this string will be stored in the
/// DiagnosticsEngine object itself.
void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "",
StringRef Arg2 = "");
StringRef Arg2 = "", StringRef Arg3 = "");
/// Clear out the current diagnostic.
void Clear() { CurDiagID = std::numeric_limits<unsigned>::max(); }

View File

@ -70,6 +70,8 @@ def note_constexpr_pointer_subtraction_not_same_array : Note<
"subtracted pointers are not elements of the same array">;
def note_constexpr_pointer_subtraction_zero_size : Note<
"subtraction of pointers to type %0 of zero size">;
def note_constexpr_pointer_comparison_unspecified : Note<
"comparison has unspecified value">;
def note_constexpr_pointer_comparison_base_classes : Note<
"comparison of addresses of subobjects of different base classes "
"has unspecified value">;
@ -216,6 +218,14 @@ def note_constexpr_baa_insufficient_alignment : Note<
def note_constexpr_baa_value_insufficient_alignment : Note<
"value of the aligned pointer (%0) is not a multiple of the asserted %1 "
"%plural{1:byte|:bytes}1">;
def note_constexpr_invalid_alignment : Note<
"requested alignment %0 is not a positive power of two">;
def note_constexpr_alignment_too_big : Note<
"requested alignment must be %0 or less for type %1; %2 is invalid">;
def note_constexpr_alignment_compute : Note<
"cannot constant evaluate whether run-time alignment is at least %0">;
def note_constexpr_alignment_adjust : Note<
"cannot constant evaluate the result of adjusting alignment to %0">;
def note_constexpr_destroy_out_of_lifetime : Note<
"destroying object '%0' whose lifetime has already ended">;
def note_constexpr_unsupported_destruction : Note<
@ -329,6 +339,10 @@ def warn_integer_constant_overflow : Warning<
def note_unimplemented_constexpr_lambda_feature_ast : Note<
"unimplemented constexpr lambda feature: %0 (coming soon!)">;
def warn_is_constant_evaluated_always_true_constexpr : Warning<
"'%0' will always evaluate to 'true' in a manifestly constant-evaluated expression">,
InGroup<DiagGroup<"constant-evaluated">>;
// inline asm related.
let CategoryName = "Inline Assembly Issue" in {
def err_asm_invalid_escape : Error<

View File

@ -146,8 +146,8 @@ def warn_doc_returns_attached_to_a_void_function : Warning<
// \deprecated command
def warn_doc_deprecated_not_sync : Warning<
"declaration is marked with '\\deprecated' command but does not have "
"a deprecation attribute">,
"declaration is marked with '%select{\\|@}0deprecated' command but does "
"not have a deprecation attribute">,
InGroup<DocumentationDeprecatedSync>, DefaultIgnore;
def note_add_deprecation_attr : Note<

View File

@ -87,7 +87,8 @@ def warn_cxx98_compat_variadic_templates :
Warning<"variadic templates are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_default_special_members : Error<
"only special member functions may be defaulted">;
"only special member functions %select{|and comparison operators }0"
"may be defaulted">;
def err_deleted_non_function : Error<
"only functions can have deleted definitions">;
def err_module_not_found : Error<"module '%0' not found">, DefaultFatal;
@ -270,6 +271,8 @@ def err_target_unsupported_mcmse : Error<
"-mcmse is not supported for %0">;
def err_opt_not_valid_with_opt : Error<
"option '%0' cannot be specified with '%1'">;
def err_opt_not_valid_without_opt : Error<
"option '%0' cannot be specified without '%1'">;
def err_opt_not_valid_on_target : Error<
"option '%0' cannot be specified on this target">;
@ -304,6 +307,11 @@ def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to b
def err_openclcxx_not_supported : Error<
"'%0' is not supported in C++ for OpenCL">;
// HIP
def warn_ignored_hip_only_option : Warning<
"'%0' is ignored since it is only supported for HIP">,
InGroup<HIPOnly>;
// OpenMP
def err_omp_more_one_clause : Error<
"directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier| with 'source' dependence}2">;

View File

@ -91,6 +91,8 @@ def err_no_external_assembler : Error<
"there is no external assembler that can be used on this platform">;
def err_drv_unable_to_remove_file : Error<
"unable to remove file: %0">;
def err_drv_unable_to_set_working_directory : Error <
"unable to set working directory: %0">;
def err_drv_command_failure : Error<
"unable to execute command: %0">;
def err_drv_invalid_darwin_version : Error<
@ -141,8 +143,8 @@ def err_drv_missing_arg_mtp : Error<
"missing argument to '%0'">;
def err_drv_invalid_libcxx_deployment : Error<
"invalid deployment target for -stdlib=libc++ (requires %0 or later)">;
def err_drv_invalid_argument_to_fdebug_prefix_map : Error<
"invalid argument '%0' to -fdebug-prefix-map">;
def err_drv_invalid_argument_to_option : Error<
"invalid argument '%0' to -%1">;
def err_drv_malformed_sanitizer_blacklist : Error<
"malformed sanitizer blacklist: '%0'">;
def err_drv_duplicate_config : Error<
@ -248,6 +250,9 @@ def err_drv_unsupported_embed_bitcode
def err_drv_bitcode_unsupported_on_toolchain : Error<
"-fembed-bitcode is not supported on versions of iOS prior to 6.0">;
def err_drv_invalid_malign_branch_EQ : Error<
"invalid argument '%0' to -malign-branch=; each element must be one of: %1">;
def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>;
def warn_drv_optimization_value : Warning<"optimization level '%0' is not supported; using '%1%2' instead">,
InGroup<InvalidCommandLineArgument>;
@ -402,6 +407,8 @@ def err_drv_unsupported_indirect_jump_opt : Error<
"'-mindirect-jump=%0' is unsupported with the '%1' architecture">;
def err_drv_unknown_indirect_jump_opt : Error<
"unknown '-mindirect-jump=' option '%0'">;
def err_drv_unsupported_fpatchable_function_entry_argument : Error<
"the second argument of '-fpatchable-function-entry' must be 0 or omitted">;
def warn_drv_unable_to_find_directory_expected : Warning<
"unable to find %0 directory, expected to be in '%1'">,

View File

@ -60,7 +60,27 @@ def UndefinedBoolConversion : DiagGroup<"undefined-bool-conversion">;
def BoolConversion : DiagGroup<"bool-conversion", [PointerBoolConversion,
UndefinedBoolConversion]>;
def IntConversion : DiagGroup<"int-conversion">;
def EnumConversion : DiagGroup<"enum-conversion">;
def DeprecatedEnumCompareConditional :
DiagGroup<"deprecated-enum-compare-conditional">;
def EnumCompareConditional : DiagGroup<"enum-compare-conditional",
[DeprecatedEnumCompareConditional]>;
def EnumCompareSwitch : DiagGroup<"enum-compare-switch">;
def DeprecatedEnumCompare : DiagGroup<"deprecated-enum-compare">;
def EnumCompare : DiagGroup<"enum-compare", [EnumCompareSwitch,
DeprecatedEnumCompare]>;
def DeprecatedAnonEnumEnumConversion : DiagGroup<"deprecated-anon-enum-enum-conversion">;
def DeprecatedEnumEnumConversion : DiagGroup<"deprecated-enum-enum-conversion">;
def DeprecatedEnumFloatConversion : DiagGroup<"deprecated-enum-float-conversion">;
def AnonEnumEnumConversion : DiagGroup<"anon-enum-enum-conversion",
[DeprecatedAnonEnumEnumConversion]>;
def EnumEnumConversion : DiagGroup<"enum-enum-conversion",
[DeprecatedEnumEnumConversion]>;
def EnumFloatConversion : DiagGroup<"enum-float-conversion",
[DeprecatedEnumFloatConversion]>;
def EnumConversion : DiagGroup<"enum-conversion",
[EnumEnumConversion,
EnumFloatConversion,
EnumCompareConditional]>;
def ObjCSignedCharBoolImplicitIntConversion :
DiagGroup<"objc-signed-char-bool-implicit-int-conversion">;
def ImplicitIntConversion : DiagGroup<"implicit-int-conversion",
@ -113,6 +133,7 @@ def UndefinedVarTemplate : DiagGroup<"undefined-var-template">;
def UndefinedFuncTemplate : DiagGroup<"undefined-func-template">;
def MissingNoEscape : DiagGroup<"missing-noescape">;
def DefaultedFunctionDeleted : DiagGroup<"defaulted-function-deleted">;
def DeleteIncomplete : DiagGroup<"delete-incomplete">;
def DeleteNonAbstractNonVirtualDtor : DiagGroup<"delete-non-abstract-non-virtual-dtor">;
def DeleteAbstractNonVirtualDtor : DiagGroup<"delete-abstract-non-virtual-dtor">;
@ -125,8 +146,11 @@ def FinalDtorNonFinalClass : DiagGroup<"final-dtor-non-final-class">;
def CXX11CompatDeprecatedWritableStr :
DiagGroup<"c++11-compat-deprecated-writable-strings">;
def DeprecatedArrayCompare : DiagGroup<"deprecated-array-compare">;
def DeprecatedAttributes : DiagGroup<"deprecated-attributes">;
def DeprecatedCommaSubscript : DiagGroup<"deprecated-comma-subscript">;
def DeprecatedCopy : DiagGroup<"deprecated-copy">;
def DeprecatedCopyDtor : DiagGroup<"deprecated-copy-dtor">;
def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
def UnavailableDeclarations : DiagGroup<"unavailable-declarations">;
def UnguardedAvailabilityNew : DiagGroup<"unguarded-availability-new">;
@ -144,10 +168,18 @@ def DeprecatedVolatile : DiagGroup<"deprecated-volatile">;
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
[CXX11CompatDeprecatedWritableStr]>;
// FIXME: Why is DeprecatedImplementations not in this group?
def Deprecated : DiagGroup<"deprecated", [DeprecatedAttributes,
def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
DeprecatedArrayCompare,
DeprecatedAttributes,
DeprecatedCommaSubscript,
DeprecatedCopy,
DeprecatedCopyDtor,
DeprecatedDeclarations,
DeprecatedDynamicExceptionSpec,
DeprecatedEnumCompare,
DeprecatedEnumCompareConditional,
DeprecatedEnumEnumConversion,
DeprecatedEnumFloatConversion,
DeprecatedIncrementBool,
DeprecatedRegister,
DeprecatedThisCapture,
@ -568,9 +600,6 @@ def CoveredSwitchDefault : DiagGroup<"covered-switch-default">;
def SwitchBool : DiagGroup<"switch-bool">;
def SwitchEnum : DiagGroup<"switch-enum">;
def Switch : DiagGroup<"switch">;
def EnumCompareConditional : DiagGroup<"enum-compare-conditional">;
def EnumCompareSwitch : DiagGroup<"enum-compare-switch">;
def EnumCompare : DiagGroup<"enum-compare", [EnumCompareSwitch]>;
def ImplicitFallthroughPerFunction :
DiagGroup<"implicit-fallthrough-per-function">;
def ImplicitFallthrough : DiagGroup<"implicit-fallthrough",
@ -688,6 +717,7 @@ def ZeroLengthArray : DiagGroup<"zero-length-array">;
def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">;
def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">;
def Fallback : DiagGroup<"fallback">;
def MisleadingIndentation : DiagGroup<"misleading-indentation">;
// This covers both the deprecated case (in C++98)
// and the extension case (in C++11 onwards).
@ -811,6 +841,7 @@ def Move : DiagGroup<"move", [
]>;
def Extra : DiagGroup<"extra", [
DeprecatedCopy,
MissingFieldInitializers,
IgnoredQualifiers,
InitializerOverrides,
@ -826,11 +857,11 @@ def Most : DiagGroup<"most", [
CharSubscript,
Comment,
DeleteNonVirtualDtor,
ForLoopAnalysis,
Format,
Implicit,
InfiniteRecursion,
IntInBoolContext,
LoopAnalysis,
MismatchedTags,
MissingBraces,
Move,
@ -842,6 +873,7 @@ def Most : DiagGroup<"most", [
SizeofArrayArgument,
SizeofArrayDecay,
StringPlusInt,
TautologicalCompare,
Trigraphs,
Uninitialized,
UnknownPragmas,
@ -877,7 +909,7 @@ def Consumed : DiagGroup<"consumed">;
// Note that putting warnings in -Wall will not disable them by default. If a
// warning should be active _only_ when -Wall is passed in, mark it as
// DefaultIgnore in addition to putting it here.
def All : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool]>;
def All : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool, MisleadingIndentation]>;
// Warnings that should be in clang-cl /w4.
def : DiagGroup<"CL4", [All, Extra]>;
@ -1049,7 +1081,11 @@ def ASM : DiagGroup<"asm", [
def SourceUsesOpenMP : DiagGroup<"source-uses-openmp">;
def OpenMPClauses : DiagGroup<"openmp-clauses">;
def OpenMPLoopForm : DiagGroup<"openmp-loop-form">;
def OpenMPTarget : DiagGroup<"openmp-target">;
def OpenMPMapping : DiagGroup<"openmp-mapping">;
def OpenMPTarget : DiagGroup<"openmp-target", [OpenMPMapping]>;
def OpenMP : DiagGroup<"openmp", [
SourceUsesOpenMP, OpenMPClauses, OpenMPLoopForm, OpenMPTarget, OpenMPMapping
]>;
// Backend warnings.
def BackendInlineAsm : DiagGroup<"inline-asm">;
@ -1077,6 +1113,10 @@ def SerializedDiagnostics : DiagGroup<"serialized-diagnostics">;
// compiling CUDA C/C++ but which is not compatible with the CUDA spec.
def CudaCompat : DiagGroup<"cuda-compat">;
// A warning group for warnings about features supported by HIP but
// ignored by CUDA.
def HIPOnly : DiagGroup<"hip-only">;
// Warnings which cause linking of the runtime libraries like
// libc and the CRT to be skipped.
def AVRRtlibLinkingQuirks : DiagGroup<"avr-rtlib-linking-quirks">;

View File

@ -61,6 +61,13 @@ def warn_null_statement : Warning<
"remove unnecessary ';' to silence this warning">,
InGroup<ExtraSemiStmt>, DefaultIgnore;
def warn_misleading_indentation : Warning<
"misleading indentation; statement is not part of "
"the previous '%select{if|else|for|while}0'">,
InGroup<MisleadingIndentation>, DefaultIgnore;
def note_previous_statement : Note<
"previous statement is here">;
def ext_thread_before : Extension<"'__thread' before '%0'">;
def ext_keyword_as_ident : ExtWarn<
"keyword '%0' will be made available as an identifier "
@ -174,6 +181,13 @@ def err_function_declared_typedef : Error<
def err_at_defs_cxx : Error<"@defs is not supported in Objective-C++">;
def err_at_in_class : Error<"unexpected '@' in member specification">;
def err_unexpected_semi : Error<"unexpected ';' before %0">;
def err_unparenthesized_non_primary_expr_in_requires_clause : Error<
"parentheses are required around this expression in a requires clause">;
def note_unparenthesized_non_primary_expr_in_requires_clause : Note<
"parentheses are required around this expression in a requires clause">;
def err_potential_function_call_in_constraint_logical_or : Error<
"function call must be parenthesized to be considered part of the requires "
"clause">;
def err_expected_fn_body : Error<
"expected function body after function declarator">;
@ -258,7 +272,7 @@ def err_label_end_of_compound_statement : Error<
def err_address_of_label_outside_fn : Error<
"use of address-of-label extension outside of a function body">;
def err_asm_operand_wide_string_literal : Error<
"cannot use %select{unicode|wide}0 string literal in 'asm'">;
"cannot use %select{unicode|wide|an empty}0 string literal in 'asm'">;
def err_expected_selector_for_method : Error<
"expected selector for Objective-C method">;
def err_expected_property_name : Error<"expected property name">;
@ -302,6 +316,12 @@ def err_init_list_bin_op : Error<"initializer list cannot be used on the "
def warn_cxx98_compat_trailing_return_type : Warning<
"trailing return types are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_requires_clause_must_appear_after_trailing_return : Error<
"trailing return type must appear before trailing requires clause">;
def err_requires_clause_on_declarator_not_declaring_a_function : Error<
"trailing requires clause can only be used when declaring a function">;
def err_requires_clause_inside_parens : Error<
"trailing requires clause should be placed outside parentheses">;
def ext_auto_storage_class : ExtWarn<
"'auto' storage class specifier is not permitted in C++11, and will not "
"be supported in future releases">, InGroup<DiagGroup<"auto-storage-class">>;
@ -325,6 +345,8 @@ def err_for_range_expected_decl : Error<
def err_argument_required_after_attribute : Error<
"argument required after attribute">;
def err_missing_param : Error<"expected parameter declarator">;
def err_function_scope_depth_exceeded : Error<
"function scope depth exceeded maximum of %0">, DefaultFatal;
def err_missing_comma_before_ellipsis : Error<
"C requires a comma prior to the ellipsis in a variadic function type">;
def err_unexpected_typedef_ident : Error<
@ -871,7 +893,7 @@ def warn_cxx98_compat_lambda : Warning<
InGroup<CXX98Compat>, DefaultIgnore;
def err_lambda_missing_parens : Error<
"lambda requires '()' before %select{'mutable'|return type|"
"attribute specifier|'constexpr'|'consteval'}0">;
"attribute specifier|'constexpr'|'consteval'|'requires' clause}0">;
def err_lambda_decl_specifier_repeated : Error<
"%select{'mutable'|'constexpr'|'consteval'}0 cannot appear multiple times in a lambda declarator">;
def err_lambda_capture_misplaced_ellipsis : Error<
@ -1223,6 +1245,9 @@ def note_omp_declare_variant_ctx_used_here : Note<
def warn_omp_more_one_device_type_clause : Warning<
"more than one 'device_type' clause is specified">,
InGroup<OpenMPClauses>;
def err_omp_wrong_device_kind_trait : Error<
"unknown '%0' device kind trait in the 'device' context selector set, expected"
" one of 'host', 'nohost', 'cpu', 'gpu' or 'fpga'">;
// Pragma loop support.
def err_pragma_loop_missing_argument : Error<

View File

@ -551,9 +551,13 @@ def err_access_decl : Error<
"use using declarations instead">;
def warn_deprecated_copy_operation : Warning<
"definition of implicit copy %select{constructor|assignment operator}1 "
"for %0 is deprecated because it has a user-declared "
"%select{copy %select{assignment operator|constructor}1|destructor}2">,
InGroup<Deprecated>, DefaultIgnore;
"for %0 is deprecated because it has a user-declared copy "
"%select{assignment operator|constructor}1">,
InGroup<DeprecatedCopy>, DefaultIgnore;
def warn_deprecated_copy_dtor_operation : Warning<
"definition of implicit copy %select{constructor|assignment operator}1 "
"for %0 is deprecated because it has a user-declared destructor">,
InGroup<DeprecatedCopyDtor>, DefaultIgnore;
def warn_cxx17_compat_exception_spec_in_signature : Warning<
"mangled name of %0 will change in C++17 due to non-throwing exception "
"specification in function signature">, InGroup<CXX17CompatMangling>;
@ -575,21 +579,22 @@ def err_thread_non_global : Error<
def err_thread_unsupported : Error<
"thread-local storage is not supported for the current target">;
// FIXME: Combine fallout warnings to just one warning.
def warn_maybe_falloff_nonvoid_function : Warning<
"control may reach end of non-void function">,
"non-void function does not return a value in all control paths">,
InGroup<ReturnType>;
def warn_falloff_nonvoid_function : Warning<
"control reaches end of non-void function">,
"non-void function does not return a value">,
InGroup<ReturnType>;
def err_maybe_falloff_nonvoid_block : Error<
"control may reach end of non-void block">;
"non-void block does not return a value in all control paths">;
def err_falloff_nonvoid_block : Error<
"control reaches end of non-void block">;
"non-void block does not return a value">;
def warn_maybe_falloff_nonvoid_coroutine : Warning<
"control may reach end of coroutine; which is undefined behavior because the promise type %0 does not declare 'return_void()'">,
"non-void coroutine does not return a value in all control paths">,
InGroup<ReturnType>;
def warn_falloff_nonvoid_coroutine : Warning<
"control reaches end of coroutine; which is undefined behavior because the promise type %0 does not declare 'return_void()'">,
"non-void coroutine does not return a value">,
InGroup<ReturnType>;
def warn_suggest_noreturn_function : Warning<
"%select{function|method}0 %1 could be declared with attribute 'noreturn'">,
@ -987,6 +992,28 @@ def warn_objc_boxing_invalid_utf8_string : Warning<
"string is ill-formed as UTF-8 and will become a null %0 when boxed">,
InGroup<ObjCBoxing>;
def err_objc_direct_on_protocol : Error<
"'objc_direct' attribute cannot be applied to %select{methods|properties}0 "
"declared in an Objective-C protocol">;
def err_objc_direct_duplicate_decl : Error<
"%select{|direct }0method declaration conflicts "
"with previous %select{|direct }1declaration of method %2">;
def err_objc_direct_impl_decl_mismatch : Error<
"direct method was declared in %select{the primary interface|an extension|a category}0 "
"but is implemented in %select{the primary interface|a category|a different category}1">;
def err_objc_direct_missing_on_decl : Error<
"direct method implementation was previously declared not direct">;
def err_objc_direct_on_override : Error<
"methods that %select{override superclass methods|implement protocol requirements}0 cannot be direct">;
def err_objc_override_direct_method : Error<
"cannot override a method that is declared direct by a superclass">;
def warn_objc_direct_ignored : Warning<
"%0 attribute isn't implemented by this Objective-C runtime">,
InGroup<IgnoredAttributes>;
def warn_objc_direct_property_ignored : Warning<
"direct attribute on property %0 ignored (not implemented by this Objective-C runtime)">,
InGroup<IgnoredAttributes>;
def warn_conflicting_overriding_ret_types : Warning<
"conflicting return type in "
"declaration of %0%diff{: $ vs $|}1,2">,
@ -1072,6 +1099,7 @@ def warn_accessor_property_type_mismatch : Warning<
"type of property %0 does not match type of accessor %1">;
def note_conv_function_declared_at : Note<"type conversion function declared here">;
def note_method_declared_at : Note<"method %0 declared here">;
def note_direct_method_declared_at : Note<"direct method %0 declared here">;
def note_property_attribute : Note<"property %0 is declared "
"%select{deprecated|unavailable|partial}1 here">;
def err_setter_type_void : Error<"type of setter must be void">;
@ -1307,6 +1335,8 @@ def warn_multiple_selectors: Warning<
"several methods with selector %0 of mismatched types are found "
"for the @selector expression">,
InGroup<SelectorTypeMismatch>, DefaultIgnore;
def err_direct_selector_expression: Error<
"@selector expression formed with direct selector %0">;
def err_objc_kindof_nonobject : Error<
"'__kindof' specifier cannot be applied to non-object type %0">;
@ -1320,6 +1350,12 @@ def err_objc_method_unsupported_param_ret_type : Error<
def warn_messaging_unqualified_id : Warning<
"messaging unqualified id">, DefaultIgnore,
InGroup<DiagGroup<"objc-messaging-id">>;
def err_messaging_unqualified_id_with_direct_method : Error<
"messaging unqualified id with a method that is possibly direct">;
def err_messaging_super_with_direct_method : Error<
"messaging super with a direct method">;
def err_messaging_class_with_direct_method : Error<
"messaging a Class with a method that is possibly direct">;
// C++ declarations
def err_static_assert_expression_is_not_constant : Error<
@ -1702,7 +1738,10 @@ def note_ivar_decl : Note<"instance variable is declared here">;
def note_bitfield_decl : Note<"bit-field is declared here">;
def note_implicit_param_decl : Note<"%0 is an implicit parameter">;
def note_member_synthesized_at : Note<
"in implicit %sub{select_special_member_kind}0 for %1 "
"in %select{implicit|defaulted}0 %sub{select_special_member_kind}1 for %2 "
"first required here">;
def note_comparison_synthesized_at : Note<
"in defaulted %sub{select_defaulted_comparison_kind}0 for %1 "
"first required here">;
def err_missing_default_ctor : Error<
"%select{constructor for %1 must explicitly initialize the|"
@ -1894,7 +1933,8 @@ def err_lvalue_reference_bind_to_unrelated : Error<
"cannot bind to a value of unrelated type}1,2">;
def err_reference_bind_drops_quals : Error<
"binding reference %diff{of type $ to value of type $|to value}0,1 "
"%select{drops %3 qualifier%plural{1:|2:|4:|:s}4|changes address space}2">;
"%select{drops %3 qualifier%plural{1:|2:|4:|:s}4|changes address space|"
"not permitted due to incompatible qualifiers}2">;
def err_reference_bind_failed : Error<
"reference %diff{to %select{type|incomplete type}1 $ could not bind to an "
"%select{rvalue|lvalue}2 of type $|could not bind to %select{rvalue|lvalue}2 of "
@ -2542,9 +2582,47 @@ def err_non_constant_constraint_expression : Error<
"expression">;
def err_non_bool_atomic_constraint : Error<
"atomic constraint must be of type 'bool' (found %0)">;
def err_template_arg_list_constraints_not_satisfied : Error<
"constraints not satisfied for %select{class template|function template|variable template|alias template|"
"template template parameter|template}0 %1%2">;
def note_constraints_not_satisfied : Note<
"constraints not satisfied">;
def note_substituted_constraint_expr_is_ill_formed : Note<
"because substituted constraint expression is ill-formed%0">;
def note_atomic_constraint_evaluated_to_false : Note<
"%select{and |because }0'%1' evaluated to false">;
def note_concept_specialization_constraint_evaluated_to_false : Note<
"%select{and |because }0'%1' evaluated to false">;
def note_single_arg_concept_specialization_constraint_evaluated_to_false : Note<
"%select{and |because }0%1 does not satisfy %2">;
def note_atomic_constraint_evaluated_to_false_elaborated : Note<
"%select{and |because }0'%1' (%2 %3 %4) evaluated to false">;
def err_constrained_virtual_method : Error<
"virtual function cannot have a requires clause">;
def err_trailing_requires_clause_on_deduction_guide : Error<
"deduction guide cannot have a requires clause">;
def err_reference_to_function_with_unsatisfied_constraints : Error<
"invalid reference to function %0: constraints not satisfied">;
def note_ambiguous_atomic_constraints : Note<
"similar constraint expressions not considered equivalent; constraint "
"expressions cannot be considered equivalent unless they originate from the "
"same concept">;
def note_ambiguous_atomic_constraints_similar_expression : Note<
"similar constraint expression here">;
def err_template_different_requires_clause : Error<
"requires clause differs in template redeclaration">;
def err_template_different_type_constraint : Error<
"type constraint differs in template redeclaration">;
def err_template_template_parameter_not_at_least_as_constrained : Error<
"template template argument %0 is more constrained than template template "
"parameter %1">;
def err_type_constraint_non_type_concept : Error<
"concept named in type constraint is not a type concept">;
def err_type_constraint_missing_arguments : Error<
"%0 requires more than 1 template argument; provide the remaining arguments "
"explicitly to use it here">;
// C++11 char16_t/char32_t
def warn_cxx98_compat_unicode_type : Warning<
@ -2577,7 +2655,7 @@ def err_nsobject_attribute : Error<
def err_attributes_are_not_compatible : Error<
"%0 and %1 attributes are not compatible">;
def err_attribute_invalid_argument : Error<
"%select{'void'|a reference type|an array type|a non-vector or "
"%select{a reference type|an array type|a non-vector or "
"non-vectorizable scalar type}0 is an invalid argument to attribute %1">;
def err_attribute_wrong_number_arguments : Error<
"%0 attribute %plural{0:takes no arguments|1:takes one argument|"
@ -2594,6 +2672,8 @@ def err_attribute_requires_positive_integer : Error<
"integral compile time constant expression">;
def err_attribute_requires_opencl_version : Error<
"%0 attribute requires OpenCL version %1%select{| or above}2">;
def err_invalid_branch_protection_spec : Error<
"invalid or misplaced branch protection specification '%0'">;
def warn_unsupported_target_attribute
: Warning<"%select{unsupported|duplicate}0%select{| architecture}1 '%2' in"
" the 'target' attribute string; 'target' attribute ignored">,
@ -2854,6 +2934,9 @@ def err_alignment_not_power_of_two : Error<
def err_alignment_dependent_typedef_name : Error<
"requested alignment is dependent but declaration is not dependent">;
def warn_alignment_builtin_useless : Warning<
"%select{aligning a value|the result of checking whether a value is aligned}0"
" to 1 byte is %select{a no-op|always true}0">, InGroup<TautologicalCompare>;
def err_attribute_aligned_too_great : Error<
"requested alignment must be %0 bytes or smaller">;
def warn_assume_aligned_too_great
@ -3069,6 +3152,8 @@ def warn_declspec_allocator_nonpointer : Warning<
def err_cconv_incomplete_param_type : Error<
"parameter %0 must have a complete type to use function %1 with the %2 "
"calling convention">;
def err_attribute_output_parameter : Error<
"attribute only applies to output parameters">;
def ext_cannot_use_trivial_abi : ExtWarn<
"'trivial_abi' cannot be applied to %0">, InGroup<IgnoredAttributes>;
@ -3604,6 +3689,15 @@ def err_attribute_overloadable_no_prototype : Error<
def err_attribute_overloadable_multiple_unmarked_overloads : Error<
"at most one overload for a given name may lack the 'overloadable' "
"attribute">;
def warn_attribute_no_builtin_invalid_builtin_name : Warning<
"'%0' is not a valid builtin name for %1">,
InGroup<DiagGroup<"invalid-no-builtin-names">>;
def err_attribute_no_builtin_wildcard_or_builtin_name : Error<
"empty %0 cannot be composed with named ones">;
def err_attribute_no_builtin_on_non_definition : Error<
"%0 attribute is permitted on definitions only">;
def err_attribute_no_builtin_on_defaulted_deleted_function : Error<
"%0 attribute has no effect on defaulted or deleted functions">;
def warn_ns_attribute_wrong_return_type : Warning<
"%0 attribute only applies to %select{functions|methods|properties}1 that "
"return %select{an Objective-C object|a pointer|a non-retainable pointer}2">,
@ -3776,6 +3870,7 @@ def select_ovl_candidate_kind : TextSubstitution<
"constructor (the implicit move constructor)|"
"function (the implicit copy assignment operator)|"
"function (the implicit move assignment operator)|"
"function (the implicit 'operator==' for this 'operator<=>)'|"
"inherited constructor}0%select{| template| %2}1">;
def note_ovl_candidate : Note<
@ -3788,10 +3883,9 @@ def note_ovl_candidate : Note<
"| has different qualifiers (expected %5 but found %6)"
"| has different exception specification}4">;
def note_ovl_candidate_explicit_forbidden : Note<
"candidate %0 ignored: cannot be explicit">;
def note_explicit_bool_resolved_to_true : Note<
"explicit(bool) specifier resolved to true">;
def note_ovl_candidate_explicit : Note<
"explicit %select{constructor|conversion function|deduction guide}0 "
"is not a candidate%select{| (explicit specifier evaluates to true)}1">;
def note_ovl_candidate_inherited_constructor : Note<
"constructor from base class %0 inherited here">;
def note_ovl_candidate_inherited_constructor_slice : Note<
@ -3807,12 +3901,14 @@ def note_ovl_candidate_bad_deduction : Note<
"candidate template ignored: failed template argument deduction">;
def note_ovl_candidate_incomplete_deduction : Note<"candidate template ignored: "
"couldn't infer template argument %0">;
def note_ovl_candidate_incomplete_deduction_pack : Note<"candidate template ignored: "
def note_ovl_candidate_incomplete_deduction_pack : Note<
"candidate template ignored: "
"deduced too few arguments for expanded pack %0; no argument for %ordinal1 "
"expanded parameter in deduced argument pack %2">;
def note_ovl_candidate_inconsistent_deduction : Note<
"candidate template ignored: deduced conflicting %select{types|values|"
"templates}0 for parameter %1%diff{ ($ vs. $)|}2,3">;
"candidate template ignored: deduced %select{conflicting types|"
"conflicting values|conflicting templates|packs of different lengths}0 "
"for parameter %1%diff{ ($ vs. $)|}2,3">;
def note_ovl_candidate_inconsistent_deduction_types : Note<
"candidate template ignored: deduced values %diff{"
"of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|"
@ -3820,6 +3916,8 @@ def note_ovl_candidate_inconsistent_deduction_types : Note<
def note_ovl_candidate_explicit_arg_mismatch_named : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0">;
def note_ovl_candidate_unsatisfied_constraints : Note<
"candidate template ignored: constraints not satisfied%0">;
def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for %ordinal0 template parameter">;
@ -3848,6 +3946,9 @@ def note_ovl_candidate_disabled_by_extension : Note<
def err_addrof_function_disabled_by_enable_if_attr : Error<
"cannot take address of function %0 because it has one or more "
"non-tautological enable_if conditions">;
def err_addrof_function_constraints_not_satisfied : Error<
"cannot take address of function %0 because its constraints are not "
"satisfied">;
def note_addrof_ovl_candidate_disabled_by_enable_if_attr : Note<
"candidate function made ineligible by enable_if">;
def note_ovl_candidate_deduced_mismatch : Note<
@ -3920,8 +4021,12 @@ def note_ovl_candidate_bad_lvalue : Note<
"%select{%ordinal4 argument|object argument}3">;
def note_ovl_candidate_bad_addrspace : Note<
"candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
"address space mismatch in %select{%ordinal6|'this'}5 argument (%3), "
"parameter type must be %4">;
"cannot %select{pass pointer to|bind reference in}5 %3 "
"%select{as a pointer to|to object in}5 %4 in %ordinal6 "
"argument">;
def note_ovl_candidate_bad_addrspace_this : Note<
"candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
"'this' object is in %3, but method expects object in %4">;
def note_ovl_candidate_bad_gc : Note<
"candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
"%select{%ordinal7|'this'}6 argument (%3) has %select{no|__weak|__strong}4 "
@ -3957,6 +4062,9 @@ def note_ovl_candidate_bad_target : Note<
"call to "
"%select{__device__|__global__|__host__|__host__ __device__|invalid}3 function from"
" %select{__device__|__global__|__host__|__host__ __device__|invalid}4 function">;
def note_ovl_candidate_constraints_not_satisfied : Note<
"candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: constraints "
"not satisfied">;
def note_implicit_member_target_infer_collision : Note<
"implicit %sub{select_special_member_kind}0 inferred target collision: call to both "
"%select{__device__|__global__|__host__|__host__ __device__}1 and "
@ -4004,7 +4112,10 @@ def err_ovl_deleted_oper : Error<
"overload resolution selected deleted operator '%0'">;
def err_ovl_deleted_special_oper : Error<
"object of type %0 cannot be %select{constructed|copied|moved|assigned|"
"assigned|destroyed}1 because its %sub{select_special_member_kind}1 is implicitly deleted">;
"assigned|destroyed}1 because its %sub{select_special_member_kind}1 is "
"implicitly deleted">;
def err_ovl_deleted_comparison : Error<
"object of type %0 cannot be compared because its %1 is implicitly deleted">;
def err_ovl_rewrite_equalequal_not_bool : Error<
"return type %0 of selected 'operator==' function for rewritten "
"'%1' comparison is not 'bool'">;
@ -4512,8 +4623,21 @@ def note_template_default_arg_checking : Note<
"while checking a default template argument used here">;
def note_concept_specialization_here : Note<
"while checking the satisfaction of concept '%0' requested here">;
def note_checking_constraints_for_template_id_here : Note<
"while checking constraint satisfaction for template '%0' required here">;
def note_checking_constraints_for_var_spec_id_here : Note<
"while checking constraint satisfaction for variable template "
"partial specialization '%0' required here">;
def note_checking_constraints_for_class_spec_id_here : Note<
"while checking constraint satisfaction for class template partial "
"specialization '%0' required here">;
def note_constraint_substitution_here : Note<
"while substituting template arguments into constraint expression here">;
def note_constraint_normalization_here : Note<
"while calculating associated constraint of template '%0' here">;
def note_parameter_mapping_substitution_here : Note<
"while substituting into concept arguments here; substitution failures not "
"allowed in concept arguments">;
def note_instantiation_contexts_suppressed : Note<
"(skipping %0 context%s0 in backtrace; use -ftemplate-backtrace-limit=0 to "
"see all)">;
@ -4677,8 +4801,9 @@ def note_template_declared_here : Note<
"%select{function template|class template|variable template"
"|type alias template|template template parameter}0 "
"%1 declared here">;
def err_alias_template_expansion_into_fixed_list : Error<
"pack expansion used as argument for non-pack parameter of alias template">;
def err_template_expansion_into_fixed_list : Error<
"pack expansion used as argument for non-pack parameter of %select{alias "
"template|concept}0">;
def note_parameter_type : Note<
"parameter of type %0 is declared here">;
@ -4705,8 +4830,8 @@ def err_unexpanded_parameter_pack : Error<
"size|static assertion|fixed underlying type|enumerator value|"
"using declaration|friend declaration|qualifier|initializer|default argument|"
"non-type template parameter type|exception type|partial specialization|"
"__if_exists name|__if_not_exists name|lambda|block}0 contains"
"%plural{0: an|:}1 unexpanded parameter pack"
"__if_exists name|__if_not_exists name|lambda|block|type constraint}0 "
"contains%plural{0: an|:}1 unexpanded parameter pack"
"%plural{0:|1: %2|2:s %2 and %3|:s %2, %3, ...}1">;
def err_pack_expansion_without_parameter_packs : Error<
@ -6108,6 +6233,8 @@ def ext_typecheck_ordered_comparison_of_pointer_and_zero : Extension<
"ordered comparison between pointer and zero (%0 and %1) is an extension">;
def err_typecheck_ordered_comparison_of_pointer_and_zero : Error<
"ordered comparison between pointer and zero (%0 and %1)">;
def err_typecheck_three_way_comparison_of_pointer_and_zero : Error<
"three-way comparison between pointer and zero">;
def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
"ordered comparison of function pointers (%0 and %1)">,
InGroup<DiagGroup<"ordered-compare-function-pointers">>;
@ -6137,6 +6264,52 @@ def err_typecheck_op_on_nonoverlapping_address_space_pointers : Error<
"%diff{ ($ and $)|}0,1}2"
" which are pointers to non-overlapping address spaces">;
def select_arith_conv_kind : TextSubstitution<
"%select{arithmetic between|bitwise operation between|comparison of|"
"conditional expression between|compound assignment of}0">;
def warn_arith_conv_enum_float : Warning<
"%sub{select_arith_conv_kind}0 "
"%select{floating-point|enumeration}1 type %2 "
"%plural{2:with|4:from|:and}0 "
"%select{enumeration|floating-point}1 type %3">,
InGroup<EnumFloatConversion>, DefaultIgnore;
def warn_arith_conv_enum_float_cxx2a : Warning<
"%sub{select_arith_conv_kind}0 "
"%select{floating-point|enumeration}1 type %2 "
"%plural{2:with|4:from|:and}0 "
"%select{enumeration|floating-point}1 type %3 is deprecated">,
InGroup<DeprecatedEnumFloatConversion>;
def warn_arith_conv_mixed_enum_types : Warning<
"%sub{select_arith_conv_kind}0 "
"different enumeration types%diff{ ($ and $)|}1,2">,
InGroup<EnumEnumConversion>, DefaultIgnore;
def warn_arith_conv_mixed_enum_types_cxx2a : Warning<
"%sub{select_arith_conv_kind}0 "
"different enumeration types%diff{ ($ and $)|}1,2 is deprecated">,
InGroup<DeprecatedEnumEnumConversion>;
def warn_arith_conv_mixed_anon_enum_types : Warning<
warn_arith_conv_mixed_enum_types.Text>,
InGroup<AnonEnumEnumConversion>, DefaultIgnore;
def warn_arith_conv_mixed_anon_enum_types_cxx2a : Warning<
warn_arith_conv_mixed_enum_types_cxx2a.Text>,
InGroup<DeprecatedAnonEnumEnumConversion>;
def warn_conditional_mixed_enum_types : Warning<
warn_arith_conv_mixed_enum_types.Text>,
InGroup<EnumCompareConditional>, DefaultIgnore;
def warn_conditional_mixed_enum_types_cxx2a : Warning<
warn_arith_conv_mixed_enum_types_cxx2a.Text>,
InGroup<DeprecatedEnumCompareConditional>;
def warn_comparison_mixed_enum_types : Warning<
warn_arith_conv_mixed_enum_types.Text>,
InGroup<EnumCompare>;
def warn_comparison_mixed_enum_types_cxx2a : Warning<
warn_arith_conv_mixed_enum_types_cxx2a.Text>,
InGroup<DeprecatedEnumCompare>;
def warn_comparison_of_mixed_enum_types_switch : Warning<
"comparison of different enumeration types in switch statement"
"%diff{ ($ and $)|}0,1">,
InGroup<EnumCompareSwitch>;
def err_typecheck_assign_const : Error<
"%select{"
"cannot assign to return value because function %1 returns a const value|"
@ -6190,18 +6363,6 @@ def warn_left_shift_always : Warning<
"converting the result of '<<' to a boolean always evaluates "
"to %select{false|true}0">,
InGroup<TautologicalConstantCompare>;
def warn_comparison_of_mixed_enum_types : Warning<
"comparison of two values with different enumeration types"
"%diff{ ($ and $)|}0,1">,
InGroup<EnumCompare>;
def warn_conditional_mixed_enum_types : Warning<
"enumeration type mismatch in conditional expression"
"%diff{ ($ and $)|}0,1">,
InGroup<EnumCompareConditional>, DefaultIgnore;
def warn_comparison_of_mixed_enum_types_switch : Warning<
"comparison of two values with different enumeration types in switch statement"
"%diff{ ($ and $)|}0,1">,
InGroup<EnumCompareSwitch>;
def warn_null_in_arithmetic_operation : Warning<
"use of NULL in arithmetic operation">,
InGroup<NullArithmetic>;
@ -6430,6 +6591,8 @@ def warn_objc_unsafe_perform_selector : Warning<
InGroup<DiagGroup<"objc-unsafe-perform-selector">>;
def note_objc_unsafe_perform_selector_method_declared_here : Note<
"method %0 that returns %1 declared here">;
def err_attribute_arm_mve_alias : Error<
"'__clang_arm_mve_alias' attribute can only be applied to an ARM MVE builtin">;
def warn_setter_getter_impl_required : Warning<
"property %0 requires method %1 to be defined - "
@ -6557,10 +6720,10 @@ def err_downcast_from_inaccessible_base : Error<
def err_upcast_to_inaccessible_base : Error<
"cannot cast %0 to its %select{private|protected}2 base class %1">;
def err_bad_dynamic_cast_not_ref_or_ptr : Error<
"%0 is not a reference or pointer">;
def err_bad_dynamic_cast_not_class : Error<"%0 is not a class">;
def err_bad_dynamic_cast_incomplete : Error<"%0 is an incomplete type">;
def err_bad_dynamic_cast_not_ptr : Error<"%0 is not a pointer">;
"invalid target type %0 for dynamic_cast; target type must be a reference or pointer type to a defined class">;
def err_bad_dynamic_cast_not_class : Error<"%0 is not a class type">;
def err_bad_cast_incomplete : Error<"%0 is an incomplete type">;
def err_bad_dynamic_cast_not_ptr : Error<"cannot use dynamic_cast to convert from %0 to %1">;
def err_bad_dynamic_cast_not_polymorphic : Error<"%0 is not polymorphic">;
// Other C++ expressions
@ -6792,6 +6955,14 @@ def err_conditional_vector_size : Error<
def err_conditional_vector_element_size : Error<
"vector condition type %0 and result type %1 do not have elements of the "
"same size">;
def err_conditional_vector_has_void : Error<
"GNU vector conditional operand cannot be %select{void|a throw expression}0">;
def err_conditional_vector_operand_type
: Error<"%select{enumeration|extended vector}0 type %1 is not allowed in a "
"vector conditional">;
def err_conditional_vector_mismatched_vectors
: Error<"vector operands to the vector conditional must be the same type "
"%diff{($ and $)|}0,1}">;
def err_throw_incomplete : Error<
"cannot throw object of incomplete type %0">;
@ -6847,10 +7018,10 @@ let CategoryName = "Lambda Issue" in {
def err_noreturn_lambda_has_return_expr : Error<
"lambda declared 'noreturn' should not return">;
def warn_maybe_falloff_nonvoid_lambda : Warning<
"control may reach end of non-void lambda">,
"non-void lambda does not return a value in all control paths">,
InGroup<ReturnType>;
def warn_falloff_nonvoid_lambda : Warning<
"control reaches end of non-void lambda">,
"non-void lambda does not return a value">,
InGroup<ReturnType>;
def err_access_lambda_capture : Error<
// The ERRORs represent other special members that aren't constructors, in
@ -7391,10 +7562,8 @@ def err_atomic_op_needs_trivial_copy : Error<
def err_atomic_op_needs_atomic_int_or_ptr : Error<
"address argument to atomic operation must be a pointer to %select{|atomic }0"
"integer or pointer (%1 invalid)">;
def err_atomic_op_needs_int32_or_ptr : Error<
"address argument to atomic operation must be a pointer to signed or unsigned 32-bit integer">;
def err_atomic_op_bitwise_needs_atomic_int : Error<
"address argument to bitwise atomic operation must be a pointer to "
def err_atomic_op_needs_atomic_int : Error<
"address argument to atomic operation must be a pointer to "
"%select{|atomic }0integer (%1 invalid)">;
def warn_atomic_op_has_invalid_memory_order : Warning<
"memory order argument to atomic operation is invalid">,
@ -8081,7 +8250,7 @@ def err_incorrect_defaulted_consteval : Error<
"cannot be consteval because implicit definition is not constexpr">;
def warn_defaulted_method_deleted : Warning<
"explicitly defaulted %sub{select_special_member_kind}0 is implicitly "
"deleted">, InGroup<DiagGroup<"defaulted-function-deleted">>;
"deleted">, InGroup<DefaultedFunctionDeleted>;
def err_out_of_line_default_deletes : Error<
"defaulting this %sub{select_special_member_kind}0 "
"would delete it after its first declaration">;
@ -8099,6 +8268,89 @@ def note_vbase_moved_here : Note<
"%select{%1 is a virtual base class of base class %2 declared here|"
"virtual base class %1 declared here}0">;
// C++20 defaulted comparisons
// This corresponds to values of Sema::DefaultedComparisonKind.
def select_defaulted_comparison_kind : TextSubstitution<
"%select{<ERROR>|equality|three-way|equality|relational}0 comparison "
"operator">;
def ext_defaulted_comparison : ExtWarn<
"defaulted comparison operators are a C++20 extension">, InGroup<CXX2a>;
def warn_cxx17_compat_defaulted_comparison : Warning<
"defaulted comparison operators are incompatible with C++ standards "
"before C++20">, InGroup<CXXPre2aCompat>, DefaultIgnore;
def err_defaulted_comparison_template : Error<
"comparison operator template cannot be defaulted">;
def err_defaulted_comparison_out_of_class : Error<
"%sub{select_defaulted_comparison_kind}0 can only be defaulted in a class "
"definition">;
def err_defaulted_comparison_param : Error<
"invalid parameter type for defaulted %sub{select_defaulted_comparison_kind}0"
"; found %1, expected %2%select{| or %4}3">;
def err_defaulted_comparison_param_mismatch : Error<
"parameters for defaulted %sub{select_defaulted_comparison_kind}0 "
"must have the same type%diff{ (found $ vs $)|}1,2">;
def err_defaulted_comparison_non_const : Error<
"defaulted member %sub{select_defaulted_comparison_kind}0 must be "
"const-qualified">;
def err_defaulted_comparison_return_type_not_bool : Error<
"return type for defaulted %sub{select_defaulted_comparison_kind}0 "
"must be 'bool', not %1">;
def err_defaulted_comparison_deduced_return_type_not_auto : Error<
"deduced return type for defaulted %sub{select_defaulted_comparison_kind}0 "
"must be 'auto', not %1">;
def warn_defaulted_comparison_deleted : Warning<
"explicitly defaulted %sub{select_defaulted_comparison_kind}0 is implicitly "
"deleted">, InGroup<DefaultedFunctionDeleted>;
def err_non_first_default_compare_deletes : Error<
"defaulting %select{this %sub{select_defaulted_comparison_kind}1|"
"the corresponding implicit 'operator==' for this defaulted 'operator<=>'}0 "
"would delete it after its first declaration">;
def note_defaulted_comparison_union : Note<
"defaulted %0 is implicitly deleted because "
"%2 is a %select{union-like class|union}1 with variant members">;
def note_defaulted_comparison_reference_member : Note<
"defaulted %0 is implicitly deleted because "
"class %1 has a reference member">;
def note_defaulted_comparison_ambiguous : Note<
"defaulted %0 is implicitly deleted because implied %select{|'==' |'<' }1"
"comparison %select{|for member %3 |for base class %3 }2is ambiguous">;
def note_defaulted_comparison_inaccessible : Note<
"defaulted %0 is implicitly deleted because it would invoke a "
"%select{private|protected}3 %4%select{ member of %6|"
" member of %6 to compare member %2| to compare base class %2}1">;
def note_defaulted_comparison_calls_deleted : Note<
"defaulted %0 is implicitly deleted because it would invoke a deleted "
"comparison function%select{| for member %2| for base class %2}1">;
def note_defaulted_comparison_no_viable_function : Note<
"defaulted %0 is implicitly deleted because there is no viable comparison "
"function%select{| for member %2| for base class %2}1">;
def note_defaulted_comparison_no_viable_function_synthesized : Note<
"three-way comparison cannot be synthesized because there is no viable "
"function for %select{'=='|'<'}0 comparison">;
def note_defaulted_comparison_not_rewritten_callee : Note<
"defaulted %0 is implicitly deleted because this non-rewritten comparison "
"function would be the best match for the comparison">;
def note_defaulted_comparison_cannot_deduce : Note<
"return type of defaulted 'operator<=>' cannot be deduced because "
"return type %2 of three-way comparison for %select{|member|base class}0 %1 "
"is not a standard comparison category type">;
def note_defaulted_comparison_cannot_deduce_callee : Note<
"selected 'operator<=>' for %select{|member|base class}0 %1 declared here">;
def err_incorrect_defaulted_comparison_constexpr : Error<
"defaulted definition of %select{%sub{select_defaulted_comparison_kind}1|"
"three-way comparison operator}0 "
"cannot be declared %select{constexpr|consteval}2 because "
"%select{it|the corresponding implicit 'operator=='}0 "
"invokes a non-constexpr comparison function">;
def note_defaulted_comparison_not_constexpr : Note<
"non-constexpr comparison function would be used to compare "
"%select{|member %1|base class %1}0">;
def note_defaulted_comparison_not_constexpr_here : Note<
"non-constexpr comparison function declared here">;
def note_in_declaration_of_implicit_equality_comparison : Note<
"while declaring the corresponding implicit 'operator==' "
"for this defaulted 'operator<=>'">;
def ext_implicit_exception_spec_mismatch : ExtWarn<
"function previously declared with an %select{explicit|implicit}0 exception "
"specification redeclared with an %select{implicit|explicit}0 exception "
@ -8342,10 +8594,14 @@ def warn_comparison_bitwise_or : Warning<
def warn_tautological_overlap_comparison : Warning<
"overlapping comparisons always evaluate to %select{false|true}0">,
InGroup<TautologicalOverlapCompare>, DefaultIgnore;
def warn_depr_array_comparison : Warning<
"comparison between two arrays is deprecated; "
"to compare array addresses, use unary '+' to decay operands to pointers">,
InGroup<DeprecatedArrayCompare>;
def warn_stringcompare : Warning<
"result of comparison against %select{a string literal|@encode}0 is "
"unspecified (use strncmp instead)">,
"unspecified (use an explicit string comparison function instead)">,
InGroup<StringCompare>;
def warn_identity_field_assign : Warning<
@ -8635,6 +8891,12 @@ def warn_argument_invalid_range : Warning<
InGroup<DiagGroup<"argument-outside-range">>;
def err_argument_not_multiple : Error<
"argument should be a multiple of %0">;
def err_argument_not_power_of_2 : Error<
"argument should be a power of 2">;
def err_argument_not_shifted_byte : Error<
"argument should be an 8-bit value shifted by a multiple of 8 bits">;
def err_argument_not_shifted_byte_or_xxff : Error<
"argument should be an 8-bit value shifted by a multiple of 8 bits, or in the form 0x??FF">;
def warn_neon_vector_initializer_non_portable : Warning<
"vector initializers are not compatible with NEON intrinsics in big endian "
"mode">, InGroup<DiagGroup<"nonportable-vector-initialization">>;
@ -8653,6 +8915,12 @@ def err_32_bit_builtin_64_bit_tgt : Error<
"this builtin is only available on 32-bit targets">;
def err_builtin_x64_aarch64_only : Error<
"this builtin is only available on x86-64 and aarch64 targets">;
def err_mips_builtin_requires_dsp : Error<
"this builtin requires 'dsp' ASE, please use -mdsp">;
def err_mips_builtin_requires_dspr2 : Error<
"this builtin requires 'dsp r2' ASE, please use -mdspr2">;
def err_mips_builtin_requires_msa : Error<
"this builtin requires 'msa' ASE, please use -mmsa">;
def err_ppc_builtin_only_on_pwr7 : Error<
"this builtin is only valid on POWER7 or later CPUs">;
def err_x86_builtin_invalid_rounding : Error<
@ -8878,7 +9146,7 @@ def err_unknown_any_function : Error<
"function %0 with unknown type must be given a function type">;
def err_filter_expression_integral : Error<
"filter expression type should be an integral value not %0">;
"filter expression has non-integral type %0">;
def err_non_asm_stmt_in_naked_function : Error<
"non-ASM statement in naked function is not supported">;
@ -9109,8 +9377,12 @@ def err_omp_threadprivate_incomplete_type : Error<
"threadprivate variable with incomplete type %0">;
def err_omp_no_dsa_for_variable : Error<
"variable %0 must have explicitly specified data sharing attributes">;
def err_omp_defaultmap_no_attr_for_variable : Error<
"variable %0 must have explicitly specified data sharing attributes, data mapping attributes, or in an is_device_ptr clause">;
def note_omp_default_dsa_none : Note<
"explicit data sharing attribute requested here">;
def note_omp_defaultmap_attr_none : Note<
"explicit data sharing attribute, data mapping attribute, or is_device_ptr clause requested here">;
def err_omp_wrong_dsa : Error<
"%0 variable cannot be %1">;
def err_omp_variably_modified_type_not_supported : Error<
@ -9187,8 +9459,8 @@ def err_omp_aligned_expected_array_or_ptr : Error<
"argument of aligned clause should be array"
"%select{ or pointer|, pointer, reference to array or reference to pointer}1"
", not %0">;
def err_omp_aligned_twice : Error<
"%select{a variable|a parameter|'this'}0 cannot appear in more than one aligned clause">;
def err_omp_used_in_clause_twice : Error<
"%select{a variable|a parameter|'this'}0 cannot appear in more than one %1 clause">;
def err_omp_local_var_in_threadprivate_init : Error<
"variable with local storage in initial value of threadprivate variable">;
def err_omp_loop_not_canonical_init : Error<
@ -9199,7 +9471,7 @@ def ext_omp_loop_not_canonical_init : ExtWarn<
"('var = init' or 'T var = init')">, InGroup<OpenMPLoopForm>;
def err_omp_loop_not_canonical_cond : Error<
"condition of OpenMP for loop must be a relational comparison "
"('<', '<=', '>', %select{or '>='|'>=', or '!='}0) of loop variable %1">;
"('<', '<=', '>', %select{or '>='|'>=', or '!='}0) of loop variable %1">;
def err_omp_loop_not_canonical_incr : Error<
"increment clause of OpenMP for loop must perform simple addition "
"or subtraction on loop variable %0">;
@ -9254,7 +9526,7 @@ def err_omp_prohibited_region : Error<
"; perhaps you forget to enclose 'omp %3' directive into a target region?|"
"; perhaps you forget to enclose 'omp %3' directive into a teams region?}2">;
def err_omp_prohibited_region_simd : Error<
"OpenMP constructs may not be nested inside a simd region">;
"OpenMP constructs may not be nested inside a simd region%select{| except for ordered simd, simd or atomic directive}0">;
def err_omp_prohibited_region_atomic : Error<
"OpenMP constructs may not be nested inside an atomic region">;
def err_omp_prohibited_region_critical_same_name : Error<
@ -9365,7 +9637,7 @@ def err_omp_wrong_if_directive_name_modifier : Error<
def err_omp_no_more_if_clause : Error<
"no more 'if' clause is allowed">;
def err_omp_unnamed_if_clause : Error<
"expected %select{|one of}0 %1 directive name modifier%select{|s}0">;
"expected%select{| one of}0 %1 directive name modifier%select{|s}0">;
def note_omp_previous_named_if_clause : Note<
"previous clause with directive name modifier specified here">;
def err_omp_ordered_directive_with_param : Error<
@ -9410,6 +9682,8 @@ def err_omp_depend_sink_expected_plus_minus : Error<
"expected '+' or '-' operation">;
def err_omp_depend_sink_source_not_allowed : Error<
"'depend(%select{source|sink:vec}0)' clause%select{|s}0 cannot be mixed with 'depend(%select{sink:vec|source}0)' clause%select{s|}0">;
def err_omp_depend_zero_length_array_section_not_allowed : Error<
"zero-length array section is not allowed in 'depend' clause">;
def err_omp_linear_ordered : Error<
"'linear' clause cannot be specified along with 'ordered' clause with a parameter">;
def err_omp_unexpected_schedule_modifier : Error<
@ -9449,8 +9723,8 @@ def err_omp_reduction_vla_unsupported : Error<
def err_omp_linear_distribute_var_non_loop_iteration : Error<
"only loop iteration variables are allowed in 'linear' clause in distribute directives">;
def warn_omp_non_trivial_type_mapped : Warning<
"Non-trivial type %0 is mapped, only trivial types are guaranteed to be mapped correctly">,
InGroup<OpenMPTarget>;
"Type %0 is not trivially copyable and not guaranteed to be mapped correctly">,
InGroup<OpenMPMapping>;
def err_omp_requires_clause_redeclaration : Error <
"Only one %0 clause can appear on a requires directive in a single translation unit">;
def note_omp_requires_previous_clause : Note <
@ -9519,10 +9793,6 @@ def warn_omp_declare_variant_after_used : Warning<
def warn_omp_declare_variant_after_emitted : Warning<
"'#pragma omp declare variant' cannot be applied to the function that was defined already;"
" the original function might be used">, InGroup<SourceUsesOpenMP>;
def err_omp_declare_variant_noproto : Error<
"function with '#pragma omp declare variant' must have a prototype">;
def note_omp_declare_variant_specified_here : Note<
"'#pragma omp declare variant' for function specified here">;
def err_omp_declare_variant_doesnt_support : Error<
"'#pragma omp declare variant' does not "
"support %select{function templates|virtual functions|"
@ -9539,6 +9809,11 @@ def warn_omp_declare_variant_marked_as_declare_variant : Warning<
"variant function in '#pragma omp declare variant' is itself marked as '#pragma omp declare variant'"
>, InGroup<SourceUsesOpenMP>;
def note_omp_marked_declare_variant_here : Note<"marked as 'declare variant' here">;
def err_omp_one_defaultmap_each_category: Error<
"at most one defaultmap clause for each variable-category can appear on the directive">;
def err_omp_lastprivate_conditional_non_scalar : Error<
"expected list item of scalar type in 'lastprivate' clause with 'conditional' modifier"
>;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
@ -9966,8 +10241,8 @@ def warn_dispatch_body_ignored : Warning<
// three-way comparison operator diagnostics
def err_implied_comparison_category_type_not_found : Error<
"cannot deduce return type of 'operator<=>' because type '%0' was not found; "
"include <compare>">;
"cannot %select{use builtin operator '<=>'|default 'operator<=>'}1 "
"because type '%0' was not found; include <compare>">;
def err_spaceship_argument_narrowing : Error<
"argument to 'operator<=>' "
"%select{cannot be narrowed from type %1 to %2|"
@ -9980,6 +10255,8 @@ def err_std_compare_type_not_supported : Error<
"the type does not have the expected form}1">;
def note_rewriting_operator_as_spaceship : Note<
"while rewriting comparison as call to 'operator<=>' declared here">;
def err_three_way_vector_comparison : Error<
"three-way comparison between vectors is not supported">;
// Memory Tagging Extensions (MTE) diagnostics
def err_memtag_arg_null_or_pointer : Error<
@ -10013,4 +10290,19 @@ def err_bit_cast_non_trivially_copyable : Error<
"__builtin_bit_cast %select{source|destination}0 type must be trivially copyable">;
def err_bit_cast_type_size_mismatch : Error<
"__builtin_bit_cast source size does not equal destination size (%0 vs %1)">;
// SYCL-specific diagnostics
def warn_sycl_kernel_num_of_template_params : Warning<
"'sycl_kernel' attribute only applies to a function template with at least"
" two template parameters">, InGroup<IgnoredAttributes>;
def warn_sycl_kernel_invalid_template_param_type : Warning<
"template parameter of a function template with the 'sycl_kernel' attribute"
" cannot be a non-type template parameter">, InGroup<IgnoredAttributes>;
def warn_sycl_kernel_num_of_function_params : Warning<
"function template with 'sycl_kernel' attribute must have a single parameter">,
InGroup<IgnoredAttributes>;
def warn_sycl_kernel_return_type : Warning<
"function template with 'sycl_kernel' attribute must have a 'void' return type">,
InGroup<IgnoredAttributes>;
} // end of sema component.

View File

@ -74,6 +74,8 @@ def note_module_file_imported_by : Note<
"imported by %select{|module '%2' in }1'%0'">;
def err_module_file_not_module : Error<
"AST file '%0' was not built as a module">, DefaultFatal;
def err_module_file_missing_top_level_submodule : Error<
"module file '%0' is missing its top-level submodule">, DefaultFatal;
def remark_module_import : Remark<
"importing module '%0'%select{| into '%3'}2 from '%1'">,

View File

@ -222,8 +222,8 @@ class FileManager : public RefCountedBase<FileManager> {
llvm::BumpPtrAllocator>
SeenFileEntries;
/// The canonical names of directories.
llvm::DenseMap<const DirectoryEntry *, llvm::StringRef> CanonicalDirNames;
/// The canonical names of files and directories .
llvm::DenseMap<const void *, llvm::StringRef> CanonicalNames;
/// Storage for canonical names that we have computed.
llvm::BumpPtrAllocator CanonicalNameStorage;
@ -421,6 +421,13 @@ class FileManager : public RefCountedBase<FileManager> {
/// required, which is (almost) never.
StringRef getCanonicalName(const DirectoryEntry *Dir);
/// Retrieve the canonical name for a given file.
///
/// This is a very expensive operation, despite its results being cached,
/// and should only be used when the physical layout of the file system is
/// required, which is (almost) never.
StringRef getCanonicalName(const FileEntry *File);
void PrintStats() const;
};

View File

@ -384,6 +384,17 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
return getName().startswith("<#") && getName().endswith("#>");
}
/// Determine whether \p this is a name reserved for the implementation (C99
/// 7.1.3, C++ [lib.global.names]).
bool isReservedName(bool doubleUnderscoreOnly = false) const {
if (getLength() < 2)
return false;
const char *Name = getNameStart();
return Name[0] == '_' &&
(Name[1] == '_' ||
(Name[1] >= 'A' && Name[1] <= 'Z' && !doubleUnderscoreOnly));
}
/// Provide less than operator for lexicographical sorting.
bool operator<(const IdentifierInfo &RHS) const {
return getName() < RHS.getName();
@ -581,6 +592,8 @@ class IdentifierTable {
iterator end() const { return HashTable.end(); }
unsigned size() const { return HashTable.size(); }
iterator find(StringRef Name) const { return HashTable.find(Name); }
/// Print some statistics to stderr that indicate how well the
/// hashing is doing.
void PrintStats() const;

View File

@ -122,6 +122,7 @@ LANGOPT(WritableStrings , 1, 0, "writable string support")
LANGOPT(ConstStrings , 1, 0, "const-qualified string support")
ENUM_LANGOPT(LaxVectorConversions, LaxVectorConversionKind, 2,
LaxVectorConversionKind::All, "lax vector conversions")
LANGOPT(ConvergentFunctions, 1, 1, "Assume convergent functions")
LANGOPT(AltiVec , 1, 0, "AltiVec-style vector initializers")
LANGOPT(ZVector , 1, 0, "System z vector extensions")
LANGOPT(Exceptions , 1, 0, "exception handling")
@ -212,6 +213,7 @@ LANGOPT(OpenMPSimd , 1, 0, "Use SIMD only OpenMP support.")
LANGOPT(OpenMPUseTLS , 1, 0, "Use TLS for threadprivates or runtime calls")
LANGOPT(OpenMPIsDevice , 1, 0, "Generate code only for OpenMP target device")
LANGOPT(OpenMPCUDAMode , 1, 0, "Generate code for OpenMP pragmas in SIMT/SPMD mode")
LANGOPT(OpenMPIRBuilder , 1, 0, "Use the experimental OpenMP-IR-Builder codegen path.")
LANGOPT(OpenMPCUDAForceFullRuntime , 1, 0, "Force to use full runtime in all constructs when offloading to CUDA devices")
LANGOPT(OpenMPCUDANumSMs , 32, 0, "Number of SMs for CUDA devices.")
LANGOPT(OpenMPCUDABlocksPerSM , 32, 0, "Number of blocks per SM for CUDA devices.")
@ -224,6 +226,8 @@ LANGOPT(CUDAAllowVariadicFunctions, 1, 0, "allowing variadic functions in CUDA d
LANGOPT(CUDAHostDeviceConstexpr, 1, 1, "treating unattributed constexpr functions as __host__ __device__")
LANGOPT(CUDADeviceApproxTranscendentals, 1, 0, "using approximate transcendental functions")
LANGOPT(GPURelocatableDeviceCode, 1, 0, "generate relocatable device code")
LANGOPT(GPUAllowDeviceInit, 1, 0, "allowing device side global init functions for HIP")
LANGOPT(GPUMaxThreadsPerBlock, 32, 256, "default max threads per block for kernel launch bounds for HIP")
LANGOPT(SYCLIsDevice , 1, 0, "Generate code for SYCL device")
@ -253,6 +257,8 @@ LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating poi
LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
/// FP_CONTRACT mode (on/off/fast).
ENUM_LANGOPT(DefaultFPContractMode, FPContractModeKind, 2, FPC_Off, "FP contraction type")
ENUM_LANGOPT(FPRoundingMode, FPRoundingModeKind, 3, FPR_ToNearest, "FP Rounding Mode type")
ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type")
LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")
@ -295,14 +301,13 @@ BENIGN_LANGOPT(ConstexprStepLimit, 32, 1048576,
"maximum constexpr evaluation steps")
BENIGN_LANGOPT(EnableNewConstInterp, 1, 0,
"enable the experimental new constant interpreter")
BENIGN_LANGOPT(ForceNewConstInterp, 1, 0,
"force the use of the experimental new constant interpreter")
BENIGN_LANGOPT(BracketDepth, 32, 256,
"maximum bracket nesting depth")
BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0,
"if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.")
VALUE_LANGOPT(MSCompatibilityVersion, 32, 0, "Microsoft Visual C/C++ Version")
VALUE_LANGOPT(VtorDispMode, 2, 1, "How many vtordisps to insert")
ENUM_LANGOPT(VtorDispMode, MSVtorDispMode, 2, MSVtorDispMode::ForVBaseOverride,
"How many vtordisps to insert")
LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")

View File

@ -44,6 +44,10 @@ class LangOptionsBase {
#include "clang/Basic/LangOptions.def"
};
/// In the Microsoft ABI, this controls the placement of virtual displacement
/// members used to implement virtual inheritance.
enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable };
/// Keeps track of the various options that can be
/// enabled, which controls the dialect of C or C++ that is accepted.
class LangOptions : public LangOptionsBase {
@ -91,6 +95,8 @@ class LangOptions : public LangOptionsBase {
PPTMK_FullGeneralityVirtualInheritance
};
using MSVtorDispMode = clang::MSVtorDispMode;
enum DefaultCallingConvention {
DCC_None,
DCC_CDecl,
@ -184,6 +190,34 @@ class LangOptions : public LangOptionsBase {
FEA_On
};
// Values of the following enumerations correspond to metadata arguments
// specified for constrained floating-point intrinsics:
// http://llvm.org/docs/LangRef.html#constrained-floating-point-intrinsics.
/// Possible rounding modes.
enum FPRoundingModeKind {
/// Rounding to nearest, corresponds to "round.tonearest".
FPR_ToNearest,
/// Rounding toward -Inf, corresponds to "round.downward".
FPR_Downward,
/// Rounding toward +Inf, corresponds to "round.upward".
FPR_Upward,
/// Rounding toward zero, corresponds to "round.towardzero".
FPR_TowardZero,
/// Is determined by runtime environment, corresponds to "round.dynamic".
FPR_Dynamic
};
/// Possible floating point exception behavior.
enum FPExceptionModeKind {
/// Assume that floating-point exceptions are masked.
FPE_Ignore,
/// Transformations do not cause new exceptions but may hide some.
FPE_MayTrap,
/// Strictly preserve the floating-point exception semantics.
FPE_Strict
};
enum class LaxVectorConversionKind {
/// Permit no implicit vector bitcasts.
None,
@ -312,7 +346,7 @@ class LangOptions : public LangOptionsBase {
}
bool assumeFunctionsAreConvergent() const {
return (CUDA && CUDAIsDevice) || OpenCL;
return ConvergentFunctions;
}
/// Return the OpenCL C or C++ version as a VersionTuple.

View File

@ -446,6 +446,20 @@ class ObjCRuntime {
llvm_unreachable("bad kind");
}
/// Does this runtime supports direct dispatch
bool allowsDirectDispatch() const {
switch (getKind()) {
case FragileMacOSX: return false;
case MacOSX: return true;
case iOS: return true;
case WatchOS: return true;
case GCC: return false;
case GNUstep: return false;
case ObjFW: return false;
}
llvm_unreachable("bad kind");
}
/// Try to parse an Objective-C runtime specification from the given
/// string.
///

View File

@ -11,12 +11,6 @@
///
//===----------------------------------------------------------------------===//
#ifndef OPENMP_DIRECTIVE
# define OPENMP_DIRECTIVE(Name)
#endif
#ifndef OPENMP_DIRECTIVE_EXT
#define OPENMP_DIRECTIVE_EXT(Name, Str)
#endif
#ifndef OPENMP_CLAUSE
# define OPENMP_CLAUSE(Name, Class)
#endif
@ -44,6 +38,9 @@
#ifndef OPENMP_PARALLEL_FOR_SIMD_CLAUSE
# define OPENMP_PARALLEL_FOR_SIMD_CLAUSE(Name)
#endif
#ifndef OPENMP_PARALLEL_MASTER_CLAUSE
# define OPENMP_PARALLEL_MASTER_CLAUSE(Name)
#endif
#ifndef OPENMP_PARALLEL_SECTIONS_CLAUSE
# define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name)
#endif
@ -101,6 +98,9 @@
#ifndef OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE
# define OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(Name)
#endif
#ifndef OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE
# define OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(Name)
#endif
#ifndef OPENMP_CRITICAL_CLAUSE
# define OPENMP_CRITICAL_CLAUSE(Name)
#endif
@ -110,9 +110,6 @@
#ifndef OPENMP_DEFAULT_KIND
# define OPENMP_DEFAULT_KIND(Name)
#endif
#ifndef OPENMP_PROC_BIND_KIND
# define OPENMP_PROC_BIND_KIND(Name)
#endif
#ifndef OPENMP_SCHEDULE_KIND
#define OPENMP_SCHEDULE_KIND(Name)
#endif
@ -206,70 +203,23 @@
#ifndef OPENMP_DECLARE_VARIANT_CLAUSE
#define OPENMP_DECLARE_VARIANT_CLAUSE(Name)
#endif
#ifndef OPENMP_MATCH_KIND
#define OPENMP_MATCH_KIND(Name)
#ifndef OPENMP_CONTEXT_SELECTOR_SET
#define OPENMP_CONTEXT_SELECTOR_SET(Name)
#endif
#ifndef OPENMP_CONTEXT_SELECTOR
#define OPENMP_CONTEXT_SELECTOR(Name)
#endif
#ifndef OPENMP_LASTPRIVATE_KIND
#define OPENMP_LASTPRIVATE_KIND(Name)
#endif
// OpenMP directives.
OPENMP_DIRECTIVE(threadprivate)
OPENMP_DIRECTIVE(parallel)
OPENMP_DIRECTIVE(task)
OPENMP_DIRECTIVE(simd)
OPENMP_DIRECTIVE(for)
OPENMP_DIRECTIVE(sections)
OPENMP_DIRECTIVE(section)
OPENMP_DIRECTIVE(single)
OPENMP_DIRECTIVE(master)
OPENMP_DIRECTIVE(critical)
OPENMP_DIRECTIVE(taskyield)
OPENMP_DIRECTIVE(barrier)
OPENMP_DIRECTIVE(taskwait)
OPENMP_DIRECTIVE(taskgroup)
OPENMP_DIRECTIVE(flush)
OPENMP_DIRECTIVE(ordered)
OPENMP_DIRECTIVE(atomic)
OPENMP_DIRECTIVE(target)
OPENMP_DIRECTIVE(teams)
OPENMP_DIRECTIVE(cancel)
OPENMP_DIRECTIVE(requires)
OPENMP_DIRECTIVE_EXT(target_data, "target data")
OPENMP_DIRECTIVE_EXT(target_enter_data, "target enter data")
OPENMP_DIRECTIVE_EXT(target_exit_data, "target exit data")
OPENMP_DIRECTIVE_EXT(target_parallel, "target parallel")
OPENMP_DIRECTIVE_EXT(target_parallel_for, "target parallel for")
OPENMP_DIRECTIVE_EXT(target_update, "target update")
OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
OPENMP_DIRECTIVE_EXT(parallel_for_simd, "parallel for simd")
OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
OPENMP_DIRECTIVE_EXT(for_simd, "for simd")
OPENMP_DIRECTIVE_EXT(cancellation_point, "cancellation point")
OPENMP_DIRECTIVE_EXT(declare_reduction, "declare reduction")
OPENMP_DIRECTIVE_EXT(declare_mapper, "declare mapper")
OPENMP_DIRECTIVE_EXT(declare_simd, "declare simd")
OPENMP_DIRECTIVE(taskloop)
OPENMP_DIRECTIVE_EXT(taskloop_simd, "taskloop simd")
OPENMP_DIRECTIVE(distribute)
OPENMP_DIRECTIVE_EXT(declare_target, "declare target")
OPENMP_DIRECTIVE_EXT(end_declare_target, "end declare target")
OPENMP_DIRECTIVE_EXT(distribute_parallel_for, "distribute parallel for")
OPENMP_DIRECTIVE_EXT(distribute_parallel_for_simd, "distribute parallel for simd")
OPENMP_DIRECTIVE_EXT(distribute_simd, "distribute simd")
OPENMP_DIRECTIVE_EXT(target_parallel_for_simd, "target parallel for simd")
OPENMP_DIRECTIVE_EXT(target_simd, "target simd")
OPENMP_DIRECTIVE_EXT(teams_distribute, "teams distribute")
OPENMP_DIRECTIVE_EXT(teams_distribute_simd, "teams distribute simd")
OPENMP_DIRECTIVE_EXT(teams_distribute_parallel_for_simd, "teams distribute parallel for simd")
OPENMP_DIRECTIVE_EXT(teams_distribute_parallel_for, "teams distribute parallel for")
OPENMP_DIRECTIVE_EXT(target_teams, "target teams")
OPENMP_DIRECTIVE_EXT(target_teams_distribute, "target teams distribute")
OPENMP_DIRECTIVE_EXT(target_teams_distribute_parallel_for, "target teams distribute parallel for")
OPENMP_DIRECTIVE_EXT(target_teams_distribute_parallel_for_simd, "target teams distribute parallel for simd")
OPENMP_DIRECTIVE_EXT(target_teams_distribute_simd, "target teams distribute simd")
OPENMP_DIRECTIVE(allocate)
OPENMP_DIRECTIVE_EXT(declare_variant, "declare variant")
OPENMP_DIRECTIVE_EXT(master_taskloop, "master taskloop")
OPENMP_DIRECTIVE_EXT(parallel_master_taskloop, "parallel master taskloop")
OPENMP_DIRECTIVE_EXT(master_taskloop_simd, "master taskloop simd")
// OpenMP context selector sets.
OPENMP_CONTEXT_SELECTOR_SET(implementation)
OPENMP_CONTEXT_SELECTOR_SET(device)
// OpenMP context selectors.
OPENMP_CONTEXT_SELECTOR(vendor)
OPENMP_CONTEXT_SELECTOR(kind)
// OpenMP clauses.
OPENMP_CLAUSE(allocator, OMPAllocatorClause)
@ -327,6 +277,7 @@ OPENMP_CLAUSE(reverse_offload, OMPReverseOffloadClause)
OPENMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause)
OPENMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause)
OPENMP_CLAUSE(allocate, OMPAllocateClause)
OPENMP_CLAUSE(nontemporal, OMPNontemporalClause)
// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
@ -350,6 +301,8 @@ OPENMP_SIMD_CLAUSE(simdlen)
OPENMP_SIMD_CLAUSE(collapse)
OPENMP_SIMD_CLAUSE(reduction)
OPENMP_SIMD_CLAUSE(allocate)
OPENMP_SIMD_CLAUSE(if)
OPENMP_SIMD_CLAUSE(nontemporal)
// Clauses allowed for directive 'omp for'.
OPENMP_FOR_CLAUSE(private)
@ -377,6 +330,8 @@ OPENMP_FOR_SIMD_CLAUSE(linear)
OPENMP_FOR_SIMD_CLAUSE(aligned)
OPENMP_FOR_SIMD_CLAUSE(ordered)
OPENMP_FOR_SIMD_CLAUSE(allocate)
OPENMP_FOR_SIMD_CLAUSE(if)
OPENMP_FOR_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'omp sections'.
OPENMP_SECTIONS_CLAUSE(private)
@ -400,11 +355,6 @@ OPENMP_CANCEL_CLAUSE(if)
OPENMP_DEFAULT_KIND(none)
OPENMP_DEFAULT_KIND(shared)
// Static attributes for 'proc_bind' clause.
OPENMP_PROC_BIND_KIND(master)
OPENMP_PROC_BIND_KIND(close)
OPENMP_PROC_BIND_KIND(spread)
// Static attributes for 'schedule' clause.
OPENMP_SCHEDULE_KIND(static)
OPENMP_SCHEDULE_KIND(dynamic)
@ -419,9 +369,17 @@ OPENMP_SCHEDULE_MODIFIER(simd)
// Static attributes for 'defaultmap' clause.
OPENMP_DEFAULTMAP_KIND(scalar)
OPENMP_DEFAULTMAP_KIND(aggregate)
OPENMP_DEFAULTMAP_KIND(pointer)
// Modifiers for 'defaultmap' clause.
OPENMP_DEFAULTMAP_MODIFIER(alloc)
OPENMP_DEFAULTMAP_MODIFIER(to)
OPENMP_DEFAULTMAP_MODIFIER(from)
OPENMP_DEFAULTMAP_MODIFIER(tofrom)
OPENMP_DEFAULTMAP_MODIFIER(firstprivate)
OPENMP_DEFAULTMAP_MODIFIER(none)
OPENMP_DEFAULTMAP_MODIFIER(default)
// Static attributes for 'depend' clause.
OPENMP_DEPEND_KIND(in)
@ -472,6 +430,19 @@ OPENMP_PARALLEL_FOR_SIMD_CLAUSE(linear)
OPENMP_PARALLEL_FOR_SIMD_CLAUSE(aligned)
OPENMP_PARALLEL_FOR_SIMD_CLAUSE(ordered)
OPENMP_PARALLEL_FOR_SIMD_CLAUSE(allocate)
OPENMP_PARALLEL_FOR_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'parallel master'.
OPENMP_PARALLEL_MASTER_CLAUSE(if)
OPENMP_PARALLEL_MASTER_CLAUSE(num_threads)
OPENMP_PARALLEL_MASTER_CLAUSE(default)
OPENMP_PARALLEL_MASTER_CLAUSE(private)
OPENMP_PARALLEL_MASTER_CLAUSE(firstprivate)
OPENMP_PARALLEL_MASTER_CLAUSE(shared)
OPENMP_PARALLEL_MASTER_CLAUSE(copyin)
OPENMP_PARALLEL_MASTER_CLAUSE(reduction)
OPENMP_PARALLEL_MASTER_CLAUSE(proc_bind)
OPENMP_PARALLEL_MASTER_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'parallel sections'.
OPENMP_PARALLEL_SECTIONS_CLAUSE(if)
@ -677,6 +648,7 @@ OPENMP_TASKLOOP_SIMD_CLAUSE(num_tasks)
OPENMP_TASKLOOP_SIMD_CLAUSE(reduction)
OPENMP_TASKLOOP_SIMD_CLAUSE(in_reduction)
OPENMP_TASKLOOP_SIMD_CLAUSE(allocate)
OPENMP_TASKLOOP_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'master taskloop'.
OPENMP_MASTER_TASKLOOP_CLAUSE(if)
@ -719,6 +691,7 @@ OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(num_tasks)
OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(reduction)
OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(in_reduction)
OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(allocate)
OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'parallel master taskloop'.
OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(if)
@ -741,6 +714,32 @@ OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(num_threads)
OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(proc_bind)
OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(copyin)
// Clauses allowed for OpenMP directive 'parallel master taskloop simd'.
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(if)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(shared)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(private)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(firstprivate)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(lastprivate)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(default)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(collapse)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(final)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(untied)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(mergeable)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(priority)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(grainsize)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(nogroup)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(num_tasks)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(reduction)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(allocate)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(num_threads)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(proc_bind)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(copyin)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(linear)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(aligned)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(safelen)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(simdlen)
OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'critical'.
OPENMP_CRITICAL_CLAUSE(hint)
@ -790,6 +789,7 @@ OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned)
OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen)
OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate)
OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'distribute simd'
OPENMP_DISTRIBUTE_SIMD_CLAUSE(private)
@ -803,6 +803,8 @@ OPENMP_DISTRIBUTE_SIMD_CLAUSE(safelen)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(simdlen)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(reduction)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(allocate)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(if)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'target parallel for simd'.
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(if)
@ -828,6 +830,7 @@ OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(is_device_ptr)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(allocate)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'target simd'.
OPENMP_TARGET_SIMD_CLAUSE(if)
@ -847,6 +850,7 @@ OPENMP_TARGET_SIMD_CLAUSE(simdlen)
OPENMP_TARGET_SIMD_CLAUSE(collapse)
OPENMP_TARGET_SIMD_CLAUSE(reduction)
OPENMP_TARGET_SIMD_CLAUSE(allocate)
OPENMP_TARGET_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'teams distribute'.
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(default)
@ -877,6 +881,8 @@ OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(allocate)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(if)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'teams distribute parallel for simd'
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate)
@ -898,6 +904,7 @@ OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_teams)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(thread_limit)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'teams distribute parallel for'
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate)
@ -1004,6 +1011,7 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'target teams distribute simd'.
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(if)
@ -1027,6 +1035,7 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(allocate)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nontemporal)
// Clauses allowed for OpenMP directive 'taskgroup'.
OPENMP_TASKGROUP_CLAUSE(task_reduction)
@ -1043,16 +1052,18 @@ OPENMP_DEVICE_TYPE_KIND(any)
// Clauses allowed for OpenMP directive 'declare variant'.
OPENMP_DECLARE_VARIANT_CLAUSE(match)
// Context selectors for 'match' clause.
// TODO: add other context selectors.
OPENMP_MATCH_KIND(implementation)
// Type of the 'lastprivate' clause.
OPENMP_LASTPRIVATE_KIND(conditional)
#undef OPENMP_MATCH_KIND
#undef OPENMP_LASTPRIVATE_KIND
#undef OPENMP_CONTEXT_SELECTOR
#undef OPENMP_CONTEXT_SELECTOR_SET
#undef OPENMP_DECLARE_VARIANT_CLAUSE
#undef OPENMP_DEVICE_TYPE_KIND
#undef OPENMP_ALLOCATE_CLAUSE
#undef OPENMP_DECLARE_MAPPER_CLAUSE
#undef OPENMP_TASKGROUP_CLAUSE
#undef OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE
#undef OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE
#undef OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE
#undef OPENMP_MASTER_TASKLOOP_CLAUSE
@ -1062,10 +1073,7 @@ OPENMP_MATCH_KIND(implementation)
#undef OPENMP_DEPEND_KIND
#undef OPENMP_SCHEDULE_MODIFIER
#undef OPENMP_SCHEDULE_KIND
#undef OPENMP_PROC_BIND_KIND
#undef OPENMP_DEFAULT_KIND
#undef OPENMP_DIRECTIVE
#undef OPENMP_DIRECTIVE_EXT
#undef OPENMP_CLAUSE
#undef OPENMP_CRITICAL_CLAUSE
#undef OPENMP_ORDERED_CLAUSE
@ -1075,6 +1083,7 @@ OPENMP_MATCH_KIND(implementation)
#undef OPENMP_PARALLEL_CLAUSE
#undef OPENMP_PARALLEL_FOR_CLAUSE
#undef OPENMP_PARALLEL_FOR_SIMD_CLAUSE
#undef OPENMP_PARALLEL_MASTER_CLAUSE
#undef OPENMP_PARALLEL_SECTIONS_CLAUSE
#undef OPENMP_TASK_CLAUSE
#undef OPENMP_ATOMIC_CLAUSE

View File

@ -15,19 +15,52 @@
#define LLVM_CLANG_BASIC_OPENMPKINDS_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
namespace clang {
/// OpenMP directives.
enum OpenMPDirectiveKind {
#define OPENMP_DIRECTIVE(Name) \
OMPD_##Name,
#define OPENMP_DIRECTIVE_EXT(Name, Str) \
OMPD_##Name,
/// OpenMP context selector sets.
enum OpenMPContextSelectorSetKind {
#define OPENMP_CONTEXT_SELECTOR_SET(Name) OMP_CTX_SET_##Name,
#include "clang/Basic/OpenMPKinds.def"
OMPD_unknown
OMP_CTX_SET_unknown,
};
/// OpenMP context selectors.
enum OpenMPContextSelectorKind {
#define OPENMP_CONTEXT_SELECTOR(Name) OMP_CTX_##Name,
#include "clang/Basic/OpenMPKinds.def"
OMP_CTX_unknown,
};
OpenMPContextSelectorSetKind getOpenMPContextSelectorSet(llvm::StringRef Str);
llvm::StringRef
getOpenMPContextSelectorSetName(OpenMPContextSelectorSetKind Kind);
OpenMPContextSelectorKind getOpenMPContextSelector(llvm::StringRef Str);
llvm::StringRef getOpenMPContextSelectorName(OpenMPContextSelectorKind Kind);
/// Struct to store the context selectors info.
template <typename VectorType, typename ScoreT> struct OpenMPCtxSelectorData {
OpenMPContextSelectorSetKind CtxSet = OMP_CTX_SET_unknown;
OpenMPContextSelectorKind Ctx = OMP_CTX_unknown;
ScoreT Score;
VectorType Names;
explicit OpenMPCtxSelectorData() = default;
explicit OpenMPCtxSelectorData(OpenMPContextSelectorSetKind CtxSet,
OpenMPContextSelectorKind Ctx,
const ScoreT &Score, VectorType &&Names)
: CtxSet(CtxSet), Ctx(Ctx), Score(Score), Names(Names) {}
template <typename U>
explicit OpenMPCtxSelectorData(OpenMPContextSelectorSetKind CtxSet,
OpenMPContextSelectorKind Ctx,
const ScoreT &Score, const U &Names)
: CtxSet(CtxSet), Ctx(Ctx), Score(Score),
Names(Names.begin(), Names.end()) {}
};
/// OpenMP directives.
using OpenMPDirectiveKind = llvm::omp::Directive;
/// OpenMP clauses.
enum OpenMPClauseKind {
#define OPENMP_CLAUSE(Name, Class) \
@ -48,14 +81,6 @@ enum OpenMPDefaultClauseKind {
OMPC_DEFAULT_unknown
};
/// OpenMP attributes for 'proc_bind' clause.
enum OpenMPProcBindClauseKind {
#define OPENMP_PROC_BIND_KIND(Name) \
OMPC_PROC_BIND_##Name,
#include "clang/Basic/OpenMPKinds.def"
OMPC_PROC_BIND_unknown
};
/// OpenMP attributes for 'schedule' clause.
enum OpenMPScheduleClauseKind {
#define OPENMP_SCHEDULE_KIND(Name) \
@ -162,6 +187,13 @@ enum OpenMPDeviceType {
OMPC_DEVICE_TYPE_unknown
};
/// OpenMP 'lastprivate' clause modifier.
enum OpenMPLastprivateModifier {
#define OPENMP_LASTPRIVATE_KIND(Name) OMPC_LASTPRIVATE_##Name,
#include "clang/Basic/OpenMPKinds.def"
OMPC_LASTPRIVATE_unknown,
};
/// Scheduling data for loop-based OpenMP directives.
struct OpenMPScheduleTy final {
OpenMPScheduleClauseKind Schedule = OMPC_SCHEDULE_unknown;
@ -169,9 +201,6 @@ struct OpenMPScheduleTy final {
OpenMPScheduleClauseModifier M2 = OMPC_SCHEDULE_MODIFIER_unknown;
};
OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str);
const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind);
OpenMPClauseKind getOpenMPClauseKind(llvm::StringRef Str);
const char *getOpenMPClauseName(OpenMPClauseKind Kind);
@ -179,7 +208,8 @@ unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str);
const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type);
bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
OpenMPClauseKind CKind);
OpenMPClauseKind CKind,
unsigned OpenMPVersion);
/// Checks if the specified directive is a directive with an associated
/// loop construct.
@ -269,8 +299,8 @@ bool isOpenMPPrivate(OpenMPClauseKind Kind);
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind);
/// Checks if the specified directive kind is one of tasking directives - task,
/// taskloop, taksloop simd, master taskloop, parallel master taskloop or master
/// taskloop simd.
/// taskloop, taksloop simd, master taskloop, parallel master taskloop, master
/// taskloop simd, or parallel master taskloop simd.
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind);
/// Checks if the specified directive kind is one of the composite or combined

View File

@ -16,7 +16,6 @@
#define LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/SmallVector.h"

View File

@ -17,6 +17,7 @@
#include "clang/Basic/Sanitizers.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/SpecialCaseList.h"
#include "llvm/Support/VirtualFileSystem.h"
#include <memory>
namespace clang {
@ -24,10 +25,12 @@ namespace clang {
class SanitizerSpecialCaseList : public llvm::SpecialCaseList {
public:
static std::unique_ptr<SanitizerSpecialCaseList>
create(const std::vector<std::string> &Paths, std::string &Error);
create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &VFS,
std::string &Error);
static std::unique_ptr<SanitizerSpecialCaseList>
createOrDie(const std::vector<std::string> &Paths);
createOrDie(const std::vector<std::string> &Paths,
llvm::vfs::FileSystem &VFS);
// Query blacklisted entries if any bit in Mask matches the entry's section.
bool inSection(SanitizerMask Mask, StringRef Prefix, StringRef Query,

View File

@ -52,10 +52,11 @@ class SanitizerMask {
/// Create a mask with a bit enabled at position Pos.
static constexpr SanitizerMask bitPosToMask(const unsigned Pos) {
return SanitizerMask((Pos < kNumBitElem) ? 1ULL << Pos % kNumBitElem : 0,
(Pos >= kNumBitElem && Pos < kNumBitElem * 2)
? 1ULL << Pos % kNumBitElem
: 0);
uint64_t mask1 = (Pos < kNumBitElem) ? 1ULL << (Pos % kNumBitElem) : 0;
uint64_t mask2 = (Pos >= kNumBitElem && Pos < (kNumBitElem * 2))
? 1ULL << (Pos % kNumBitElem)
: 0;
return SanitizerMask(mask1, mask2);
}
unsigned countPopulation() const {

View File

@ -188,9 +188,20 @@ inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
return !(LHS == RHS);
}
// Ordering is meaningful only if LHS and RHS have the same FileID!
// Otherwise use SourceManager::isBeforeInTranslationUnit().
inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
return LHS.getRawEncoding() < RHS.getRawEncoding();
}
inline bool operator>(const SourceLocation &LHS, const SourceLocation &RHS) {
return LHS.getRawEncoding() > RHS.getRawEncoding();
}
inline bool operator<=(const SourceLocation &LHS, const SourceLocation &RHS) {
return LHS.getRawEncoding() <= RHS.getRawEncoding();
}
inline bool operator>=(const SourceLocation &LHS, const SourceLocation &RHS) {
return LHS.getRawEncoding() >= RHS.getRawEncoding();
}
/// A trivial tuple used to represent a source range.
class SourceRange {
@ -219,6 +230,11 @@ class SourceRange {
return B != X.B || E != X.E;
}
// Returns true iff other is wholly contained within this range.
bool fullyContains(const SourceRange &other) const {
return B <= other.B && E >= other.E;
}
void print(raw_ostream &OS, const SourceManager &SM) const;
std::string printToString(const SourceManager &SM) const;
void dump(const SourceManager &SM) const;

View File

@ -226,6 +226,10 @@ namespace SrcMgr {
bool shouldFreeBuffer() const {
return (Buffer.getInt() & DoNotFreeFlag) == 0;
}
// If BufStr has an invalid BOM, returns the BOM name; otherwise, returns
// nullptr
static const char *getInvalidBOM(StringRef BufStr);
};
// Assert that the \c ContentCache objects will always be 8-byte aligned so
@ -827,6 +831,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
SrcMgr::CharacteristicKind FileCharacter,
int LoadedID = 0, unsigned LoadedOffset = 0) {
assert(SourceFile && "Null source file!");
const SrcMgr::ContentCache *IR =
getOrCreateContentCache(SourceFile, isSystem(FileCharacter));
assert(IR && "getOrCreateContentCache() cannot return NULL");

View File

@ -354,6 +354,15 @@ namespace clang {
SwiftContext
};
/// Assigned inheritance model for a class in the MS C++ ABI. Must match order
/// of spellings in MSInheritanceAttr.
enum class MSInheritanceModel {
Single = 0,
Multiple = 1,
Virtual = 2,
Unspecified = 3,
};
llvm::StringRef getParameterABISpelling(ParameterABI kind);
} // end namespace clang

View File

@ -1,266 +1,266 @@
class AttrSubject;
include "clang/Basic/ASTNode.td"
class Stmt<bit abstract = 0> : AttrSubject {
class StmtNode<StmtNode base, bit abstract = 0> : ASTNode, AttrSubject {
StmtNode Base = base;
bit Abstract = abstract;
}
class DStmt<Stmt base, bit abstract = 0> : Stmt<abstract> {
Stmt Base = base;
}
// Statements
def NullStmt : Stmt;
def CompoundStmt : Stmt;
def IfStmt : Stmt;
def SwitchStmt : Stmt;
def WhileStmt : Stmt;
def DoStmt : Stmt;
def ForStmt : Stmt;
def GotoStmt : Stmt;
def IndirectGotoStmt : Stmt;
def ContinueStmt : Stmt;
def BreakStmt : Stmt;
def ReturnStmt : Stmt;
def DeclStmt : Stmt;
def SwitchCase : Stmt<1>;
def CaseStmt : DStmt<SwitchCase>;
def DefaultStmt : DStmt<SwitchCase>;
def CapturedStmt : Stmt;
def Stmt : StmtNode<?, 1>;
def NullStmt : StmtNode<Stmt>;
def CompoundStmt : StmtNode<Stmt>;
def IfStmt : StmtNode<Stmt>;
def SwitchStmt : StmtNode<Stmt>;
def WhileStmt : StmtNode<Stmt>;
def DoStmt : StmtNode<Stmt>;
def ForStmt : StmtNode<Stmt>;
def GotoStmt : StmtNode<Stmt>;
def IndirectGotoStmt : StmtNode<Stmt>;
def ContinueStmt : StmtNode<Stmt>;
def BreakStmt : StmtNode<Stmt>;
def ReturnStmt : StmtNode<Stmt>;
def DeclStmt : StmtNode<Stmt>;
def SwitchCase : StmtNode<Stmt, 1>;
def CaseStmt : StmtNode<SwitchCase>;
def DefaultStmt : StmtNode<SwitchCase>;
def CapturedStmt : StmtNode<Stmt>;
// Statements that might produce a value (for example, as the last non-null
// statement in a GNU statement-expression).
def ValueStmt : Stmt<1>;
def LabelStmt : DStmt<ValueStmt>;
def AttributedStmt : DStmt<ValueStmt>;
def ValueStmt : StmtNode<Stmt, 1>;
def LabelStmt : StmtNode<ValueStmt>;
def AttributedStmt : StmtNode<ValueStmt>;
// Asm statements
def AsmStmt : Stmt<1>;
def GCCAsmStmt : DStmt<AsmStmt>;
def MSAsmStmt : DStmt<AsmStmt>;
def AsmStmt : StmtNode<Stmt, 1>;
def GCCAsmStmt : StmtNode<AsmStmt>;
def MSAsmStmt : StmtNode<AsmStmt>;
// Obj-C statements
def ObjCAtTryStmt : Stmt;
def ObjCAtCatchStmt : Stmt;
def ObjCAtFinallyStmt : Stmt;
def ObjCAtThrowStmt : Stmt;
def ObjCAtSynchronizedStmt : Stmt;
def ObjCForCollectionStmt : Stmt;
def ObjCAutoreleasePoolStmt : Stmt;
def ObjCAtTryStmt : StmtNode<Stmt>;
def ObjCAtCatchStmt : StmtNode<Stmt>;
def ObjCAtFinallyStmt : StmtNode<Stmt>;
def ObjCAtThrowStmt : StmtNode<Stmt>;
def ObjCAtSynchronizedStmt : StmtNode<Stmt>;
def ObjCForCollectionStmt : StmtNode<Stmt>;
def ObjCAutoreleasePoolStmt : StmtNode<Stmt>;
// C++ statements
def CXXCatchStmt : Stmt;
def CXXTryStmt : Stmt;
def CXXForRangeStmt : Stmt;
def CXXCatchStmt : StmtNode<Stmt>;
def CXXTryStmt : StmtNode<Stmt>;
def CXXForRangeStmt : StmtNode<Stmt>;
// C++ Coroutines TS statements
def CoroutineBodyStmt : Stmt;
def CoreturnStmt : Stmt;
def CoroutineBodyStmt : StmtNode<Stmt>;
def CoreturnStmt : StmtNode<Stmt>;
// Expressions
def Expr : DStmt<ValueStmt, 1>;
def PredefinedExpr : DStmt<Expr>;
def DeclRefExpr : DStmt<Expr>;
def IntegerLiteral : DStmt<Expr>;
def FixedPointLiteral : DStmt<Expr>;
def FloatingLiteral : DStmt<Expr>;
def ImaginaryLiteral : DStmt<Expr>;
def StringLiteral : DStmt<Expr>;
def CharacterLiteral : DStmt<Expr>;
def ParenExpr : DStmt<Expr>;
def UnaryOperator : DStmt<Expr>;
def OffsetOfExpr : DStmt<Expr>;
def UnaryExprOrTypeTraitExpr : DStmt<Expr>;
def ArraySubscriptExpr : DStmt<Expr>;
def OMPArraySectionExpr : DStmt<Expr>;
def CallExpr : DStmt<Expr>;
def MemberExpr : DStmt<Expr>;
def CastExpr : DStmt<Expr, 1>;
def BinaryOperator : DStmt<Expr>;
def CompoundAssignOperator : DStmt<BinaryOperator>;
def AbstractConditionalOperator : DStmt<Expr, 1>;
def ConditionalOperator : DStmt<AbstractConditionalOperator>;
def BinaryConditionalOperator : DStmt<AbstractConditionalOperator>;
def ImplicitCastExpr : DStmt<CastExpr>;
def ExplicitCastExpr : DStmt<CastExpr, 1>;
def CStyleCastExpr : DStmt<ExplicitCastExpr>;
def CompoundLiteralExpr : DStmt<Expr>;
def ExtVectorElementExpr : DStmt<Expr>;
def InitListExpr : DStmt<Expr>;
def DesignatedInitExpr : DStmt<Expr>;
def DesignatedInitUpdateExpr : DStmt<Expr>;
def ImplicitValueInitExpr : DStmt<Expr>;
def NoInitExpr : DStmt<Expr>;
def ArrayInitLoopExpr : DStmt<Expr>;
def ArrayInitIndexExpr : DStmt<Expr>;
def ParenListExpr : DStmt<Expr>;
def VAArgExpr : DStmt<Expr>;
def GenericSelectionExpr : DStmt<Expr>;
def PseudoObjectExpr : DStmt<Expr>;
def SourceLocExpr : DStmt<Expr>;
def Expr : StmtNode<ValueStmt, 1>;
def PredefinedExpr : StmtNode<Expr>;
def DeclRefExpr : StmtNode<Expr>;
def IntegerLiteral : StmtNode<Expr>;
def FixedPointLiteral : StmtNode<Expr>;
def FloatingLiteral : StmtNode<Expr>;
def ImaginaryLiteral : StmtNode<Expr>;
def StringLiteral : StmtNode<Expr>;
def CharacterLiteral : StmtNode<Expr>;
def ParenExpr : StmtNode<Expr>;
def UnaryOperator : StmtNode<Expr>;
def OffsetOfExpr : StmtNode<Expr>;
def UnaryExprOrTypeTraitExpr : StmtNode<Expr>;
def ArraySubscriptExpr : StmtNode<Expr>;
def OMPArraySectionExpr : StmtNode<Expr>;
def CallExpr : StmtNode<Expr>;
def MemberExpr : StmtNode<Expr>;
def CastExpr : StmtNode<Expr, 1>;
def BinaryOperator : StmtNode<Expr>;
def CompoundAssignOperator : StmtNode<BinaryOperator>;
def AbstractConditionalOperator : StmtNode<Expr, 1>;
def ConditionalOperator : StmtNode<AbstractConditionalOperator>;
def BinaryConditionalOperator : StmtNode<AbstractConditionalOperator>;
def ImplicitCastExpr : StmtNode<CastExpr>;
def ExplicitCastExpr : StmtNode<CastExpr, 1>;
def CStyleCastExpr : StmtNode<ExplicitCastExpr>;
def CompoundLiteralExpr : StmtNode<Expr>;
def ExtVectorElementExpr : StmtNode<Expr>;
def InitListExpr : StmtNode<Expr>;
def DesignatedInitExpr : StmtNode<Expr>;
def DesignatedInitUpdateExpr : StmtNode<Expr>;
def ImplicitValueInitExpr : StmtNode<Expr>;
def NoInitExpr : StmtNode<Expr>;
def ArrayInitLoopExpr : StmtNode<Expr>;
def ArrayInitIndexExpr : StmtNode<Expr>;
def ParenListExpr : StmtNode<Expr>;
def VAArgExpr : StmtNode<Expr>;
def GenericSelectionExpr : StmtNode<Expr>;
def PseudoObjectExpr : StmtNode<Expr>;
def SourceLocExpr : StmtNode<Expr>;
// Wrapper expressions
def FullExpr : DStmt<Expr, 1>;
def ConstantExpr : DStmt<FullExpr>;
def FullExpr : StmtNode<Expr, 1>;
def ConstantExpr : StmtNode<FullExpr>;
// Atomic expressions
def AtomicExpr : DStmt<Expr>;
def AtomicExpr : StmtNode<Expr>;
// GNU Extensions.
def AddrLabelExpr : DStmt<Expr>;
def StmtExpr : DStmt<Expr>;
def ChooseExpr : DStmt<Expr>;
def GNUNullExpr : DStmt<Expr>;
def AddrLabelExpr : StmtNode<Expr>;
def StmtExpr : StmtNode<Expr>;
def ChooseExpr : StmtNode<Expr>;
def GNUNullExpr : StmtNode<Expr>;
// C++ Expressions.
def CXXOperatorCallExpr : DStmt<CallExpr>;
def CXXMemberCallExpr : DStmt<CallExpr>;
def CXXRewrittenBinaryOperator : DStmt<Expr>;
def CXXNamedCastExpr : DStmt<ExplicitCastExpr, 1>;
def CXXStaticCastExpr : DStmt<CXXNamedCastExpr>;
def CXXDynamicCastExpr : DStmt<CXXNamedCastExpr>;
def CXXReinterpretCastExpr : DStmt<CXXNamedCastExpr>;
def CXXConstCastExpr : DStmt<CXXNamedCastExpr>;
def CXXFunctionalCastExpr : DStmt<ExplicitCastExpr>;
def CXXTypeidExpr : DStmt<Expr>;
def UserDefinedLiteral : DStmt<CallExpr>;
def CXXBoolLiteralExpr : DStmt<Expr>;
def CXXNullPtrLiteralExpr : DStmt<Expr>;
def CXXThisExpr : DStmt<Expr>;
def CXXThrowExpr : DStmt<Expr>;
def CXXDefaultArgExpr : DStmt<Expr>;
def CXXDefaultInitExpr : DStmt<Expr>;
def CXXScalarValueInitExpr : DStmt<Expr>;
def CXXStdInitializerListExpr : DStmt<Expr>;
def CXXNewExpr : DStmt<Expr>;
def CXXDeleteExpr : DStmt<Expr>;
def CXXPseudoDestructorExpr : DStmt<Expr>;
def TypeTraitExpr : DStmt<Expr>;
def ArrayTypeTraitExpr : DStmt<Expr>;
def ExpressionTraitExpr : DStmt<Expr>;
def DependentScopeDeclRefExpr : DStmt<Expr>;
def CXXConstructExpr : DStmt<Expr>;
def CXXInheritedCtorInitExpr : DStmt<Expr>;
def CXXBindTemporaryExpr : DStmt<Expr>;
def ExprWithCleanups : DStmt<FullExpr>;
def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>;
def CXXUnresolvedConstructExpr : DStmt<Expr>;
def CXXDependentScopeMemberExpr : DStmt<Expr>;
def OverloadExpr : DStmt<Expr, 1>;
def UnresolvedLookupExpr : DStmt<OverloadExpr>;
def UnresolvedMemberExpr : DStmt<OverloadExpr>;
def CXXNoexceptExpr : DStmt<Expr>;
def PackExpansionExpr : DStmt<Expr>;
def SizeOfPackExpr : DStmt<Expr>;
def SubstNonTypeTemplateParmExpr : DStmt<Expr>;
def SubstNonTypeTemplateParmPackExpr : DStmt<Expr>;
def FunctionParmPackExpr : DStmt<Expr>;
def MaterializeTemporaryExpr : DStmt<Expr>;
def LambdaExpr : DStmt<Expr>;
def CXXFoldExpr : DStmt<Expr>;
def CXXOperatorCallExpr : StmtNode<CallExpr>;
def CXXMemberCallExpr : StmtNode<CallExpr>;
def CXXRewrittenBinaryOperator : StmtNode<Expr>;
def CXXNamedCastExpr : StmtNode<ExplicitCastExpr, 1>;
def CXXStaticCastExpr : StmtNode<CXXNamedCastExpr>;
def CXXDynamicCastExpr : StmtNode<CXXNamedCastExpr>;
def CXXReinterpretCastExpr : StmtNode<CXXNamedCastExpr>;
def CXXConstCastExpr : StmtNode<CXXNamedCastExpr>;
def CXXFunctionalCastExpr : StmtNode<ExplicitCastExpr>;
def CXXTypeidExpr : StmtNode<Expr>;
def UserDefinedLiteral : StmtNode<CallExpr>;
def CXXBoolLiteralExpr : StmtNode<Expr>;
def CXXNullPtrLiteralExpr : StmtNode<Expr>;
def CXXThisExpr : StmtNode<Expr>;
def CXXThrowExpr : StmtNode<Expr>;
def CXXDefaultArgExpr : StmtNode<Expr>;
def CXXDefaultInitExpr : StmtNode<Expr>;
def CXXScalarValueInitExpr : StmtNode<Expr>;
def CXXStdInitializerListExpr : StmtNode<Expr>;
def CXXNewExpr : StmtNode<Expr>;
def CXXDeleteExpr : StmtNode<Expr>;
def CXXPseudoDestructorExpr : StmtNode<Expr>;
def TypeTraitExpr : StmtNode<Expr>;
def ArrayTypeTraitExpr : StmtNode<Expr>;
def ExpressionTraitExpr : StmtNode<Expr>;
def DependentScopeDeclRefExpr : StmtNode<Expr>;
def CXXConstructExpr : StmtNode<Expr>;
def CXXInheritedCtorInitExpr : StmtNode<Expr>;
def CXXBindTemporaryExpr : StmtNode<Expr>;
def ExprWithCleanups : StmtNode<FullExpr>;
def CXXTemporaryObjectExpr : StmtNode<CXXConstructExpr>;
def CXXUnresolvedConstructExpr : StmtNode<Expr>;
def CXXDependentScopeMemberExpr : StmtNode<Expr>;
def OverloadExpr : StmtNode<Expr, 1>;
def UnresolvedLookupExpr : StmtNode<OverloadExpr>;
def UnresolvedMemberExpr : StmtNode<OverloadExpr>;
def CXXNoexceptExpr : StmtNode<Expr>;
def PackExpansionExpr : StmtNode<Expr>;
def SizeOfPackExpr : StmtNode<Expr>;
def SubstNonTypeTemplateParmExpr : StmtNode<Expr>;
def SubstNonTypeTemplateParmPackExpr : StmtNode<Expr>;
def FunctionParmPackExpr : StmtNode<Expr>;
def MaterializeTemporaryExpr : StmtNode<Expr>;
def LambdaExpr : StmtNode<Expr>;
def CXXFoldExpr : StmtNode<Expr>;
// C++ Coroutines TS expressions
def CoroutineSuspendExpr : DStmt<Expr, 1>;
def CoawaitExpr : DStmt<CoroutineSuspendExpr>;
def DependentCoawaitExpr : DStmt<Expr>;
def CoyieldExpr : DStmt<CoroutineSuspendExpr>;
def CoroutineSuspendExpr : StmtNode<Expr, 1>;
def CoawaitExpr : StmtNode<CoroutineSuspendExpr>;
def DependentCoawaitExpr : StmtNode<Expr>;
def CoyieldExpr : StmtNode<CoroutineSuspendExpr>;
// C++2a Concepts expressions
def ConceptSpecializationExpr : DStmt<Expr>;
def ConceptSpecializationExpr : StmtNode<Expr>;
// Obj-C Expressions.
def ObjCStringLiteral : DStmt<Expr>;
def ObjCBoxedExpr : DStmt<Expr>;
def ObjCArrayLiteral : DStmt<Expr>;
def ObjCDictionaryLiteral : DStmt<Expr>;
def ObjCEncodeExpr : DStmt<Expr>;
def ObjCMessageExpr : DStmt<Expr>;
def ObjCSelectorExpr : DStmt<Expr>;
def ObjCProtocolExpr : DStmt<Expr>;
def ObjCIvarRefExpr : DStmt<Expr>;
def ObjCPropertyRefExpr : DStmt<Expr>;
def ObjCIsaExpr : DStmt<Expr>;
def ObjCIndirectCopyRestoreExpr : DStmt<Expr>;
def ObjCBoolLiteralExpr : DStmt<Expr>;
def ObjCSubscriptRefExpr : DStmt<Expr>;
def ObjCAvailabilityCheckExpr : DStmt<Expr>;
def ObjCStringLiteral : StmtNode<Expr>;
def ObjCBoxedExpr : StmtNode<Expr>;
def ObjCArrayLiteral : StmtNode<Expr>;
def ObjCDictionaryLiteral : StmtNode<Expr>;
def ObjCEncodeExpr : StmtNode<Expr>;
def ObjCMessageExpr : StmtNode<Expr>;
def ObjCSelectorExpr : StmtNode<Expr>;
def ObjCProtocolExpr : StmtNode<Expr>;
def ObjCIvarRefExpr : StmtNode<Expr>;
def ObjCPropertyRefExpr : StmtNode<Expr>;
def ObjCIsaExpr : StmtNode<Expr>;
def ObjCIndirectCopyRestoreExpr : StmtNode<Expr>;
def ObjCBoolLiteralExpr : StmtNode<Expr>;
def ObjCSubscriptRefExpr : StmtNode<Expr>;
def ObjCAvailabilityCheckExpr : StmtNode<Expr>;
// Obj-C ARC Expressions.
def ObjCBridgedCastExpr : DStmt<ExplicitCastExpr>;
def ObjCBridgedCastExpr : StmtNode<ExplicitCastExpr>;
// CUDA Expressions.
def CUDAKernelCallExpr : DStmt<CallExpr>;
def CUDAKernelCallExpr : StmtNode<CallExpr>;
// Clang Extensions.
def ShuffleVectorExpr : DStmt<Expr>;
def ConvertVectorExpr : DStmt<Expr>;
def BlockExpr : DStmt<Expr>;
def OpaqueValueExpr : DStmt<Expr>;
def TypoExpr : DStmt<Expr>;
def BuiltinBitCastExpr : DStmt<ExplicitCastExpr>;
def ShuffleVectorExpr : StmtNode<Expr>;
def ConvertVectorExpr : StmtNode<Expr>;
def BlockExpr : StmtNode<Expr>;
def OpaqueValueExpr : StmtNode<Expr>;
def TypoExpr : StmtNode<Expr>;
def BuiltinBitCastExpr : StmtNode<ExplicitCastExpr>;
// Microsoft Extensions.
def MSPropertyRefExpr : DStmt<Expr>;
def MSPropertySubscriptExpr : DStmt<Expr>;
def CXXUuidofExpr : DStmt<Expr>;
def SEHTryStmt : Stmt;
def SEHExceptStmt : Stmt;
def SEHFinallyStmt : Stmt;
def SEHLeaveStmt : Stmt;
def MSDependentExistsStmt : Stmt;
def MSPropertyRefExpr : StmtNode<Expr>;
def MSPropertySubscriptExpr : StmtNode<Expr>;
def CXXUuidofExpr : StmtNode<Expr>;
def SEHTryStmt : StmtNode<Stmt>;
def SEHExceptStmt : StmtNode<Stmt>;
def SEHFinallyStmt : StmtNode<Stmt>;
def SEHLeaveStmt : StmtNode<Stmt>;
def MSDependentExistsStmt : StmtNode<Stmt>;
// OpenCL Extensions.
def AsTypeExpr : DStmt<Expr>;
def AsTypeExpr : StmtNode<Expr>;
// OpenMP Directives.
def OMPExecutableDirective : Stmt<1>;
def OMPLoopDirective : DStmt<OMPExecutableDirective, 1>;
def OMPParallelDirective : DStmt<OMPExecutableDirective>;
def OMPSimdDirective : DStmt<OMPLoopDirective>;
def OMPForDirective : DStmt<OMPLoopDirective>;
def OMPForSimdDirective : DStmt<OMPLoopDirective>;
def OMPSectionsDirective : DStmt<OMPExecutableDirective>;
def OMPSectionDirective : DStmt<OMPExecutableDirective>;
def OMPSingleDirective : DStmt<OMPExecutableDirective>;
def OMPMasterDirective : DStmt<OMPExecutableDirective>;
def OMPCriticalDirective : DStmt<OMPExecutableDirective>;
def OMPParallelForDirective : DStmt<OMPLoopDirective>;
def OMPParallelForSimdDirective : DStmt<OMPLoopDirective>;
def OMPParallelSectionsDirective : DStmt<OMPExecutableDirective>;
def OMPTaskDirective : DStmt<OMPExecutableDirective>;
def OMPTaskyieldDirective : DStmt<OMPExecutableDirective>;
def OMPBarrierDirective : DStmt<OMPExecutableDirective>;
def OMPTaskwaitDirective : DStmt<OMPExecutableDirective>;
def OMPTaskgroupDirective : DStmt<OMPExecutableDirective>;
def OMPFlushDirective : DStmt<OMPExecutableDirective>;
def OMPOrderedDirective : DStmt<OMPExecutableDirective>;
def OMPAtomicDirective : DStmt<OMPExecutableDirective>;
def OMPTargetDirective : DStmt<OMPExecutableDirective>;
def OMPTargetDataDirective : DStmt<OMPExecutableDirective>;
def OMPTargetEnterDataDirective : DStmt<OMPExecutableDirective>;
def OMPTargetExitDataDirective : DStmt<OMPExecutableDirective>;
def OMPTargetParallelDirective : DStmt<OMPExecutableDirective>;
def OMPTargetParallelForDirective : DStmt<OMPExecutableDirective>;
def OMPTargetUpdateDirective : DStmt<OMPExecutableDirective>;
def OMPTeamsDirective : DStmt<OMPExecutableDirective>;
def OMPCancellationPointDirective : DStmt<OMPExecutableDirective>;
def OMPCancelDirective : DStmt<OMPExecutableDirective>;
def OMPTaskLoopDirective : DStmt<OMPLoopDirective>;
def OMPTaskLoopSimdDirective : DStmt<OMPLoopDirective>;
def OMPMasterTaskLoopDirective : DStmt<OMPLoopDirective>;
def OMPMasterTaskLoopSimdDirective : DStmt<OMPLoopDirective>;
def OMPParallelMasterTaskLoopDirective : DStmt<OMPLoopDirective>;
def OMPDistributeDirective : DStmt<OMPLoopDirective>;
def OMPDistributeParallelForDirective : DStmt<OMPLoopDirective>;
def OMPDistributeParallelForSimdDirective : DStmt<OMPLoopDirective>;
def OMPDistributeSimdDirective : DStmt<OMPLoopDirective>;
def OMPTargetParallelForSimdDirective : DStmt<OMPLoopDirective>;
def OMPTargetSimdDirective : DStmt<OMPLoopDirective>;
def OMPTeamsDistributeDirective : DStmt<OMPLoopDirective>;
def OMPTeamsDistributeSimdDirective : DStmt<OMPLoopDirective>;
def OMPTeamsDistributeParallelForSimdDirective : DStmt<OMPLoopDirective>;
def OMPTeamsDistributeParallelForDirective : DStmt<OMPLoopDirective>;
def OMPTargetTeamsDirective : DStmt<OMPExecutableDirective>;
def OMPTargetTeamsDistributeDirective : DStmt<OMPLoopDirective>;
def OMPTargetTeamsDistributeParallelForDirective : DStmt<OMPLoopDirective>;
def OMPTargetTeamsDistributeParallelForSimdDirective : DStmt<OMPLoopDirective>;
def OMPTargetTeamsDistributeSimdDirective : DStmt<OMPLoopDirective>;
def OMPExecutableDirective : StmtNode<Stmt, 1>;
def OMPLoopDirective : StmtNode<OMPExecutableDirective, 1>;
def OMPParallelDirective : StmtNode<OMPExecutableDirective>;
def OMPSimdDirective : StmtNode<OMPLoopDirective>;
def OMPForDirective : StmtNode<OMPLoopDirective>;
def OMPForSimdDirective : StmtNode<OMPLoopDirective>;
def OMPSectionsDirective : StmtNode<OMPExecutableDirective>;
def OMPSectionDirective : StmtNode<OMPExecutableDirective>;
def OMPSingleDirective : StmtNode<OMPExecutableDirective>;
def OMPMasterDirective : StmtNode<OMPExecutableDirective>;
def OMPCriticalDirective : StmtNode<OMPExecutableDirective>;
def OMPParallelForDirective : StmtNode<OMPLoopDirective>;
def OMPParallelForSimdDirective : StmtNode<OMPLoopDirective>;
def OMPParallelMasterDirective : StmtNode<OMPExecutableDirective>;
def OMPParallelSectionsDirective : StmtNode<OMPExecutableDirective>;
def OMPTaskDirective : StmtNode<OMPExecutableDirective>;
def OMPTaskyieldDirective : StmtNode<OMPExecutableDirective>;
def OMPBarrierDirective : StmtNode<OMPExecutableDirective>;
def OMPTaskwaitDirective : StmtNode<OMPExecutableDirective>;
def OMPTaskgroupDirective : StmtNode<OMPExecutableDirective>;
def OMPFlushDirective : StmtNode<OMPExecutableDirective>;
def OMPOrderedDirective : StmtNode<OMPExecutableDirective>;
def OMPAtomicDirective : StmtNode<OMPExecutableDirective>;
def OMPTargetDirective : StmtNode<OMPExecutableDirective>;
def OMPTargetDataDirective : StmtNode<OMPExecutableDirective>;
def OMPTargetEnterDataDirective : StmtNode<OMPExecutableDirective>;
def OMPTargetExitDataDirective : StmtNode<OMPExecutableDirective>;
def OMPTargetParallelDirective : StmtNode<OMPExecutableDirective>;
def OMPTargetParallelForDirective : StmtNode<OMPExecutableDirective>;
def OMPTargetUpdateDirective : StmtNode<OMPExecutableDirective>;
def OMPTeamsDirective : StmtNode<OMPExecutableDirective>;
def OMPCancellationPointDirective : StmtNode<OMPExecutableDirective>;
def OMPCancelDirective : StmtNode<OMPExecutableDirective>;
def OMPTaskLoopDirective : StmtNode<OMPLoopDirective>;
def OMPTaskLoopSimdDirective : StmtNode<OMPLoopDirective>;
def OMPMasterTaskLoopDirective : StmtNode<OMPLoopDirective>;
def OMPMasterTaskLoopSimdDirective : StmtNode<OMPLoopDirective>;
def OMPParallelMasterTaskLoopDirective : StmtNode<OMPLoopDirective>;
def OMPParallelMasterTaskLoopSimdDirective : StmtNode<OMPLoopDirective>;
def OMPDistributeDirective : StmtNode<OMPLoopDirective>;
def OMPDistributeParallelForDirective : StmtNode<OMPLoopDirective>;
def OMPDistributeParallelForSimdDirective : StmtNode<OMPLoopDirective>;
def OMPDistributeSimdDirective : StmtNode<OMPLoopDirective>;
def OMPTargetParallelForSimdDirective : StmtNode<OMPLoopDirective>;
def OMPTargetSimdDirective : StmtNode<OMPLoopDirective>;
def OMPTeamsDistributeDirective : StmtNode<OMPLoopDirective>;
def OMPTeamsDistributeSimdDirective : StmtNode<OMPLoopDirective>;
def OMPTeamsDistributeParallelForSimdDirective : StmtNode<OMPLoopDirective>;
def OMPTeamsDistributeParallelForDirective : StmtNode<OMPLoopDirective>;
def OMPTargetTeamsDirective : StmtNode<OMPExecutableDirective>;
def OMPTargetTeamsDistributeDirective : StmtNode<OMPLoopDirective>;
def OMPTargetTeamsDistributeParallelForDirective : StmtNode<OMPLoopDirective>;
def OMPTargetTeamsDistributeParallelForSimdDirective : StmtNode<OMPLoopDirective>;
def OMPTargetTeamsDistributeSimdDirective : StmtNode<OMPLoopDirective>;

View File

@ -103,6 +103,12 @@ class TargetCXXABI {
/// of these details is necessarily final yet.
WebAssembly,
/// The Fuchsia ABI is a modified version of the Itanium ABI.
///
/// The relevant changes from the Itanium ABI are:
/// - constructors and destructors return 'this', as in ARM.
Fuchsia,
/// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and
/// compatible compilers).
///
@ -133,6 +139,7 @@ class TargetCXXABI {
/// Does this ABI generally fall into the Itanium family of ABIs?
bool isItaniumFamily() const {
switch (getKind()) {
case Fuchsia:
case GenericAArch64:
case GenericItanium:
case GenericARM:
@ -152,6 +159,7 @@ class TargetCXXABI {
/// Is this ABI an MSVC-compatible ABI?
bool isMicrosoft() const {
switch (getKind()) {
case Fuchsia:
case GenericAArch64:
case GenericItanium:
case GenericARM:
@ -182,6 +190,7 @@ class TargetCXXABI {
case WebAssembly:
// WebAssembly doesn't require any special alignment for member functions.
return false;
case Fuchsia:
case GenericARM:
case GenericAArch64:
case GenericMIPS:
@ -257,6 +266,7 @@ class TargetCXXABI {
/// done on a generic Itanium platform.
bool canKeyFunctionBeInline() const {
switch (getKind()) {
case Fuchsia:
case GenericARM:
case iOS64:
case WebAssembly:
@ -277,27 +287,18 @@ class TargetCXXABI {
/// padding of a base class?
///
/// This decision cannot be changed without breaking platform ABI
/// compatibility, and yet it is tied to language guarantees which
/// the committee has so far seen fit to strengthen no less than
/// three separate times:
/// - originally, there were no restrictions at all;
/// - C++98 declared that objects could not be allocated in the
/// tail padding of a POD type;
/// - C++03 extended the definition of POD to include classes
/// containing member pointers; and
/// - C++11 greatly broadened the definition of POD to include
/// all trivial standard-layout classes.
/// Each of these changes technically took several existing
/// platforms and made them permanently non-conformant.
/// compatibility. In ISO C++98, tail padding reuse was only permitted for
/// non-POD base classes, but that restriction was removed retroactively by
/// DR 43, and tail padding reuse is always permitted in all de facto C++
/// language modes. However, many platforms use a variant of the old C++98
/// rule for compatibility.
enum TailPaddingUseRules {
/// The tail-padding of a base class is always theoretically
/// available, even if it's POD. This is not strictly conforming
/// in any language mode.
/// available, even if it's POD.
AlwaysUseTailPadding,
/// Only allocate objects in the tail padding of a base class if
/// the base class is not POD according to the rules of C++ TR1.
/// This is non-strictly conforming in C++11 mode.
UseTailPaddingUnlessPOD03,
/// Only allocate objects in the tail padding of a base class if
@ -318,6 +319,7 @@ class TargetCXXABI {
// iOS on ARM64 and WebAssembly use the C++11 POD rules. They do not honor
// the Itanium exception about classes with over-large bitfields.
case Fuchsia:
case iOS64:
case WebAssembly:
case WatchOS:

View File

@ -16,6 +16,7 @@
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetCXXABI.h"
#include "clang/Basic/TargetOptions.h"
@ -944,12 +945,14 @@ class TargetInfo : public virtual TransferrableTargetInfo,
bool validateInputConstraint(MutableArrayRef<ConstraintInfo> OutputConstraints,
ConstraintInfo &info) const;
virtual bool validateOutputSize(StringRef /*Constraint*/,
virtual bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
StringRef /*Constraint*/,
unsigned /*Size*/) const {
return true;
}
virtual bool validateInputSize(StringRef /*Constraint*/,
virtual bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,
StringRef /*Constraint*/,
unsigned /*Size*/) const {
return true;
}
@ -1103,6 +1106,23 @@ class TargetInfo : public virtual TransferrableTargetInfo,
return true;
}
struct BranchProtectionInfo {
CodeGenOptions::SignReturnAddressScope SignReturnAddr =
CodeGenOptions::SignReturnAddressScope::None;
CodeGenOptions::SignReturnAddressKeyValue SignKey =
CodeGenOptions::SignReturnAddressKeyValue::AKey;
bool BranchTargetEnforcement = false;
};
/// Determine if this TargetInfo supports the given branch protection
/// specification
virtual bool validateBranchProtection(StringRef Spec,
BranchProtectionInfo &BPI,
StringRef &Err) const {
Err = "";
return false;
}
/// Perform initialization based on the user configured
/// set of features (e.g., +sse4).
///
@ -1126,10 +1146,7 @@ class TargetInfo : public virtual TransferrableTargetInfo,
/// Identify whether this target supports multiversioning of functions,
/// which requires support for cpu_supports and cpu_is functionality.
bool supportsMultiVersioning() const {
return getTriple().getArch() == llvm::Triple::x86 ||
getTriple().getArch() == llvm::Triple::x86_64;
}
bool supportsMultiVersioning() const { return getTriple().isX86(); }
/// Identify whether this target supports IFuncs.
bool supportsIFunc() const { return getTriple().isOSBinFormatELF(); }
@ -1194,8 +1211,7 @@ class TargetInfo : public virtual TransferrableTargetInfo,
/// Whether the target supports SEH __try.
bool isSEHTrySupported() const {
return getTriple().isOSWindows() &&
(getTriple().getArch() == llvm::Triple::x86 ||
getTriple().getArch() == llvm::Triple::x86_64 ||
(getTriple().isX86() ||
getTriple().getArch() == llvm::Triple::aarch64);
}
@ -1371,6 +1387,9 @@ class TargetInfo : public virtual TransferrableTargetInfo,
virtual void setAuxTarget(const TargetInfo *Aux) {}
/// Whether target allows debuginfo types for decl only variables.
virtual bool allowDebugInfoForExternalVar() const { return false; }
protected:
/// Copy type and layout related info.
void copyAuxTarget(const TargetInfo *Aux);

View File

@ -524,6 +524,8 @@ TYPE_TRAIT_2(__is_same, IsSame, KEYCXX)
TYPE_TRAIT_2(__is_convertible, IsConvertible, KEYCXX)
KEYWORD(__array_rank , KEYCXX)
KEYWORD(__array_extent , KEYCXX)
// Name for GCC 6 compatibility.
ALIAS("__is_same_as", __is_same, KEYCXX)
// Apple Extension.
KEYWORD(__private_extern__ , KEYALL)
@ -727,7 +729,9 @@ ANNOTATION(typename) // annotation for a C typedef name, a C++ (possibly
// template-id that names a type ("std::vector<int>")
ANNOTATION(template_id) // annotation for a C++ template-id that names a
// function template specialization (not a type),
// e.g., "std::swap<int>"
// e.g., "std::swap<int>", or a type-constraint (which
// might not have explicit template arguments),
// e.g. "C", "C<int>".
ANNOTATION(non_type) // annotation for a single non-type declaration
ANNOTATION(non_type_undeclared) // annotation for an undeclared identifier that
// was assumed to be an ADL-only function name

View File

@ -1,11 +1,10 @@
class Type<bit abstract = 0> {
include "clang/Basic/ASTNode.td"
class TypeNode<TypeNode base, bit abstract = 0> : ASTNode {
TypeNode Base = base;
bit Abstract = abstract;
}
class DerivedType<Type base, bit abstract = 0> : Type<abstract> {
Type Base = base;
}
/// A type node that is only used to represent dependent types in C++. For
/// example, DependentTemplateSpecializationType is used to represent types
/// where the base template-id is dependent (such as `T::foo<U>`). Code
@ -51,56 +50,57 @@ class NeverCanonicalUnlessDependent {}
/// to types that may not be leaves should not declare this.
class LeafType {}
def BuiltinType : Type, LeafType;
def ComplexType : Type;
def PointerType : Type;
def BlockPointerType : Type;
def ReferenceType : Type<1>;
def LValueReferenceType : DerivedType<ReferenceType>;
def RValueReferenceType : DerivedType<ReferenceType>;
def MemberPointerType : Type;
def ArrayType : Type<1>;
def ConstantArrayType : DerivedType<ArrayType>;
def IncompleteArrayType : DerivedType<ArrayType>;
def VariableArrayType : DerivedType<ArrayType>;
def DependentSizedArrayType : DerivedType<ArrayType>, AlwaysDependent;
def DependentSizedExtVectorType : Type, AlwaysDependent;
def DependentAddressSpaceType : Type, AlwaysDependent;
def VectorType : Type;
def DependentVectorType : Type, AlwaysDependent;
def ExtVectorType : DerivedType<VectorType>;
def FunctionType : Type<1>;
def FunctionProtoType : DerivedType<FunctionType>;
def FunctionNoProtoType : DerivedType<FunctionType>;
def UnresolvedUsingType : Type, AlwaysDependent;
def ParenType : Type, NeverCanonical;
def TypedefType : Type, NeverCanonical;
def MacroQualifiedType : Type, NeverCanonical;
def AdjustedType : Type, NeverCanonical;
def DecayedType : DerivedType<AdjustedType>, NeverCanonical;
def TypeOfExprType : Type, NeverCanonicalUnlessDependent;
def TypeOfType : Type, NeverCanonicalUnlessDependent;
def DecltypeType : Type, NeverCanonicalUnlessDependent;
def UnaryTransformType : Type, NeverCanonicalUnlessDependent;
def TagType : Type<1>;
def RecordType : DerivedType<TagType>, LeafType;
def EnumType : DerivedType<TagType>, LeafType;
def ElaboratedType : Type, NeverCanonical;
def AttributedType : Type, NeverCanonical;
def TemplateTypeParmType : Type, AlwaysDependent, LeafType;
def SubstTemplateTypeParmType : Type, NeverCanonical;
def SubstTemplateTypeParmPackType : Type, AlwaysDependent;
def TemplateSpecializationType : Type, NeverCanonicalUnlessDependent;
def DeducedType : Type<1>;
def AutoType : DerivedType<DeducedType>;
def DeducedTemplateSpecializationType : DerivedType<DeducedType>;
def InjectedClassNameType : Type, AlwaysDependent, LeafType;
def DependentNameType : Type, AlwaysDependent;
def DependentTemplateSpecializationType : Type, AlwaysDependent;
def PackExpansionType : Type, NeverCanonicalUnlessDependent;
def ObjCTypeParamType : Type, NeverCanonical;
def ObjCObjectType : Type;
def ObjCInterfaceType : DerivedType<ObjCObjectType>, LeafType;
def ObjCObjectPointerType : Type;
def PipeType : Type;
def AtomicType : Type;
def Type : TypeNode<?, 1>;
def BuiltinType : TypeNode<Type>, LeafType;
def ComplexType : TypeNode<Type>;
def PointerType : TypeNode<Type>;
def BlockPointerType : TypeNode<Type>;
def ReferenceType : TypeNode<Type, 1>;
def LValueReferenceType : TypeNode<ReferenceType>;
def RValueReferenceType : TypeNode<ReferenceType>;
def MemberPointerType : TypeNode<Type>;
def ArrayType : TypeNode<Type, 1>;
def ConstantArrayType : TypeNode<ArrayType>;
def IncompleteArrayType : TypeNode<ArrayType>;
def VariableArrayType : TypeNode<ArrayType>;
def DependentSizedArrayType : TypeNode<ArrayType>, AlwaysDependent;
def DependentSizedExtVectorType : TypeNode<Type>, AlwaysDependent;
def DependentAddressSpaceType : TypeNode<Type>, AlwaysDependent;
def VectorType : TypeNode<Type>;
def DependentVectorType : TypeNode<Type>, AlwaysDependent;
def ExtVectorType : TypeNode<VectorType>;
def FunctionType : TypeNode<Type, 1>;
def FunctionProtoType : TypeNode<FunctionType>;
def FunctionNoProtoType : TypeNode<FunctionType>;
def UnresolvedUsingType : TypeNode<Type>, AlwaysDependent;
def ParenType : TypeNode<Type>, NeverCanonical;
def TypedefType : TypeNode<Type>, NeverCanonical;
def MacroQualifiedType : TypeNode<Type>, NeverCanonical;
def AdjustedType : TypeNode<Type>, NeverCanonical;
def DecayedType : TypeNode<AdjustedType>, NeverCanonical;
def TypeOfExprType : TypeNode<Type>, NeverCanonicalUnlessDependent;
def TypeOfType : TypeNode<Type>, NeverCanonicalUnlessDependent;
def DecltypeType : TypeNode<Type>, NeverCanonicalUnlessDependent;
def UnaryTransformType : TypeNode<Type>, NeverCanonicalUnlessDependent;
def TagType : TypeNode<Type, 1>;
def RecordType : TypeNode<TagType>, LeafType;
def EnumType : TypeNode<TagType>, LeafType;
def ElaboratedType : TypeNode<Type>, NeverCanonical;
def AttributedType : TypeNode<Type>, NeverCanonical;
def TemplateTypeParmType : TypeNode<Type>, AlwaysDependent, LeafType;
def SubstTemplateTypeParmType : TypeNode<Type>, NeverCanonical;
def SubstTemplateTypeParmPackType : TypeNode<Type>, AlwaysDependent;
def TemplateSpecializationType : TypeNode<Type>, NeverCanonicalUnlessDependent;
def DeducedType : TypeNode<Type, 1>;
def AutoType : TypeNode<DeducedType>;
def DeducedTemplateSpecializationType : TypeNode<DeducedType>;
def InjectedClassNameType : TypeNode<Type>, AlwaysDependent, LeafType;
def DependentNameType : TypeNode<Type>, AlwaysDependent;
def DependentTemplateSpecializationType : TypeNode<Type>, AlwaysDependent;
def PackExpansionType : TypeNode<Type>, NeverCanonicalUnlessDependent;
def ObjCTypeParamType : TypeNode<Type>, NeverCanonical;
def ObjCObjectType : TypeNode<Type>;
def ObjCInterfaceType : TypeNode<ObjCObjectType>, LeafType;
def ObjCObjectPointerType : TypeNode<Type>;
def PipeType : TypeNode<Type>;
def AtomicType : TypeNode<Type>;

View File

@ -17,114 +17,118 @@ include "arm_neon_incl.td"
let ArchGuard = "defined(__ARM_FEATURE_FP16_SCALAR_ARITHMETIC) && defined(__aarch64__)" in {
// Negate
def VNEGSH : SInst<"vneg", "ss", "Sh">;
def VNEGSH : SInst<"vneg", "11", "Sh">;
// Reciprocal/Sqrt
def SCALAR_FRECPSH : IInst<"vrecps", "sss", "Sh">;
def FSQRTSH : SInst<"vsqrt", "ss", "Sh">;
def SCALAR_FRSQRTSH : IInst<"vrsqrts", "sss", "Sh">;
def SCALAR_FRECPSH : IInst<"vrecps", "111", "Sh">;
def FSQRTSH : SInst<"vsqrt", "11", "Sh">;
def SCALAR_FRSQRTSH : IInst<"vrsqrts", "111", "Sh">;
// Reciprocal Estimate
def SCALAR_FRECPEH : IInst<"vrecpe", "ss", "Sh">;
def SCALAR_FRECPEH : IInst<"vrecpe", "11", "Sh">;
// Reciprocal Exponent
def SCALAR_FRECPXH : IInst<"vrecpx", "ss", "Sh">;
def SCALAR_FRECPXH : IInst<"vrecpx", "11", "Sh">;
// Reciprocal Square Root Estimate
def SCALAR_FRSQRTEH : IInst<"vrsqrte", "ss", "Sh">;
def SCALAR_FRSQRTEH : IInst<"vrsqrte", "11", "Sh">;
// Rounding
def FRINTZ_S64H : SInst<"vrnd", "ss", "Sh">;
def FRINTA_S64H : SInst<"vrnda", "ss", "Sh">;
def FRINTI_S64H : SInst<"vrndi", "ss", "Sh">;
def FRINTM_S64H : SInst<"vrndm", "ss", "Sh">;
def FRINTN_S64H : SInst<"vrndn", "ss", "Sh">;
def FRINTP_S64H : SInst<"vrndp", "ss", "Sh">;
def FRINTX_S64H : SInst<"vrndx", "ss", "Sh">;
def FRINTZ_S64H : SInst<"vrnd", "11", "Sh">;
def FRINTA_S64H : SInst<"vrnda", "11", "Sh">;
def FRINTI_S64H : SInst<"vrndi", "11", "Sh">;
def FRINTM_S64H : SInst<"vrndm", "11", "Sh">;
def FRINTN_S64H : SInst<"vrndn", "11", "Sh">;
def FRINTP_S64H : SInst<"vrndp", "11", "Sh">;
def FRINTX_S64H : SInst<"vrndx", "11", "Sh">;
// Conversion
def SCALAR_SCVTFSH : SInst<"vcvth_f16", "Ys", "silUsUiUl">;
def SCALAR_FCVTZSH : SInst<"vcvt_s16", "$s", "Sh">;
def SCALAR_FCVTZSH1 : SInst<"vcvt_s32", "Is", "Sh">;
def SCALAR_FCVTZSH2 : SInst<"vcvt_s64", "Ls", "Sh">;
def SCALAR_FCVTZUH : SInst<"vcvt_u16", "bs", "Sh">;
def SCALAR_FCVTZUH1 : SInst<"vcvt_u32", "Us", "Sh">;
def SCALAR_FCVTZUH2 : SInst<"vcvt_u64", "Os", "Sh">;
def SCALAR_FCVTASH : SInst<"vcvta_s16", "$s", "Sh">;
def SCALAR_FCVTASH1 : SInst<"vcvta_s32", "Is", "Sh">;
def SCALAR_FCVTASH2 : SInst<"vcvta_s64", "Ls", "Sh">;
def SCALAR_FCVTAUH : SInst<"vcvta_u16", "bs", "Sh">;
def SCALAR_FCVTAUH1 : SInst<"vcvta_u32", "Us", "Sh">;
def SCALAR_FCVTAUH2 : SInst<"vcvta_u64", "Os", "Sh">;
def SCALAR_FCVTMSH : SInst<"vcvtm_s16", "$s", "Sh">;
def SCALAR_FCVTMSH1 : SInst<"vcvtm_s32", "Is", "Sh">;
def SCALAR_FCVTMSH2 : SInst<"vcvtm_s64", "Ls", "Sh">;
def SCALAR_FCVTMUH : SInst<"vcvtm_u16", "bs", "Sh">;
def SCALAR_FCVTMUH1 : SInst<"vcvtm_u32", "Us", "Sh">;
def SCALAR_FCVTMUH2 : SInst<"vcvtm_u64", "Os", "Sh">;
def SCALAR_FCVTNSH : SInst<"vcvtn_s16", "$s", "Sh">;
def SCALAR_FCVTNSH1 : SInst<"vcvtn_s32", "Is", "Sh">;
def SCALAR_FCVTNSH2 : SInst<"vcvtn_s64", "Ls", "Sh">;
def SCALAR_FCVTNUH : SInst<"vcvtn_u16", "bs", "Sh">;
def SCALAR_FCVTNUH1 : SInst<"vcvtn_u32", "Us", "Sh">;
def SCALAR_FCVTNUH2 : SInst<"vcvtn_u64", "Os", "Sh">;
def SCALAR_FCVTPSH : SInst<"vcvtp_s16", "$s", "Sh">;
def SCALAR_FCVTPSH1 : SInst<"vcvtp_s32", "Is", "Sh">;
def SCALAR_FCVTPSH2 : SInst<"vcvtp_s64", "Ls", "Sh">;
def SCALAR_FCVTPUH : SInst<"vcvtp_u16", "bs", "Sh">;
def SCALAR_FCVTPUH1 : SInst<"vcvtp_u32", "Us", "Sh">;
def SCALAR_FCVTPUH2 : SInst<"vcvtp_u64", "Os", "Sh">;
def SCALAR_SCVTFSH : SInst<"vcvth_f16", "(1F)(1!)", "sUs">;
def SCALAR_SCVTFSH1 : SInst<"vcvth_f16", "(1F<)(1!)", "iUi">;
def SCALAR_SCVTFSH2 : SInst<"vcvth_f16", "(1F<<)(1!)", "lUl">;
def SCALAR_FCVTZSH : SInst<"vcvt_s16", "(1S)1", "Sh">;
def SCALAR_FCVTZSH1 : SInst<"vcvt_s32", "(1S>)1", "Sh">;
def SCALAR_FCVTZSH2 : SInst<"vcvt_s64", "(1S>>)1", "Sh">;
def SCALAR_FCVTZUH : SInst<"vcvt_u16", "(1U)1", "Sh">;
def SCALAR_FCVTZUH1 : SInst<"vcvt_u32", "(1U>)1", "Sh">;
def SCALAR_FCVTZUH2 : SInst<"vcvt_u64", "(1U>>)1", "Sh">;
def SCALAR_FCVTASH : SInst<"vcvta_s16", "(1S)1", "Sh">;
def SCALAR_FCVTASH1 : SInst<"vcvta_s32", "(1S>)1", "Sh">;
def SCALAR_FCVTASH2 : SInst<"vcvta_s64", "(1S>>)1", "Sh">;
def SCALAR_FCVTAUH : SInst<"vcvta_u16", "(1U)1", "Sh">;
def SCALAR_FCVTAUH1 : SInst<"vcvta_u32", "(1U>)1", "Sh">;
def SCALAR_FCVTAUH2 : SInst<"vcvta_u64", "(1U>>)1", "Sh">;
def SCALAR_FCVTMSH : SInst<"vcvtm_s16", "(1S)1", "Sh">;
def SCALAR_FCVTMSH1 : SInst<"vcvtm_s32", "(1S>)1", "Sh">;
def SCALAR_FCVTMSH2 : SInst<"vcvtm_s64", "(1S>>)1", "Sh">;
def SCALAR_FCVTMUH : SInst<"vcvtm_u16", "(1U)1", "Sh">;
def SCALAR_FCVTMUH1 : SInst<"vcvtm_u32", "(1U>)1", "Sh">;
def SCALAR_FCVTMUH2 : SInst<"vcvtm_u64", "(1U>>)1", "Sh">;
def SCALAR_FCVTNSH : SInst<"vcvtn_s16", "(1S)1", "Sh">;
def SCALAR_FCVTNSH1 : SInst<"vcvtn_s32", "(1S>)1", "Sh">;
def SCALAR_FCVTNSH2 : SInst<"vcvtn_s64", "(1S>>)1", "Sh">;
def SCALAR_FCVTNUH : SInst<"vcvtn_u16", "(1U)1", "Sh">;
def SCALAR_FCVTNUH1 : SInst<"vcvtn_u32", "(1U>)1", "Sh">;
def SCALAR_FCVTNUH2 : SInst<"vcvtn_u64", "(1U>>)1", "Sh">;
def SCALAR_FCVTPSH : SInst<"vcvtp_s16", "(1S)1", "Sh">;
def SCALAR_FCVTPSH1 : SInst<"vcvtp_s32", "(1S>)1", "Sh">;
def SCALAR_FCVTPSH2 : SInst<"vcvtp_s64", "(1S>>)1", "Sh">;
def SCALAR_FCVTPUH : SInst<"vcvtp_u16", "(1U)1", "Sh">;
def SCALAR_FCVTPUH1 : SInst<"vcvtp_u32", "(1U>)1", "Sh">;
def SCALAR_FCVTPUH2 : SInst<"vcvtp_u64", "(1U>>)1", "Sh">;
let isVCVT_N = 1 in {
def SCALAR_SCVTFSHO : SInst<"vcvth_n_f16", "Ysi", "silUsUiUl">;
def SCALAR_FCVTZSHO : SInst<"vcvt_n_s16", "$si", "Sh">;
def SCALAR_FCVTZSH1O: SInst<"vcvt_n_s32", "Isi", "Sh">;
def SCALAR_FCVTZSH2O: SInst<"vcvt_n_s64", "Lsi", "Sh">;
def SCALAR_FCVTZUHO : SInst<"vcvt_n_u16", "bsi", "Sh">;
def SCALAR_FCVTZUH1O: SInst<"vcvt_n_u32", "Usi", "Sh">;
def SCALAR_FCVTZUH2O: SInst<"vcvt_n_u64", "Osi", "Sh">;
def SCALAR_SCVTFSHO : SInst<"vcvth_n_f16", "(1F)(1!)I", "sUs">;
def SCALAR_SCVTFSH1O: SInst<"vcvth_n_f16", "(1F<)(1!)I", "iUi">;
def SCALAR_SCVTFSH2O: SInst<"vcvth_n_f16", "(1F<<)(1!)I", "lUl">;
def SCALAR_FCVTZSHO : SInst<"vcvt_n_s16", "(1S)1I", "Sh">;
def SCALAR_FCVTZSH1O: SInst<"vcvt_n_s32", "(1S>)1I", "Sh">;
def SCALAR_FCVTZSH2O: SInst<"vcvt_n_s64", "(1S>>)1I", "Sh">;
def SCALAR_FCVTZUHO : SInst<"vcvt_n_u16", "(1U)1I", "Sh">;
def SCALAR_FCVTZUH1O: SInst<"vcvt_n_u32", "(1U>)1I", "Sh">;
def SCALAR_FCVTZUH2O: SInst<"vcvt_n_u64", "(1U>>)1I", "Sh">;
}
// Comparison
def SCALAR_CMEQRH : SInst<"vceq", "bss", "Sh">;
def SCALAR_CMEQZH : SInst<"vceqz", "bs", "Sh">;
def SCALAR_CMGERH : SInst<"vcge", "bss", "Sh">;
def SCALAR_CMGEZH : SInst<"vcgez", "bs", "Sh">;
def SCALAR_CMGTRH : SInst<"vcgt", "bss", "Sh">;
def SCALAR_CMGTZH : SInst<"vcgtz", "bs", "Sh">;
def SCALAR_CMLERH : SInst<"vcle", "bss", "Sh">;
def SCALAR_CMLEZH : SInst<"vclez", "bs", "Sh">;
def SCALAR_CMLTH : SInst<"vclt", "bss", "Sh">;
def SCALAR_CMLTZH : SInst<"vcltz", "bs", "Sh">;
def SCALAR_CMEQRH : SInst<"vceq", "(1U)11", "Sh">;
def SCALAR_CMEQZH : SInst<"vceqz", "(1U)1", "Sh">;
def SCALAR_CMGERH : SInst<"vcge", "(1U)11", "Sh">;
def SCALAR_CMGEZH : SInst<"vcgez", "(1U)1", "Sh">;
def SCALAR_CMGTRH : SInst<"vcgt", "(1U)11", "Sh">;
def SCALAR_CMGTZH : SInst<"vcgtz", "(1U)1", "Sh">;
def SCALAR_CMLERH : SInst<"vcle", "(1U)11", "Sh">;
def SCALAR_CMLEZH : SInst<"vclez", "(1U)1", "Sh">;
def SCALAR_CMLTH : SInst<"vclt", "(1U)11", "Sh">;
def SCALAR_CMLTZH : SInst<"vcltz", "(1U)1", "Sh">;
// Absolute Compare Mask Greater Than Or Equal
def SCALAR_FACGEH : IInst<"vcage", "bss", "Sh">;
def SCALAR_FACLEH : IInst<"vcale", "bss", "Sh">;
def SCALAR_FACGEH : IInst<"vcage", "(1U)11", "Sh">;
def SCALAR_FACLEH : IInst<"vcale", "(1U)11", "Sh">;
// Absolute Compare Mask Greater Than
def SCALAR_FACGT : IInst<"vcagt", "bss", "Sh">;
def SCALAR_FACLT : IInst<"vcalt", "bss", "Sh">;
def SCALAR_FACGT : IInst<"vcagt", "(1U)11", "Sh">;
def SCALAR_FACLT : IInst<"vcalt", "(1U)11", "Sh">;
// Scalar Absolute Value
def SCALAR_ABSH : SInst<"vabs", "ss", "Sh">;
def SCALAR_ABSH : SInst<"vabs", "11", "Sh">;
// Scalar Absolute Difference
def SCALAR_ABDH: IInst<"vabd", "sss", "Sh">;
def SCALAR_ABDH: IInst<"vabd", "111", "Sh">;
// Add/Sub
def VADDSH : SInst<"vadd", "sss", "Sh">;
def VSUBHS : SInst<"vsub", "sss", "Sh">;
def VADDSH : SInst<"vadd", "111", "Sh">;
def VSUBHS : SInst<"vsub", "111", "Sh">;
// Max/Min
def VMAXHS : SInst<"vmax", "sss", "Sh">;
def VMINHS : SInst<"vmin", "sss", "Sh">;
def FMAXNMHS : SInst<"vmaxnm", "sss", "Sh">;
def FMINNMHS : SInst<"vminnm", "sss", "Sh">;
def VMAXHS : SInst<"vmax", "111", "Sh">;
def VMINHS : SInst<"vmin", "111", "Sh">;
def FMAXNMHS : SInst<"vmaxnm", "111", "Sh">;
def FMINNMHS : SInst<"vminnm", "111", "Sh">;
// Multiplication/Division
def VMULHS : SInst<"vmul", "sss", "Sh">;
def MULXHS : SInst<"vmulx", "sss", "Sh">;
def FDIVHS : SInst<"vdiv", "sss", "Sh">;
def VMULHS : SInst<"vmul", "111", "Sh">;
def MULXHS : SInst<"vmulx", "111", "Sh">;
def FDIVHS : SInst<"vdiv", "111", "Sh">;
// Vector fused multiply-add operations
def VFMAHS : SInst<"vfma", "ssss", "Sh">;
def VFMSHS : SInst<"vfms", "ssss", "Sh">;
def VFMAHS : SInst<"vfma", "1111", "Sh">;
def VFMSHS : SInst<"vfms", "1111", "Sh">;
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More