Vendor import of clang release_60 branch r321788:

https://llvm.org/svn/llvm-project/cfe/branches/release_60@321788
This commit is contained in:
Dimitry Andric 2018-01-06 21:35:46 +00:00
parent 55e6d896ad
commit ead8c8e4f1
868 changed files with 10973 additions and 1418 deletions

File diff suppressed because it is too large Load Diff

View File

@ -120,6 +120,10 @@ Output path for the plist report
.. option:: -compatibility\_version<arg>
.. option:: --config <arg>
Specifies configuration file
.. option:: --constant-cfstrings
.. option:: -coverage, --coverage
@ -1545,6 +1549,10 @@ Enable ARC-style weak references in Objective-C
OpenMP target code is compiled as relocatable using the -c flag. For OpenMP targets the code is relocatable by default.
.. option:: -fopenmp-simd, -fno-openmp-simd
Emit OpenMP code only for SIMD-based constructs.
.. option:: -fopenmp-use-tls
.. option:: -fopenmp-version=<arg>
@ -1998,7 +2006,7 @@ Link stack frames through backchain on System Z
.. option:: -mconsole<arg>
.. option:: -mcpu=<arg>, -mv4 (equivalent to -mcpu=hexagonv4), -mv5 (equivalent to -mcpu=hexagonv5), -mv55 (equivalent to -mcpu=hexagonv55), -mv60 (equivalent to -mcpu=hexagonv60), -mv62 (equivalent to -mcpu=hexagonv62)
.. option:: -mcpu=<arg>, -mv4 (equivalent to -mcpu=hexagonv4), -mv5 (equivalent to -mcpu=hexagonv5), -mv55 (equivalent to -mcpu=hexagonv55), -mv60 (equivalent to -mcpu=hexagonv60), -mv62 (equivalent to -mcpu=hexagonv62), -mv65 (equivalent to -mcpu=hexagonv65)
.. option:: -mdefault-build-attributes<arg>, -mno-default-build-attributes<arg>
@ -2328,6 +2336,8 @@ X86
.. option:: -mavx2, -mno-avx2
.. option:: -mavx512bitalg, -mno-avx512bitalg
.. option:: -mavx512bw, -mno-avx512bw
.. option:: -mavx512cd, -mno-avx512cd
@ -2344,8 +2354,12 @@ X86
.. option:: -mavx512vbmi, -mno-avx512vbmi
.. option:: -mavx512vbmi2, -mno-avx512vbmi2
.. option:: -mavx512vl, -mno-avx512vl
.. option:: -mavx512vnni, -mno-avx512vnni
.. option:: -mavx512vpopcntdq, -mno-avx512vpopcntdq
.. option:: -mbmi, -mno-bmi
@ -2370,6 +2384,8 @@ X86
.. option:: -mfxsr, -mno-fxsr
.. option:: -mgfni, -mno-gfni
.. option:: -mibt, -mno-ibt
.. option:: -mlwp, -mno-lwp
@ -2424,6 +2440,10 @@ X86
.. option:: -mtbm, -mno-tbm
.. option:: -mvaes, -mno-vaes
.. option:: -mvpclmulqdq, -mno-vpclmulqdq
.. option:: -mx87, -m80387, -mno-x87
.. option:: -mxop, -mno-xop

View File

@ -168,8 +168,8 @@ Attribute Changes in Clang
Windows Support
---------------
Clang's support for building native Windows programs ...
- Clang now has initial, preliminary support for targeting Windows on
ARM64.
C Language Changes in Clang
---------------------------
@ -209,7 +209,18 @@ OpenCL C Language Changes in Clang
OpenMP Support in Clang
----------------------------------
...
- Added options `-f[no]-openmp-simd` that support code emission only foe OpenMP
SIMD-based directives, like `#pragma omp simd`, `#pragma omp parallel for simd`
etc. The code is emitted only for simd-based part of the combined directives
and clauses.
- Added support for almost all target-based directives except for
`#pragma omp target teams distribute parallel for [simd]`. Although, please
note that `depend` clauses on target-based directives are not supported yet.
Clang supports offloading to X86_64, AArch64 and PPC64[LE] devices.
- Added support for `reduction`-based clauses on `task`-based directives from
upcoming OpenMP 5.0.
Internal API Changes
--------------------

View File

@ -694,6 +694,79 @@ a special character, which is the convention used by GNU Make. The -MV
option tells Clang to put double-quotes around the entire filename, which
is the convention used by NMake and Jom.
Configuration files
-------------------
Configuration files group command-line options and allow all of them to be
specified just by referencing the configuration file. They may be used, for
example, to collect options required to tune compilation for particular
target, such as -L, -I, -l, --sysroot, codegen options, etc.
The command line option `--config` can be used to specify configuration
file in a Clang invocation. For example:
::
clang --config /home/user/cfgs/testing.txt
clang --config debug.cfg
If the provided argument contains a directory separator, it is considered as
a file path, and options are read from that file. Otherwise the argument is
treated as a file name and is searched for sequentially in the directories:
- user directory,
- system directory,
- the directory where Clang executable resides.
Both user and system directories for configuration files are specified during
clang build using CMake parameters, CLANG_CONFIG_FILE_USER_DIR and
CLANG_CONFIG_FILE_SYSTEM_DIR respectively. The first file found is used. It is
an error if the required file cannot be found.
Another way to specify a configuration file is to encode it in executable name.
For example, if the Clang executable is named `armv7l-clang` (it may be a
symbolic link to `clang`), then Clang will search for file `armv7l.cfg` in the
directory where Clang resides.
If a driver mode is specified in invocation, Clang tries to find a file specific
for the specified mode. For example, if the executable file is named
`x86_64-clang-cl`, Clang first looks for `x86_64-cl.cfg` and if it is not found,
looks for `x86_64.cfg`.
If the command line contains options that effectively change target architecture
(these are -m32, -EL, and some others) and the configuration file starts with an
architecture name, Clang tries to load the configuration file for the effective
architecture. For example, invocation:
::
x86_64-clang -m32 abc.c
causes Clang search for a file `i368.cfg` first, and if no such file is found,
Clang looks for the file `x86_64.cfg`.
The configuration file consists of command-line options specified on one or
more lines. Lines composed of whitespace characters only are ignored as well as
lines in which the first non-blank character is `#`. Long options may be split
between several lines by a trailing backslash. Here is example of a
configuration file:
::
# Several options on line
-c --target=x86_64-unknown-linux-gnu
# Long option split between lines
-I/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../\
include/c++/5.4.0
# other config files may be included
@linux.options
Files included by `@file` directives in configuration files are resolved
relative to the including file. For example, if a configuration file
`~/.llvm/target.cfg` contains the directive `@os/linux.opts`, the file
`linux.opts` is searched for in the directory `~/.llvm/os`.
Language and Target-Independent Features
========================================
@ -2042,6 +2115,11 @@ directives, and ``#pragma omp taskgroup`` directive.
Use `-fopenmp` to enable OpenMP. Support for OpenMP can be disabled with
`-fno-openmp`.
Use `-fopenmp-simd` to enable OpenMP simd features only, without linking
the runtime library; for combined constructs
(e.g. ``#pragma omp parallel for simd``) the non-simd directives and clauses
will be ignored. This can be disabled with `-fno-openmp-simd`.
Controlling implementation limits
---------------------------------
@ -2654,6 +2732,7 @@ Execute ``clang-cl /?`` to see a list of supported options:
/Gd Set __cdecl as a default calling convention
/GF- Disable string pooling
/GR- Disable emission of RTTI data
/Gregcall Set __regcall as a default calling convention
/GR Enable emission of RTTI data
/Gr Set __fastcall as a default calling convention
/GS- Disable buffer security check
@ -2710,7 +2789,7 @@ Execute ``clang-cl /?`` to see a list of supported options:
/W2 Enable -Wall
/W3 Enable -Wall
/W4 Enable -Wall and -Wextra
/Wall Enable -Wall and -Wextra
/Wall Enable -Weverything
/WX- Do not treat warnings as errors
/WX Treat warnings as errors
/w Disable all warnings
@ -2767,6 +2846,8 @@ Execute ``clang-cl /?`` to see a list of supported options:
Disable specified features of coverage instrumentation for Sanitizers
-fno-sanitize-memory-track-origins
Disable origins tracking in MemorySanitizer
-fno-sanitize-memory-use-after-dtor
Disable use-after-destroy detection in MemorySanitizer
-fno-sanitize-recover=<value>
Disable recovery for specified sanitizers
-fno-sanitize-stats Disable sanitizer statistics gathering.
@ -2797,6 +2878,8 @@ Execute ``clang-cl /?`` to see a list of supported options:
Path to blacklist file for sanitizers
-fsanitize-cfi-cross-dso
Enable control flow integrity (CFI) checks for cross-DSO calls.
-fsanitize-cfi-icall-generalize-pointers
Generalize pointers in CFI indirect call type signature checks
-fsanitize-coverage=<value>
Specify the type of coverage instrumentation for Sanitizers
-fsanitize-memory-track-origins=<value>
@ -2820,6 +2903,7 @@ Execute ``clang-cl /?`` to see a list of supported options:
-fsanitize=<check> Turn on runtime checks for various forms of undefined or suspicious
behavior. See user manual for available checks
-fstandalone-debug Emit full debug info for all types used by the program
-fwhole-program-vtables Enables whole-program vtable optimization. Requires -flto
-gcodeview Generate CodeView debug information
-gline-tables-only Emit debug line number tables only
-miamcu Use Intel MCU ABI
@ -2828,6 +2912,7 @@ Execute ``clang-cl /?`` to see a list of supported options:
-Qunused-arguments Don't emit warning for unused driver arguments
-R<remark> Enable the specified remark
--target=<value> Generate code for the given target
--version Print version information
-v Show commands to run and use verbose output
-W<warning> Enable the specified warning
-Xclang <arg> Pass <arg> to the clang compiler

View File

@ -193,16 +193,20 @@ class OMPExecutableDirective : public Stmt {
bool hasAssociatedStmt() const { return NumChildren > 0; }
/// \brief Returns statement associated with the directive.
Stmt *getAssociatedStmt() const {
const Stmt *getAssociatedStmt() const {
assert(hasAssociatedStmt() && "no associated statement.");
return const_cast<Stmt *>(*child_begin());
return *child_begin();
}
Stmt *getAssociatedStmt() {
assert(hasAssociatedStmt() && "no associated statement.");
return *child_begin();
}
/// \brief Returns the captured statement associated with the
/// component region within the (combined) directive.
//
// \param RegionKind Component region kind.
CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
assert(std::any_of(

View File

@ -112,6 +112,18 @@ def err_drv_invalid_argument_to_fdebug_prefix_map : Error<
"invalid argument '%0' to -fdebug-prefix-map">;
def err_drv_malformed_sanitizer_blacklist : Error<
"malformed sanitizer blacklist: '%0'">;
def err_drv_duplicate_config : Error<
"no more than one option '--config' is allowed">;
def err_drv_config_file_not_exist : Error<
"configuration file '%0' does not exist">;
def err_drv_config_file_not_found : Error<
"configuration file '%0' cannot be found">;
def note_drv_config_file_searched_in : Note<
"was searched for in the directory: %0">;
def err_drv_cannot_read_config_file : Error<
"cannot read configuration file '%0'">;
def err_drv_nested_config_file: Error<
"option '--config' is not allowed inside configuration file">;
def err_target_unsupported_arch
: Error<"the target architecture '%0' is not supported by the target '%1'">;

View File

@ -435,12 +435,16 @@ def StringCompare : DiagGroup<"string-compare">;
def StringPlusInt : DiagGroup<"string-plus-int">;
def StringPlusChar : DiagGroup<"string-plus-char">;
def StrncatSize : DiagGroup<"strncat-size">;
def TautologicalTypeLimitCompare : DiagGroup<"tautological-type-limit-compare">;
def TautologicalUnsignedZeroCompare : DiagGroup<"tautological-unsigned-zero-compare">;
def TautologicalUnsignedEnumZeroCompare : DiagGroup<"tautological-unsigned-enum-zero-compare">;
def TautologicalInRangeCompare : DiagGroup<"tautological-constant-in-range-compare",
[TautologicalTypeLimitCompare,
TautologicalUnsignedZeroCompare,
TautologicalUnsignedEnumZeroCompare]>;
def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
def TautologicalConstantCompare : DiagGroup<"tautological-constant-compare",
[TautologicalUnsignedZeroCompare,
TautologicalUnsignedEnumZeroCompare,
[TautologicalInRangeCompare,
TautologicalOutOfRangeCompare]>;
def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">;
@ -715,6 +719,7 @@ def IntToPointerCast : DiagGroup<"int-to-pointer-cast",
def Move : DiagGroup<"move", [PessimizingMove, RedundantMove, SelfMove]>;
def Extra : DiagGroup<"extra", [
TautologicalInRangeCompare,
MissingFieldInitializers,
IgnoredQualifiers,
InitializerOverrides,

View File

@ -1589,12 +1589,20 @@ def err_non_virtual_pure : Error<
def ext_pure_function_definition : ExtWarn<
"function definition with pure-specifier is a Microsoft extension">,
InGroup<MicrosoftPureDefinition>;
def err_implicit_object_parameter_init : Error<
"cannot initialize object parameter of type %0 with an expression "
"of type %1">;
def err_qualified_member_of_unrelated : Error<
"%q0 is not a member of class %1">;
def err_member_function_call_bad_cvr : Error<
"'this' argument to member function %0 has type %1, but function is not marked "
"%select{const|restrict|const or restrict|volatile|const or volatile|"
"volatile or restrict|const, volatile, or restrict}2">;
def err_member_function_call_bad_ref : Error<
"'this' argument to member function %0 is an %select{lvalue|rvalue}1, "
"but function has %select{non-const lvalue|rvalue}2 ref-qualifier">;
def err_member_function_call_bad_type : Error<
"cannot initialize object parameter of type %0 with an expression "
"of type %1">;
def warn_call_to_pure_virtual_member_function_from_ctor_dtor : Warning<
"call to pure virtual member function %0 has undefined behavior; "
"overrides of %0 in subclasses are not available in the "
@ -1815,10 +1823,6 @@ def warn_temporary_array_to_pointer_decay : Warning<
def err_init_list_bad_dest_type : Error<
"%select{|non-aggregate }0type %1 cannot be initialized with an initializer "
"list">;
def err_member_function_call_bad_cvr : Error<"member function %0 not viable: "
"'this' argument has type %1, but function is not marked "
"%select{const|restrict|const or restrict|volatile|const or volatile|"
"volatile or restrict|const, volatile, or restrict}2">;
def err_reference_bind_to_bitfield : Error<
"%select{non-const|volatile}0 reference cannot bind to "
@ -5942,15 +5946,15 @@ def note_typecheck_assign_const : Note<
def warn_unsigned_always_true_comparison : Warning<
"result of comparison of %select{%3|unsigned expression}0 %2 "
"%select{unsigned expression|%3}0 is always %4">,
InGroup<TautologicalUnsignedZeroCompare>;
InGroup<TautologicalUnsignedZeroCompare>, DefaultIgnore;
def warn_unsigned_enum_always_true_comparison : Warning<
"result of comparison of %select{%3|unsigned enum expression}0 %2 "
"%select{unsigned enum expression|%3}0 is always %4">,
InGroup<TautologicalUnsignedEnumZeroCompare>;
InGroup<TautologicalUnsignedEnumZeroCompare>, DefaultIgnore;
def warn_tautological_constant_compare : Warning<
"result of comparison %select{%3|%1}0 %2 "
"%select{%1|%3}0 is always %4">,
InGroup<TautologicalConstantCompare>;
InGroup<TautologicalTypeLimitCompare>, DefaultIgnore;
def warn_mixed_sign_comparison : Warning<
"comparison of integers of different signs: %0 and %1">,

View File

@ -194,6 +194,7 @@ LANGOPT(NativeHalfArgsAndReturns, 1, 0, "Native half args and returns")
LANGOPT(HalfArgsAndReturns, 1, 0, "half args and returns")
LANGOPT(CUDA , 1, 0, "CUDA")
LANGOPT(OpenMP , 32, 0, "OpenMP support and version of OpenMP (31, 40 or 45)")
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(RenderScript , 1, 0, "RenderScript")

View File

@ -35,6 +35,10 @@
/* Directories clang will search for headers */
#define C_INCLUDE_DIRS "${C_INCLUDE_DIRS}"
/* Directories clang will search for configuration files */
#cmakedefine CLANG_CONFIG_FILE_SYSTEM_DIR "${CLANG_CONFIG_FILE_SYSTEM_DIR}"
#cmakedefine CLANG_CONFIG_FILE_USER_DIR "${CLANG_CONFIG_FILE_USER_DIR}"
/* Default <path> to all compiler invocations for --sysroot=<path>. */
#define DEFAULT_SYSROOT "${DEFAULT_SYSROOT}"

View File

@ -19,6 +19,8 @@
#include "clang/Driver/Util.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/StringSaver.h"
#include <list>
#include <map>
@ -26,14 +28,6 @@
namespace llvm {
class Triple;
namespace opt {
class Arg;
class ArgList;
class DerivedArgList;
class InputArgList;
class OptTable;
}
}
namespace clang {
@ -138,6 +132,12 @@ class Driver {
/// The path to the compiler resource directory.
std::string ResourceDir;
/// System directory for config files.
std::string SystemConfigDir;
/// User directory for config files.
std::string UserConfigDir;
/// A prefix directory used to emulate a limited subset of GCC's '-Bprefix'
/// functionality.
/// FIXME: This type of customization should be removed in favor of the
@ -208,6 +208,21 @@ class Driver {
/// Name to use when invoking gcc/g++.
std::string CCCGenericGCCName;
/// Name of configuration file if used.
std::string ConfigFile;
/// Allocator for string saver.
llvm::BumpPtrAllocator Alloc;
/// Object that stores strings read from configuration file.
llvm::StringSaver Saver;
/// Arguments originated from configuration file.
std::unique_ptr<llvm::opt::InputArgList> CfgOptions;
/// Arguments originated from command line.
std::unique_ptr<llvm::opt::InputArgList> CLOptions;
/// Whether to check that input files exist when constructing compilation
/// jobs.
unsigned CheckInputsExist : 1;
@ -277,6 +292,8 @@ class Driver {
/// Name to use when invoking gcc/g++.
const std::string &getCCCGenericGCCName() const { return CCCGenericGCCName; }
const std::string &getConfigFile() const { return ConfigFile; }
const llvm::opt::OptTable &getOpts() const { return *Opts; }
const DiagnosticsEngine &getDiags() const { return Diags; }
@ -493,6 +510,18 @@ class Driver {
LTOKind getLTOMode() const { return LTOMode; }
private:
/// Tries to load options from configuration file.
///
/// \returns true if error occurred.
bool loadConfigFile();
/// Read options from the specified file.
///
/// \param [in] FileName File to read.
/// \returns true, if error occurred while reading.
bool readConfigFile(StringRef FileName);
/// Set the driver mode (cl, gcc, etc) from an option string of the form
/// --driver-mode=<mode>.
void setDriverModeFromOption(StringRef Opt);

View File

@ -519,6 +519,12 @@ def cl_fp32_correctly_rounded_divide_sqrt : Flag<["-"], "cl-fp32-correctly-round
def client__name : JoinedOrSeparate<["-"], "client_name">;
def combine : Flag<["-", "--"], "combine">, Flags<[DriverOption, Unsupported]>;
def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">;
def config : Separate<["--"], "config">, Flags<[DriverOption]>,
HelpText<"Specifies configuration file">;
def config_system_dir_EQ : Joined<["--"], "config-system-dir=">, Flags<[DriverOption, HelpHidden]>,
HelpText<"System directory for configuration files">;
def config_user_dir_EQ : Joined<["--"], "config-user-dir=">, Flags<[DriverOption, HelpHidden]>,
HelpText<"User directory for configuration files">;
def coverage : Flag<["-", "--"], "coverage">, Flags<[CoreOption]>;
def cpp_precomp : Flag<["-"], "cpp-precomp">, Group<clang_ignored_f_Group>;
def current__version : JoinedOrSeparate<["-"], "current_version">;
@ -1375,6 +1381,10 @@ def fopenmp_relocatable_target : Flag<["-"], "fopenmp-relocatable-target">, Grou
HelpText<"OpenMP target code is compiled as relocatable using the -c flag. For OpenMP targets the code is relocatable by default.">;
def fnoopenmp_relocatable_target : Flag<["-"], "fnoopenmp-relocatable-target">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
HelpText<"Do not compile OpenMP target code as relocatable.">;
def fopenmp_simd : Flag<["-"], "fopenmp-simd">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
HelpText<"Emit OpenMP code only for SIMD-based constructs.">;
def fno_openmp_simd : Flag<["-"], "fno-openmp-simd">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
HelpText<"Disable OpenMP code for SIMD-based constructs.">;
def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;

View File

@ -1447,7 +1447,7 @@ class Parser : public CodeCompletionHandler {
bool isTokIdentifier_in() const;
ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, Declarator::TheContext Ctx,
ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, DeclaratorContext Ctx,
ParsedAttributes *ParamAttrs);
void ParseObjCMethodRequirement();
Decl *ParseObjCMethodPrototype(
@ -1856,7 +1856,7 @@ class Parser : public CodeCompletionHandler {
/// A context for parsing declaration specifiers. TODO: flesh this
/// out, there are other significant restrictions on specifiers than
/// would be best implemented in the parser.
enum DeclSpecContext {
enum class DeclSpecContext {
DSC_normal, // normal context
DSC_class, // class context, enables 'friend'
DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
@ -1873,18 +1873,18 @@ class Parser : public CodeCompletionHandler {
/// trailing-type-specifier)?
static bool isTypeSpecifier(DeclSpecContext DSC) {
switch (DSC) {
case DSC_normal:
case DSC_template_param:
case DSC_class:
case DSC_top_level:
case DSC_objc_method_result:
case DSC_condition:
case DeclSpecContext::DSC_normal:
case DeclSpecContext::DSC_template_param:
case DeclSpecContext::DSC_class:
case DeclSpecContext::DSC_top_level:
case DeclSpecContext::DSC_objc_method_result:
case DeclSpecContext::DSC_condition:
return false;
case DSC_template_type_arg:
case DSC_type_specifier:
case DSC_trailing:
case DSC_alias_declaration:
case DeclSpecContext::DSC_template_type_arg:
case DeclSpecContext::DSC_type_specifier:
case DeclSpecContext::DSC_trailing:
case DeclSpecContext::DSC_alias_declaration:
return true;
}
llvm_unreachable("Missing DeclSpecContext case");
@ -1894,18 +1894,18 @@ class Parser : public CodeCompletionHandler {
/// deduction?
static bool isClassTemplateDeductionContext(DeclSpecContext DSC) {
switch (DSC) {
case DSC_normal:
case DSC_template_param:
case DSC_class:
case DSC_top_level:
case DSC_condition:
case DSC_type_specifier:
case DeclSpecContext::DSC_normal:
case DeclSpecContext::DSC_template_param:
case DeclSpecContext::DSC_class:
case DeclSpecContext::DSC_top_level:
case DeclSpecContext::DSC_condition:
case DeclSpecContext::DSC_type_specifier:
return true;
case DSC_objc_method_result:
case DSC_template_type_arg:
case DSC_trailing:
case DSC_alias_declaration:
case DeclSpecContext::DSC_objc_method_result:
case DeclSpecContext::DSC_template_type_arg:
case DeclSpecContext::DSC_trailing:
case DeclSpecContext::DSC_alias_declaration:
return false;
}
llvm_unreachable("Missing DeclSpecContext case");
@ -1920,15 +1920,16 @@ class Parser : public CodeCompletionHandler {
bool ParsedForRangeDecl() { return !ColonLoc.isInvalid(); }
};
DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd,
DeclGroupPtrTy ParseDeclaration(DeclaratorContext Context,
SourceLocation &DeclEnd,
ParsedAttributesWithRange &attrs);
DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
DeclGroupPtrTy ParseSimpleDeclaration(DeclaratorContext Context,
SourceLocation &DeclEnd,
ParsedAttributesWithRange &attrs,
bool RequireSemi,
ForRangeInit *FRI = nullptr);
bool MightBeDeclarator(unsigned Context);
DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
bool MightBeDeclarator(DeclaratorContext Context);
DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, DeclaratorContext Context,
SourceLocation *DeclEnd = nullptr,
ForRangeInit *FRI = nullptr);
Decl *ParseDeclarationAfterDeclarator(Declarator &D,
@ -1951,21 +1952,24 @@ class Parser : public CodeCompletionHandler {
const ParsedTemplateInfo &TemplateInfo,
AccessSpecifier AS, DeclSpecContext DSC,
ParsedAttributesWithRange &Attrs);
DeclSpecContext getDeclSpecContextFromDeclaratorContext(unsigned Context);
void ParseDeclarationSpecifiers(DeclSpec &DS,
DeclSpecContext
getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context);
void ParseDeclarationSpecifiers(
DeclSpec &DS,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
AccessSpecifier AS = AS_none,
DeclSpecContext DSC = DSC_normal,
DeclSpecContext DSC = DeclSpecContext::DSC_normal,
LateParsedAttrList *LateAttrs = nullptr);
bool DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
DeclSpecContext DSContext,
bool DiagnoseMissingSemiAfterTagDefinition(
DeclSpec &DS, AccessSpecifier AS, DeclSpecContext DSContext,
LateParsedAttrList *LateAttrs = nullptr);
void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none,
DeclSpecContext DSC = DSC_normal);
void ParseSpecifierQualifierList(
DeclSpec &DS, AccessSpecifier AS = AS_none,
DeclSpecContext DSC = DeclSpecContext::DSC_normal);
void ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
Declarator::TheContext Context);
DeclaratorContext Context);
void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
const ParsedTemplateInfo &TemplateInfo,
@ -2161,8 +2165,8 @@ class Parser : public CodeCompletionHandler {
public:
TypeResult ParseTypeName(SourceRange *Range = nullptr,
Declarator::TheContext Context
= Declarator::TypeNameContext,
DeclaratorContext Context
= DeclaratorContext::TypeNameContext,
AccessSpecifier AS = AS_none,
Decl **OwnedType = nullptr,
ParsedAttributes *Attrs = nullptr);
@ -2512,7 +2516,8 @@ class Parser : public CodeCompletionHandler {
void DiagnoseUnexpectedNamespace(NamedDecl *Context);
DeclGroupPtrTy ParseNamespace(unsigned Context, SourceLocation &DeclEnd,
DeclGroupPtrTy ParseNamespace(DeclaratorContext Context,
SourceLocation &DeclEnd,
SourceLocation InlineLoc = SourceLocation());
void ParseInnerNamespace(std::vector<SourceLocation> &IdentLoc,
std::vector<IdentifierInfo *> &Ident,
@ -2520,12 +2525,12 @@ class Parser : public CodeCompletionHandler {
unsigned int index, SourceLocation &InlineLoc,
ParsedAttributes &attrs,
BalancedDelimiterTracker &Tracker);
Decl *ParseLinkage(ParsingDeclSpec &DS, unsigned Context);
Decl *ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context);
Decl *ParseExportDeclaration();
DeclGroupPtrTy ParseUsingDirectiveOrDeclaration(
unsigned Context, const ParsedTemplateInfo &TemplateInfo,
DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
SourceLocation &DeclEnd, ParsedAttributesWithRange &attrs);
Decl *ParseUsingDirective(unsigned Context,
Decl *ParseUsingDirective(DeclaratorContext Context,
SourceLocation UsingLoc,
SourceLocation &DeclEnd,
ParsedAttributes &attrs);
@ -2544,8 +2549,8 @@ class Parser : public CodeCompletionHandler {
}
};
bool ParseUsingDeclarator(unsigned Context, UsingDeclarator &D);
DeclGroupPtrTy ParseUsingDeclaration(unsigned Context,
bool ParseUsingDeclarator(DeclaratorContext Context, UsingDeclarator &D);
DeclGroupPtrTy ParseUsingDeclaration(DeclaratorContext Context,
const ParsedTemplateInfo &TemplateInfo,
SourceLocation UsingLoc,
SourceLocation &DeclEnd,
@ -2729,16 +2734,16 @@ class Parser : public CodeCompletionHandler {
// C++ 14: Templates [temp]
// C++ 14.1: Template Parameters [temp.param]
Decl *ParseDeclarationStartingWithTemplate(unsigned Context,
Decl *ParseDeclarationStartingWithTemplate(DeclaratorContext Context,
SourceLocation &DeclEnd,
AccessSpecifier AS = AS_none,
AttributeList *AccessAttrs = nullptr);
Decl *ParseTemplateDeclarationOrSpecialization(unsigned Context,
Decl *ParseTemplateDeclarationOrSpecialization(DeclaratorContext Context,
SourceLocation &DeclEnd,
AccessSpecifier AS,
AttributeList *AccessAttrs);
Decl *ParseSingleDeclarationAfterTemplate(
unsigned Context,
DeclaratorContext Context,
const ParsedTemplateInfo &TemplateInfo,
ParsingDeclRAIIObject &DiagsFromParams,
SourceLocation &DeclEnd,
@ -2782,7 +2787,7 @@ class Parser : public CodeCompletionHandler {
bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
ParsedTemplateArgument ParseTemplateTemplateArgument();
ParsedTemplateArgument ParseTemplateArgument();
Decl *ParseExplicitInstantiation(unsigned Context,
Decl *ParseExplicitInstantiation(DeclaratorContext Context,
SourceLocation ExternLoc,
SourceLocation TemplateLoc,
SourceLocation &DeclEnd,

View File

@ -202,7 +202,7 @@ namespace clang {
ParsingDeclRAIIObject ParsingRAII;
public:
ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS, TheContext C)
ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS, DeclaratorContext C)
: Declarator(DS, C), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {
}

View File

@ -882,15 +882,8 @@ class ObjCDeclSpec {
};
/// \brief Represents a C++ unqualified-id that has been parsed.
class UnqualifiedId {
private:
UnqualifiedId(const UnqualifiedId &Other) = delete;
const UnqualifiedId &operator=(const UnqualifiedId &) = delete;
public:
/// \brief Describes the kind of unqualified-id parsed.
enum IdKind {
enum class UnqualifiedIdKind {
/// \brief An identifier.
IK_Identifier,
/// \brief An overloaded operator name, e.g., operator+.
@ -911,7 +904,17 @@ class UnqualifiedId {
IK_ImplicitSelfParam,
/// \brief A deduction-guide name (a template-name)
IK_DeductionGuideName
} Kind;
};
/// \brief Represents a C++ unqualified-id that has been parsed.
class UnqualifiedId {
private:
UnqualifiedId(const UnqualifiedId &Other) = delete;
const UnqualifiedId &operator=(const UnqualifiedId &) = delete;
public:
/// \brief Describes the kind of unqualified-id parsed.
UnqualifiedIdKind Kind;
struct OFI {
/// \brief The kind of overloaded operator.
@ -967,12 +970,13 @@ class UnqualifiedId {
/// \brief The location of the last token that describes this unqualified-id.
SourceLocation EndLocation;
UnqualifiedId() : Kind(IK_Identifier), Identifier(nullptr) { }
UnqualifiedId()
: Kind(UnqualifiedIdKind::IK_Identifier), Identifier(nullptr) {}
/// \brief Clear out this unqualified-id, setting it to default (invalid)
/// state.
void clear() {
Kind = IK_Identifier;
Kind = UnqualifiedIdKind::IK_Identifier;
Identifier = nullptr;
StartLocation = SourceLocation();
EndLocation = SourceLocation();
@ -985,15 +989,15 @@ class UnqualifiedId {
bool isInvalid() const { return !isValid(); }
/// \brief Determine what kind of name we have.
IdKind getKind() const { return Kind; }
void setKind(IdKind kind) { Kind = kind; }
UnqualifiedIdKind getKind() const { return Kind; }
void setKind(UnqualifiedIdKind kind) { Kind = kind; }
/// \brief Specify that this unqualified-id was parsed as an identifier.
///
/// \param Id the parsed identifier.
/// \param IdLoc the location of the parsed identifier.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc) {
Kind = IK_Identifier;
Kind = UnqualifiedIdKind::IK_Identifier;
Identifier = const_cast<IdentifierInfo *>(Id);
StartLocation = EndLocation = IdLoc;
}
@ -1022,7 +1026,7 @@ class UnqualifiedId {
void setConversionFunctionId(SourceLocation OperatorLoc,
ParsedType Ty,
SourceLocation EndLoc) {
Kind = IK_ConversionFunctionId;
Kind = UnqualifiedIdKind::IK_ConversionFunctionId;
StartLocation = OperatorLoc;
EndLocation = EndLoc;
ConversionFunctionId = Ty;
@ -1038,7 +1042,7 @@ class UnqualifiedId {
/// \param IdLoc the location of the identifier.
void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc,
SourceLocation IdLoc) {
Kind = IK_LiteralOperatorId;
Kind = UnqualifiedIdKind::IK_LiteralOperatorId;
Identifier = const_cast<IdentifierInfo *>(Id);
StartLocation = OpLoc;
EndLocation = IdLoc;
@ -1054,7 +1058,7 @@ class UnqualifiedId {
void setConstructorName(ParsedType ClassType,
SourceLocation ClassNameLoc,
SourceLocation EndLoc) {
Kind = IK_ConstructorName;
Kind = UnqualifiedIdKind::IK_ConstructorName;
StartLocation = ClassNameLoc;
EndLocation = EndLoc;
ConstructorName = ClassType;
@ -1077,7 +1081,7 @@ class UnqualifiedId {
void setDestructorName(SourceLocation TildeLoc,
ParsedType ClassType,
SourceLocation EndLoc) {
Kind = IK_DestructorName;
Kind = UnqualifiedIdKind::IK_DestructorName;
StartLocation = TildeLoc;
EndLocation = EndLoc;
DestructorName = ClassType;
@ -1097,7 +1101,7 @@ class UnqualifiedId {
/// \param TemplateLoc The location of the parsed template-name.
void setDeductionGuideName(ParsedTemplateTy Template,
SourceLocation TemplateLoc) {
Kind = IK_DeductionGuideName;
Kind = UnqualifiedIdKind::IK_DeductionGuideName;
TemplateName = Template;
StartLocation = EndLocation = TemplateLoc;
}
@ -1705,21 +1709,7 @@ enum FunctionDefinitionKind {
FDK_Deleted
};
/// \brief Information about one declarator, including the parsed type
/// information and the identifier.
///
/// When the declarator is fully formed, this is turned into the appropriate
/// Decl object.
///
/// Declarators come in two types: normal declarators and abstract declarators.
/// Abstract declarators are used when parsing types, and don't have an
/// identifier. Normal declarators do have ID's.
///
/// Instances of this class should be a transient object that lives on the
/// stack, not objects that are allocated in large quantities on the heap.
class Declarator {
public:
enum TheContext {
enum class DeclaratorContext {
FileContext, // File scope declaration.
PrototypeContext, // Within a function prototype.
ObjCResultContext, // An ObjC method result type.
@ -1746,6 +1736,21 @@ class Declarator {
AliasTemplateContext // C++11 alias-declaration template.
};
/// \brief Information about one declarator, including the parsed type
/// information and the identifier.
///
/// When the declarator is fully formed, this is turned into the appropriate
/// Decl object.
///
/// Declarators come in two types: normal declarators and abstract declarators.
/// Abstract declarators are used when parsing types, and don't have an
/// identifier. Normal declarators do have ID's.
///
/// Instances of this class should be a transient object that lives on the
/// stack, not objects that are allocated in large quantities on the heap.
class Declarator {
private:
const DeclSpec &DS;
CXXScopeSpec SS;
@ -1753,7 +1758,7 @@ class Declarator {
SourceRange Range;
/// \brief Where we are parsing this declarator.
TheContext Context;
DeclaratorContext Context;
/// The C++17 structured binding, if any. This is an alternative to a Name.
DecompositionDeclarator BindingGroup;
@ -1820,7 +1825,7 @@ class Declarator {
friend struct DeclaratorChunk;
public:
Declarator(const DeclSpec &ds, TheContext C)
Declarator(const DeclSpec &ds, DeclaratorContext C)
: DS(ds), Range(ds.getSourceRange()), Context(C),
InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
GroupingParens(false), FunctionDefinition(FDK_Declaration),
@ -1858,13 +1863,13 @@ class Declarator {
return BindingGroup;
}
TheContext getContext() const { return Context; }
DeclaratorContext getContext() const { return Context; }
bool isPrototypeContext() const {
return (Context == PrototypeContext ||
Context == ObjCParameterContext ||
Context == ObjCResultContext ||
Context == LambdaExprParameterContext);
return (Context == DeclaratorContext::PrototypeContext ||
Context == DeclaratorContext::ObjCParameterContext ||
Context == DeclaratorContext::ObjCResultContext ||
Context == DeclaratorContext::LambdaExprParameterContext);
}
/// \brief Get the source range that spans this declarator.
@ -1919,32 +1924,32 @@ class Declarator {
/// parameter lists.
bool mayOmitIdentifier() const {
switch (Context) {
case FileContext:
case KNRTypeListContext:
case MemberContext:
case BlockContext:
case ForContext:
case InitStmtContext:
case ConditionContext:
case DeclaratorContext::FileContext:
case DeclaratorContext::KNRTypeListContext:
case DeclaratorContext::MemberContext:
case DeclaratorContext::BlockContext:
case DeclaratorContext::ForContext:
case DeclaratorContext::InitStmtContext:
case DeclaratorContext::ConditionContext:
return false;
case TypeNameContext:
case FunctionalCastContext:
case AliasDeclContext:
case AliasTemplateContext:
case PrototypeContext:
case LambdaExprParameterContext:
case ObjCParameterContext:
case ObjCResultContext:
case TemplateParamContext:
case CXXNewContext:
case CXXCatchContext:
case ObjCCatchContext:
case BlockLiteralContext:
case LambdaExprContext:
case ConversionIdContext:
case TemplateTypeArgContext:
case TrailingReturnContext:
case DeclaratorContext::TypeNameContext:
case DeclaratorContext::FunctionalCastContext:
case DeclaratorContext::AliasDeclContext:
case DeclaratorContext::AliasTemplateContext:
case DeclaratorContext::PrototypeContext:
case DeclaratorContext::LambdaExprParameterContext:
case DeclaratorContext::ObjCParameterContext:
case DeclaratorContext::ObjCResultContext:
case DeclaratorContext::TemplateParamContext:
case DeclaratorContext::CXXNewContext:
case DeclaratorContext::CXXCatchContext:
case DeclaratorContext::ObjCCatchContext:
case DeclaratorContext::BlockLiteralContext:
case DeclaratorContext::LambdaExprContext:
case DeclaratorContext::ConversionIdContext:
case DeclaratorContext::TemplateTypeArgContext:
case DeclaratorContext::TrailingReturnContext:
return true;
}
llvm_unreachable("unknown context kind!");
@ -1955,32 +1960,32 @@ class Declarator {
/// typenames.
bool mayHaveIdentifier() const {
switch (Context) {
case FileContext:
case KNRTypeListContext:
case MemberContext:
case BlockContext:
case ForContext:
case InitStmtContext:
case ConditionContext:
case PrototypeContext:
case LambdaExprParameterContext:
case TemplateParamContext:
case CXXCatchContext:
case ObjCCatchContext:
case DeclaratorContext::FileContext:
case DeclaratorContext::KNRTypeListContext:
case DeclaratorContext::MemberContext:
case DeclaratorContext::BlockContext:
case DeclaratorContext::ForContext:
case DeclaratorContext::InitStmtContext:
case DeclaratorContext::ConditionContext:
case DeclaratorContext::PrototypeContext:
case DeclaratorContext::LambdaExprParameterContext:
case DeclaratorContext::TemplateParamContext:
case DeclaratorContext::CXXCatchContext:
case DeclaratorContext::ObjCCatchContext:
return true;
case TypeNameContext:
case FunctionalCastContext:
case CXXNewContext:
case AliasDeclContext:
case AliasTemplateContext:
case ObjCParameterContext:
case ObjCResultContext:
case BlockLiteralContext:
case LambdaExprContext:
case ConversionIdContext:
case TemplateTypeArgContext:
case TrailingReturnContext:
case DeclaratorContext::TypeNameContext:
case DeclaratorContext::FunctionalCastContext:
case DeclaratorContext::CXXNewContext:
case DeclaratorContext::AliasDeclContext:
case DeclaratorContext::AliasTemplateContext:
case DeclaratorContext::ObjCParameterContext:
case DeclaratorContext::ObjCResultContext:
case DeclaratorContext::BlockLiteralContext:
case DeclaratorContext::LambdaExprContext:
case DeclaratorContext::ConversionIdContext:
case DeclaratorContext::TemplateTypeArgContext:
case DeclaratorContext::TrailingReturnContext:
return false;
}
llvm_unreachable("unknown context kind!");
@ -1989,38 +1994,38 @@ class Declarator {
/// Return true if the context permits a C++17 decomposition declarator.
bool mayHaveDecompositionDeclarator() const {
switch (Context) {
case FileContext:
case DeclaratorContext::FileContext:
// FIXME: It's not clear that the proposal meant to allow file-scope
// structured bindings, but it does.
case BlockContext:
case ForContext:
case InitStmtContext:
case ConditionContext:
case DeclaratorContext::BlockContext:
case DeclaratorContext::ForContext:
case DeclaratorContext::InitStmtContext:
case DeclaratorContext::ConditionContext:
return true;
case MemberContext:
case PrototypeContext:
case TemplateParamContext:
case DeclaratorContext::MemberContext:
case DeclaratorContext::PrototypeContext:
case DeclaratorContext::TemplateParamContext:
// Maybe one day...
return false;
// These contexts don't allow any kind of non-abstract declarator.
case KNRTypeListContext:
case TypeNameContext:
case FunctionalCastContext:
case AliasDeclContext:
case AliasTemplateContext:
case LambdaExprParameterContext:
case ObjCParameterContext:
case ObjCResultContext:
case CXXNewContext:
case CXXCatchContext:
case ObjCCatchContext:
case BlockLiteralContext:
case LambdaExprContext:
case ConversionIdContext:
case TemplateTypeArgContext:
case TrailingReturnContext:
case DeclaratorContext::KNRTypeListContext:
case DeclaratorContext::TypeNameContext:
case DeclaratorContext::FunctionalCastContext:
case DeclaratorContext::AliasDeclContext:
case DeclaratorContext::AliasTemplateContext:
case DeclaratorContext::LambdaExprParameterContext:
case DeclaratorContext::ObjCParameterContext:
case DeclaratorContext::ObjCResultContext:
case DeclaratorContext::CXXNewContext:
case DeclaratorContext::CXXCatchContext:
case DeclaratorContext::ObjCCatchContext:
case DeclaratorContext::BlockLiteralContext:
case DeclaratorContext::LambdaExprContext:
case DeclaratorContext::ConversionIdContext:
case DeclaratorContext::TemplateTypeArgContext:
case DeclaratorContext::TrailingReturnContext:
return false;
}
llvm_unreachable("unknown context kind!");
@ -2035,45 +2040,45 @@ class Declarator {
return false;
if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern &&
Context != FileContext)
Context != DeclaratorContext::FileContext)
return false;
// Special names can't have direct initializers.
if (Name.getKind() != UnqualifiedId::IK_Identifier)
if (Name.getKind() != UnqualifiedIdKind::IK_Identifier)
return false;
switch (Context) {
case FileContext:
case BlockContext:
case ForContext:
case InitStmtContext:
case DeclaratorContext::FileContext:
case DeclaratorContext::BlockContext:
case DeclaratorContext::ForContext:
case DeclaratorContext::InitStmtContext:
return true;
case ConditionContext:
case DeclaratorContext::ConditionContext:
// This may not be followed by a direct initializer, but it can't be a
// function declaration either, and we'd prefer to perform a tentative
// parse in order to produce the right diagnostic.
return true;
case KNRTypeListContext:
case MemberContext:
case PrototypeContext:
case LambdaExprParameterContext:
case ObjCParameterContext:
case ObjCResultContext:
case TemplateParamContext:
case CXXCatchContext:
case ObjCCatchContext:
case TypeNameContext:
case FunctionalCastContext: // FIXME
case CXXNewContext:
case AliasDeclContext:
case AliasTemplateContext:
case BlockLiteralContext:
case LambdaExprContext:
case ConversionIdContext:
case TemplateTypeArgContext:
case TrailingReturnContext:
case DeclaratorContext::KNRTypeListContext:
case DeclaratorContext::MemberContext:
case DeclaratorContext::PrototypeContext:
case DeclaratorContext::LambdaExprParameterContext:
case DeclaratorContext::ObjCParameterContext:
case DeclaratorContext::ObjCResultContext:
case DeclaratorContext::TemplateParamContext:
case DeclaratorContext::CXXCatchContext:
case DeclaratorContext::ObjCCatchContext:
case DeclaratorContext::TypeNameContext:
case DeclaratorContext::FunctionalCastContext: // FIXME
case DeclaratorContext::CXXNewContext:
case DeclaratorContext::AliasDeclContext:
case DeclaratorContext::AliasTemplateContext:
case DeclaratorContext::BlockLiteralContext:
case DeclaratorContext::LambdaExprContext:
case DeclaratorContext::ConversionIdContext:
case DeclaratorContext::TemplateTypeArgContext:
case DeclaratorContext::TrailingReturnContext:
return false;
}
llvm_unreachable("unknown context kind!");
@ -2089,8 +2094,8 @@ class Declarator {
/// special C++ name (constructor, destructor, etc.), or a structured
/// binding (which is not exactly a name, but occupies the same position).
bool hasName() const {
return Name.getKind() != UnqualifiedId::IK_Identifier || Name.Identifier ||
isDecompositionDeclarator();
return Name.getKind() != UnqualifiedIdKind::IK_Identifier ||
Name.Identifier || isDecompositionDeclarator();
}
/// Return whether this declarator is a decomposition declarator.
@ -2099,7 +2104,7 @@ class Declarator {
}
IdentifierInfo *getIdentifier() const {
if (Name.getKind() == UnqualifiedId::IK_Identifier)
if (Name.getKind() == UnqualifiedIdKind::IK_Identifier)
return Name.Identifier;
return nullptr;
@ -2257,32 +2262,32 @@ class Declarator {
return false;
switch (Context) {
case FileContext:
case MemberContext:
case BlockContext:
case ForContext:
case InitStmtContext:
case DeclaratorContext::FileContext:
case DeclaratorContext::MemberContext:
case DeclaratorContext::BlockContext:
case DeclaratorContext::ForContext:
case DeclaratorContext::InitStmtContext:
return true;
case ConditionContext:
case KNRTypeListContext:
case TypeNameContext:
case FunctionalCastContext:
case AliasDeclContext:
case AliasTemplateContext:
case PrototypeContext:
case LambdaExprParameterContext:
case ObjCParameterContext:
case ObjCResultContext:
case TemplateParamContext:
case CXXNewContext:
case CXXCatchContext:
case ObjCCatchContext:
case BlockLiteralContext:
case LambdaExprContext:
case ConversionIdContext:
case TemplateTypeArgContext:
case TrailingReturnContext:
case DeclaratorContext::ConditionContext:
case DeclaratorContext::KNRTypeListContext:
case DeclaratorContext::TypeNameContext:
case DeclaratorContext::FunctionalCastContext:
case DeclaratorContext::AliasDeclContext:
case DeclaratorContext::AliasTemplateContext:
case DeclaratorContext::PrototypeContext:
case DeclaratorContext::LambdaExprParameterContext:
case DeclaratorContext::ObjCParameterContext:
case DeclaratorContext::ObjCResultContext:
case DeclaratorContext::TemplateParamContext:
case DeclaratorContext::CXXNewContext:
case DeclaratorContext::CXXCatchContext:
case DeclaratorContext::ObjCCatchContext:
case DeclaratorContext::BlockLiteralContext:
case DeclaratorContext::LambdaExprContext:
case DeclaratorContext::ConversionIdContext:
case DeclaratorContext::TemplateTypeArgContext:
case DeclaratorContext::TrailingReturnContext:
return false;
}
llvm_unreachable("unknown context kind!");
@ -2292,32 +2297,35 @@ class Declarator {
/// expression could appear.
bool isExpressionContext() const {
switch (Context) {
case FileContext:
case KNRTypeListContext:
case MemberContext:
case TypeNameContext: // FIXME: sizeof(...) permits an expression.
case FunctionalCastContext:
case AliasDeclContext:
case AliasTemplateContext:
case PrototypeContext:
case LambdaExprParameterContext:
case ObjCParameterContext:
case ObjCResultContext:
case TemplateParamContext:
case CXXNewContext:
case CXXCatchContext:
case ObjCCatchContext:
case BlockLiteralContext:
case LambdaExprContext:
case ConversionIdContext:
case TrailingReturnContext:
case DeclaratorContext::FileContext:
case DeclaratorContext::KNRTypeListContext:
case DeclaratorContext::MemberContext:
// FIXME: sizeof(...) permits an expression.
case DeclaratorContext::TypeNameContext:
case DeclaratorContext::FunctionalCastContext:
case DeclaratorContext::AliasDeclContext:
case DeclaratorContext::AliasTemplateContext:
case DeclaratorContext::PrototypeContext:
case DeclaratorContext::LambdaExprParameterContext:
case DeclaratorContext::ObjCParameterContext:
case DeclaratorContext::ObjCResultContext:
case DeclaratorContext::TemplateParamContext:
case DeclaratorContext::CXXNewContext:
case DeclaratorContext::CXXCatchContext:
case DeclaratorContext::ObjCCatchContext:
case DeclaratorContext::BlockLiteralContext:
case DeclaratorContext::LambdaExprContext:
case DeclaratorContext::ConversionIdContext:
case DeclaratorContext::TrailingReturnContext:
return false;
case BlockContext:
case ForContext:
case InitStmtContext:
case ConditionContext:
case TemplateTypeArgContext:
case DeclaratorContext::BlockContext:
case DeclaratorContext::ForContext:
case DeclaratorContext::InitStmtContext:
case DeclaratorContext::ConditionContext:
case DeclaratorContext::TemplateTypeArgContext:
return true;
}
@ -2430,7 +2438,8 @@ class Declarator {
/// Returns true if this declares a real member and not a friend.
bool isFirstDeclarationOfMember() {
return getContext() == MemberContext && !getDeclSpec().isFriendSpecified();
return getContext() == DeclaratorContext::MemberContext &&
!getDeclSpec().isFriendSpecified();
}
/// Returns true if this declares a static member. This cannot be called on a
@ -2451,7 +2460,8 @@ struct FieldDeclarator {
Declarator D;
Expr *BitfieldSize;
explicit FieldDeclarator(const DeclSpec &DS)
: D(DS, Declarator::MemberContext), BitfieldSize(nullptr) { }
: D(DS, DeclaratorContext::MemberContext),
BitfieldSize(nullptr) {}
};
/// \brief Represents a C++11 virt-specifier-seq.

View File

@ -5547,6 +5547,11 @@ class Sema {
ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
sema::LambdaScopeInfo *LSI);
/// Get the return type to use for a lambda's conversion function(s) to
/// function pointer type, given the type of the call operator.
QualType
getLambdaConversionFunctionResultType(const FunctionProtoType *CallOpType);
/// \brief Define the "body" of the conversion from a lambda object to a
/// function pointer.
///
@ -7760,6 +7765,9 @@ class Sema {
void InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
FunctionDecl *Function);
FunctionDecl *InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD,
const TemplateArgumentList *Args,
SourceLocation Loc);
void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
FunctionDecl *Function,
bool Recursive = false,

View File

@ -779,7 +779,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
// unique-external linkage, it's not legally usable from outside
// this translation unit. However, we should use the C linkage
// rules instead for extern "C" declarations.
if (Context.getLangOpts().CPlusPlus && !Function->isInExternCContext()) {
if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Function)) {
// Only look at the type-as-written. Otherwise, deducing the return type
// of a function could change its linkage.
QualType TypeAsWritten = Function->getType();
@ -1165,7 +1165,7 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D,
LVComputationKind computation) {
if (const auto *Function = dyn_cast<FunctionDecl>(D)) {
if (Function->isInAnonymousNamespace() &&
!Function->isInExternCContext())
!isFirstInExternCContext(Function))
return getInternalLinkageFor(Function);
// This is a "void f();" which got merged with a file static.
@ -1188,7 +1188,7 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D,
if (const auto *Var = dyn_cast<VarDecl>(D)) {
if (Var->hasExternalStorage()) {
if (Var->isInAnonymousNamespace() && !Var->isInExternCContext())
if (Var->isInAnonymousNamespace() && !isFirstInExternCContext(Var))
return getInternalLinkageFor(Var);
LinkageInfo LV;

View File

@ -139,7 +139,6 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "avx512vnni", true);
setFeatureEnabledImpl(Features, "avx512vbmi2", true);
setFeatureEnabledImpl(Features, "avx512vpopcntdq", true);
setFeatureEnabledImpl(Features, "clwb", true);
LLVM_FALLTHROUGH;
case CK_Cannonlake:
setFeatureEnabledImpl(Features, "avx512ifma", true);
@ -152,10 +151,8 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "avx512dq", true);
setFeatureEnabledImpl(Features, "avx512bw", true);
setFeatureEnabledImpl(Features, "avx512vl", true);
if (Kind == CK_SkylakeServer) {
setFeatureEnabledImpl(Features, "pku", true);
setFeatureEnabledImpl(Features, "clwb", true);
}
LLVM_FALLTHROUGH;
case CK_SkylakeClient:
setFeatureEnabledImpl(Features, "xsavec", true);

View File

@ -36,7 +36,7 @@ std::string getClangRepositoryPath() {
// If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us
// pick up a tag in an SVN export, for example.
StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/trunk/lib/Basic/Version.cpp $");
StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/branches/release_60/lib/Basic/Version.cpp $");
if (URL.empty()) {
URL = SVNRepository.slice(SVNRepository.find(':'),
SVNRepository.find("/lib/Basic"));

View File

@ -173,10 +173,12 @@ void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
ConstantAddress DeclAddr(DeclPtr, getContext().getDeclAlign(&D));
if (!T->isReferenceType()) {
if (getLangOpts().OpenMP && D.hasAttr<OMPThreadPrivateDeclAttr>())
if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd &&
D.hasAttr<OMPThreadPrivateDeclAttr>()) {
(void)CGM.getOpenMPRuntime().emitThreadPrivateVarDefinition(
&D, DeclAddr, D.getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
PerformInit, this);
}
if (PerformInit)
EmitDeclInit(*this, D, DeclAddr);
if (CGM.isTypeConstant(D.getType(), true))

View File

@ -646,7 +646,7 @@ CodeGenFunction::getMSVCDispatchBlock(EHScopeStack::stable_iterator SI) {
return DispatchBlock;
if (EHS.getKind() == EHScope::Terminate)
DispatchBlock = getTerminateHandler();
DispatchBlock = getTerminateFunclet();
else
DispatchBlock = createBasicBlock();
CGBuilderTy Builder(*this, DispatchBlock);
@ -1334,24 +1334,15 @@ llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
if (TerminateHandler)
return TerminateHandler;
CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
// Set up the terminate handler. This block is inserted at the very
// end of the function by FinishFunction.
TerminateHandler = createBasicBlock("terminate.handler");
CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
Builder.SetInsertPoint(TerminateHandler);
llvm::Value *Exn = nullptr;
SaveAndRestore<llvm::Instruction *> RestoreCurrentFuncletPad(
CurrentFuncletPad);
if (EHPersonality::get(*this).usesFuncletPads()) {
llvm::Value *ParentPad = CurrentFuncletPad;
if (!ParentPad)
ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
CurrentFuncletPad = Builder.CreateCleanupPad(ParentPad);
} else {
if (getLangOpts().CPlusPlus)
Exn = getExceptionFromSlot();
}
llvm::CallInst *terminateCall =
CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
terminateCall->setDoesNotReturn();
@ -1363,6 +1354,42 @@ llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
return TerminateHandler;
}
llvm::BasicBlock *CodeGenFunction::getTerminateFunclet() {
assert(EHPersonality::get(*this).usesFuncletPads() &&
"use getTerminateLandingPad for non-funclet EH");
llvm::BasicBlock *&TerminateFunclet = TerminateFunclets[CurrentFuncletPad];
if (TerminateFunclet)
return TerminateFunclet;
CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
// Set up the terminate handler. This block is inserted at the very
// end of the function by FinishFunction.
TerminateFunclet = createBasicBlock("terminate.handler");
Builder.SetInsertPoint(TerminateFunclet);
// Create the cleanuppad using the current parent pad as its token. Use 'none'
// if this is a top-level terminate scope, which is the common case.
SaveAndRestore<llvm::Instruction *> RestoreCurrentFuncletPad(
CurrentFuncletPad);
llvm::Value *ParentPad = CurrentFuncletPad;
if (!ParentPad)
ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
CurrentFuncletPad = Builder.CreateCleanupPad(ParentPad);
// Emit the __std_terminate call.
llvm::CallInst *terminateCall =
CGM.getCXXABI().emitTerminateForUnexpectedException(*this, nullptr);
terminateCall->setDoesNotReturn();
Builder.CreateUnreachable();
// Restore the saved insertion state.
Builder.restoreIP(SavedIP);
return TerminateFunclet;
}
llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {
if (EHResumeBlock) return EHResumeBlock;

View File

@ -2263,9 +2263,11 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
Address Addr(V, Alignment);
// Emit reference to the private copy of the variable if it is an OpenMP
// threadprivate variable.
if (CGF.getLangOpts().OpenMP && VD->hasAttr<OMPThreadPrivateDeclAttr>())
if (CGF.getLangOpts().OpenMP && !CGF.getLangOpts().OpenMPSimd &&
VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
return EmitThreadPrivateVarDeclLValue(CGF, VD, T, Addr, RealVarTy,
E->getExprLoc());
}
LValue LV = VD->getType()->isReferenceType() ?
CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(),
AlignmentSource::Decl) :
@ -2446,7 +2448,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// Check for OpenMP threadprivate variables.
if (getLangOpts().OpenMP && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd &&
VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
return EmitThreadPrivateVarDeclLValue(
*this, VD, T, addr, getTypes().ConvertTypeForMem(VD->getType()),
E->getExprLoc());

View File

@ -397,6 +397,7 @@ class InlinedOpenMPRegionRAII {
CodeGenFunction &CGF;
llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
FieldDecl *LambdaThisCaptureField = nullptr;
const CodeGen::CGBlockInfo *BlockInfo = nullptr;
public:
/// \brief Constructs region for combined constructs.
@ -412,6 +413,8 @@ class InlinedOpenMPRegionRAII {
std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields);
LambdaThisCaptureField = CGF.LambdaThisCaptureField;
CGF.LambdaThisCaptureField = nullptr;
BlockInfo = CGF.BlockInfo;
CGF.BlockInfo = nullptr;
}
~InlinedOpenMPRegionRAII() {
@ -422,6 +425,7 @@ class InlinedOpenMPRegionRAII {
CGF.CapturedStmtInfo = OldCSI;
std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields);
CGF.LambdaThisCaptureField = LambdaThisCaptureField;
CGF.BlockInfo = BlockInfo;
}
};
@ -8014,3 +8018,299 @@ Address CGOpenMPRuntime::getParameterAddress(CodeGenFunction &CGF,
const VarDecl *TargetParam) const {
return CGF.GetAddrOfLocalVar(NativeParam);
}
llvm::Value *CGOpenMPSIMDRuntime::emitParallelOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
llvm_unreachable("Not supported in SIMD-only mode");
}
llvm::Value *CGOpenMPSIMDRuntime::emitTeamsOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
llvm_unreachable("Not supported in SIMD-only mode");
}
llvm::Value *CGOpenMPSIMDRuntime::emitTaskOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
const VarDecl *PartIDVar, const VarDecl *TaskTVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
bool Tied, unsigned &NumberOfParts) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitParallelCall(CodeGenFunction &CGF,
SourceLocation Loc,
llvm::Value *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars,
const Expr *IfCond) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitCriticalRegion(
CodeGenFunction &CGF, StringRef CriticalName,
const RegionCodeGenTy &CriticalOpGen, SourceLocation Loc,
const Expr *Hint) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitMasterRegion(CodeGenFunction &CGF,
const RegionCodeGenTy &MasterOpGen,
SourceLocation Loc) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
SourceLocation Loc) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitTaskgroupRegion(
CodeGenFunction &CGF, const RegionCodeGenTy &TaskgroupOpGen,
SourceLocation Loc) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitSingleRegion(
CodeGenFunction &CGF, const RegionCodeGenTy &SingleOpGen,
SourceLocation Loc, ArrayRef<const Expr *> CopyprivateVars,
ArrayRef<const Expr *> DestExprs, ArrayRef<const Expr *> SrcExprs,
ArrayRef<const Expr *> AssignmentOps) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitOrderedRegion(CodeGenFunction &CGF,
const RegionCodeGenTy &OrderedOpGen,
SourceLocation Loc,
bool IsThreads) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitBarrierCall(CodeGenFunction &CGF,
SourceLocation Loc,
OpenMPDirectiveKind Kind,
bool EmitChecks,
bool ForceSimpleCall) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitForDispatchInit(
CodeGenFunction &CGF, SourceLocation Loc,
const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned,
bool Ordered, const DispatchRTInput &DispatchValues) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitForStaticInit(
CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind,
const OpenMPScheduleTy &ScheduleKind, const StaticRTInput &Values) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitDistributeStaticInit(
CodeGenFunction &CGF, SourceLocation Loc,
OpenMPDistScheduleClauseKind SchedKind, const StaticRTInput &Values) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF,
SourceLocation Loc,
unsigned IVSize,
bool IVSigned) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitForStaticFinish(CodeGenFunction &CGF,
SourceLocation Loc,
OpenMPDirectiveKind DKind) {
llvm_unreachable("Not supported in SIMD-only mode");
}
llvm::Value *CGOpenMPSIMDRuntime::emitForNext(CodeGenFunction &CGF,
SourceLocation Loc,
unsigned IVSize, bool IVSigned,
Address IL, Address LB,
Address UB, Address ST) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitNumThreadsClause(CodeGenFunction &CGF,
llvm::Value *NumThreads,
SourceLocation Loc) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitProcBindClause(CodeGenFunction &CGF,
OpenMPProcBindClauseKind ProcBind,
SourceLocation Loc) {
llvm_unreachable("Not supported in SIMD-only mode");
}
Address CGOpenMPSIMDRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
const VarDecl *VD,
Address VDAddr,
SourceLocation Loc) {
llvm_unreachable("Not supported in SIMD-only mode");
}
llvm::Function *CGOpenMPSIMDRuntime::emitThreadPrivateVarDefinition(
const VarDecl *VD, Address VDAddr, SourceLocation Loc, bool PerformInit,
CodeGenFunction *CGF) {
llvm_unreachable("Not supported in SIMD-only mode");
}
Address CGOpenMPSIMDRuntime::getAddrOfArtificialThreadPrivate(
CodeGenFunction &CGF, QualType VarType, StringRef Name) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitFlush(CodeGenFunction &CGF,
ArrayRef<const Expr *> Vars,
SourceLocation Loc) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
const OMPExecutableDirective &D,
llvm::Value *TaskFunction,
QualType SharedsTy, Address Shareds,
const Expr *IfCond,
const OMPTaskDataTy &Data) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitTaskLoopCall(
CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds,
const Expr *IfCond, const OMPTaskDataTy &Data) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitReduction(
CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> Privates,
ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
ArrayRef<const Expr *> ReductionOps, ReductionOptionsTy Options) {
assert(Options.SimpleReduction && "Only simple reduction is expected.");
CGOpenMPRuntime::emitReduction(CGF, Loc, Privates, LHSExprs, RHSExprs,
ReductionOps, Options);
}
llvm::Value *CGOpenMPSIMDRuntime::emitTaskReductionInit(
CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> LHSExprs,
ArrayRef<const Expr *> RHSExprs, const OMPTaskDataTy &Data) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitTaskReductionFixups(CodeGenFunction &CGF,
SourceLocation Loc,
ReductionCodeGen &RCG,
unsigned N) {
llvm_unreachable("Not supported in SIMD-only mode");
}
Address CGOpenMPSIMDRuntime::getTaskReductionItem(CodeGenFunction &CGF,
SourceLocation Loc,
llvm::Value *ReductionsPtr,
LValue SharedLVal) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
SourceLocation Loc) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitCancellationPointCall(
CodeGenFunction &CGF, SourceLocation Loc,
OpenMPDirectiveKind CancelRegion) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitCancelCall(CodeGenFunction &CGF,
SourceLocation Loc, const Expr *IfCond,
OpenMPDirectiveKind CancelRegion) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitTargetOutlinedFunction(
const OMPExecutableDirective &D, StringRef ParentName,
llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitTargetCall(CodeGenFunction &CGF,
const OMPExecutableDirective &D,
llvm::Value *OutlinedFn,
llvm::Value *OutlinedFnID,
const Expr *IfCond, const Expr *Device,
ArrayRef<llvm::Value *> CapturedVars) {
llvm_unreachable("Not supported in SIMD-only mode");
}
bool CGOpenMPSIMDRuntime::emitTargetFunctions(GlobalDecl GD) {
llvm_unreachable("Not supported in SIMD-only mode");
}
bool CGOpenMPSIMDRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
llvm_unreachable("Not supported in SIMD-only mode");
}
bool CGOpenMPSIMDRuntime::emitTargetGlobal(GlobalDecl GD) {
return false;
}
llvm::Function *CGOpenMPSIMDRuntime::emitRegistrationFunction() {
return nullptr;
}
void CGOpenMPSIMDRuntime::emitTeamsCall(CodeGenFunction &CGF,
const OMPExecutableDirective &D,
SourceLocation Loc,
llvm::Value *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitNumTeamsClause(CodeGenFunction &CGF,
const Expr *NumTeams,
const Expr *ThreadLimit,
SourceLocation Loc) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitTargetDataCalls(
CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitTargetDataStandAloneCall(
CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
const Expr *Device) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitDoacrossInit(CodeGenFunction &CGF,
const OMPLoopDirective &D) {
llvm_unreachable("Not supported in SIMD-only mode");
}
void CGOpenMPSIMDRuntime::emitDoacrossOrdered(CodeGenFunction &CGF,
const OMPDependClause *C) {
llvm_unreachable("Not supported in SIMD-only mode");
}
const VarDecl *
CGOpenMPSIMDRuntime::translateParameter(const FieldDecl *FD,
const VarDecl *NativeParam) const {
llvm_unreachable("Not supported in SIMD-only mode");
}
Address
CGOpenMPSIMDRuntime::getParameterAddress(CodeGenFunction &CGF,
const VarDecl *NativeParam,
const VarDecl *TargetParam) const {
llvm_unreachable("Not supported in SIMD-only mode");
}

View File

@ -1364,6 +1364,571 @@ class CGOpenMPRuntime {
ArrayRef<llvm::Value *> Args = llvm::None) const;
};
/// Class supports emissionof SIMD-only code.
class CGOpenMPSIMDRuntime final : public CGOpenMPRuntime {
public:
explicit CGOpenMPSIMDRuntime(CodeGenModule &CGM) : CGOpenMPRuntime(CGM) {}
~CGOpenMPSIMDRuntime() override {}
/// \brief Emits outlined function for the specified OpenMP parallel directive
/// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
/// kmp_int32 BoundID, struct context_vars*).
/// \param D OpenMP directive.
/// \param ThreadIDVar Variable for thread id in the current OpenMP region.
/// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D directive.
llvm::Value *
emitParallelOutlinedFunction(const OMPExecutableDirective &D,
const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind,
const RegionCodeGenTy &CodeGen) override;
/// \brief Emits outlined function for the specified OpenMP teams directive
/// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
/// kmp_int32 BoundID, struct context_vars*).
/// \param D OpenMP directive.
/// \param ThreadIDVar Variable for thread id in the current OpenMP region.
/// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D directive.
llvm::Value *
emitTeamsOutlinedFunction(const OMPExecutableDirective &D,
const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind,
const RegionCodeGenTy &CodeGen) override;
/// \brief Emits outlined function for the OpenMP task directive \a D. This
/// outlined function has type void(*)(kmp_int32 ThreadID, struct task_t*
/// TaskT).
/// \param D OpenMP directive.
/// \param ThreadIDVar Variable for thread id in the current OpenMP region.
/// \param PartIDVar Variable for partition id in the current OpenMP untied
/// task region.
/// \param TaskTVar Variable for task_t argument.
/// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D directive.
/// \param Tied true if task is generated for tied task, false otherwise.
/// \param NumberOfParts Number of parts in untied task. Ignored for tied
/// tasks.
///
llvm::Value *emitTaskOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
const VarDecl *PartIDVar, const VarDecl *TaskTVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
bool Tied, unsigned &NumberOfParts) override;
/// \brief Emits code for parallel or serial call of the \a OutlinedFn with
/// variables captured in a record which address is stored in \a
/// CapturedStruct.
/// \param OutlinedFn Outlined function to be run in parallel threads. Type of
/// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
/// \param CapturedVars A pointer to the record with the references to
/// variables used in \a OutlinedFn function.
/// \param IfCond Condition in the associated 'if' clause, if it was
/// specified, nullptr otherwise.
///
void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
llvm::Value *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars,
const Expr *IfCond) override;
/// \brief Emits a critical region.
/// \param CriticalName Name of the critical region.
/// \param CriticalOpGen Generator for the statement associated with the given
/// critical region.
/// \param Hint Value of the 'hint' clause (optional).
void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName,
const RegionCodeGenTy &CriticalOpGen,
SourceLocation Loc,
const Expr *Hint = nullptr) override;
/// \brief Emits a master region.
/// \param MasterOpGen Generator for the statement associated with the given
/// master region.
void emitMasterRegion(CodeGenFunction &CGF,
const RegionCodeGenTy &MasterOpGen,
SourceLocation Loc) override;
/// \brief Emits code for a taskyield directive.
void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc) override;
/// \brief Emit a taskgroup region.
/// \param TaskgroupOpGen Generator for the statement associated with the
/// given taskgroup region.
void emitTaskgroupRegion(CodeGenFunction &CGF,
const RegionCodeGenTy &TaskgroupOpGen,
SourceLocation Loc) override;
/// \brief Emits a single region.
/// \param SingleOpGen Generator for the statement associated with the given
/// single region.
void emitSingleRegion(CodeGenFunction &CGF,
const RegionCodeGenTy &SingleOpGen, SourceLocation Loc,
ArrayRef<const Expr *> CopyprivateVars,
ArrayRef<const Expr *> DestExprs,
ArrayRef<const Expr *> SrcExprs,
ArrayRef<const Expr *> AssignmentOps) override;
/// \brief Emit an ordered region.
/// \param OrderedOpGen Generator for the statement associated with the given
/// ordered region.
void emitOrderedRegion(CodeGenFunction &CGF,
const RegionCodeGenTy &OrderedOpGen,
SourceLocation Loc, bool IsThreads) override;
/// \brief Emit an implicit/explicit barrier for OpenMP threads.
/// \param Kind Directive for which this implicit barrier call must be
/// generated. Must be OMPD_barrier for explicit barrier generation.
/// \param EmitChecks true if need to emit checks for cancellation barriers.
/// \param ForceSimpleCall true simple barrier call must be emitted, false if
/// runtime class decides which one to emit (simple or with cancellation
/// checks).
///
void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
OpenMPDirectiveKind Kind, bool EmitChecks = true,
bool ForceSimpleCall = false) override;
/// This is used for non static scheduled types and when the ordered
/// clause is present on the loop construct.
/// Depending on the loop schedule, it is necessary to call some runtime
/// routine before start of the OpenMP loop to get the loop upper / lower
/// bounds \a LB and \a UB and stride \a ST.
///
/// \param CGF Reference to current CodeGenFunction.
/// \param Loc Clang source location.
/// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
/// \param IVSize Size of the iteration variable in bits.
/// \param IVSigned Sign of the iteration variable.
/// \param Ordered true if loop is ordered, false otherwise.
/// \param DispatchValues struct containing llvm values for lower bound, upper
/// bound, and chunk expression.
/// For the default (nullptr) value, the chunk 1 will be used.
///
void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc,
const OpenMPScheduleTy &ScheduleKind,
unsigned IVSize, bool IVSigned, bool Ordered,
const DispatchRTInput &DispatchValues) override;
/// \brief Call the appropriate runtime routine to initialize it before start
/// of loop.
///
/// This is used only in case of static schedule, when the user did not
/// specify a ordered clause on the loop construct.
/// Depending on the loop schedule, it is necessary to call some runtime
/// routine before start of the OpenMP loop to get the loop upper / lower
/// bounds LB and UB and stride ST.
///
/// \param CGF Reference to current CodeGenFunction.
/// \param Loc Clang source location.
/// \param DKind Kind of the directive.
/// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
/// \param Values Input arguments for the construct.
///
void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc,
OpenMPDirectiveKind DKind,
const OpenMPScheduleTy &ScheduleKind,
const StaticRTInput &Values) override;
///
/// \param CGF Reference to current CodeGenFunction.
/// \param Loc Clang source location.
/// \param SchedKind Schedule kind, specified by the 'dist_schedule' clause.
/// \param Values Input arguments for the construct.
///
void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc,
OpenMPDistScheduleClauseKind SchedKind,
const StaticRTInput &Values) override;
/// \brief Call the appropriate runtime routine to notify that we finished
/// iteration of the ordered loop with the dynamic scheduling.
///
/// \param CGF Reference to current CodeGenFunction.
/// \param Loc Clang source location.
/// \param IVSize Size of the iteration variable in bits.
/// \param IVSigned Sign of the iteration variable.
///
void emitForOrderedIterationEnd(CodeGenFunction &CGF, SourceLocation Loc,
unsigned IVSize, bool IVSigned) override;
/// \brief Call the appropriate runtime routine to notify that we finished
/// all the work with current loop.
///
/// \param CGF Reference to current CodeGenFunction.
/// \param Loc Clang source location.
/// \param DKind Kind of the directive for which the static finish is emitted.
///
void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc,
OpenMPDirectiveKind DKind) override;
/// Call __kmpc_dispatch_next(
/// ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter,
/// kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
/// kmp_int[32|64] *p_stride);
/// \param IVSize Size of the iteration variable in bits.
/// \param IVSigned Sign of the iteration variable.
/// \param IL Address of the output variable in which the flag of the
/// last iteration is returned.
/// \param LB Address of the output variable in which the lower iteration
/// number is returned.
/// \param UB Address of the output variable in which the upper iteration
/// number is returned.
/// \param ST Address of the output variable in which the stride value is
/// returned.
llvm::Value *emitForNext(CodeGenFunction &CGF, SourceLocation Loc,
unsigned IVSize, bool IVSigned, Address IL,
Address LB, Address UB, Address ST) override;
/// \brief Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32
/// global_tid, kmp_int32 num_threads) to generate code for 'num_threads'
/// clause.
/// \param NumThreads An integer value of threads.
void emitNumThreadsClause(CodeGenFunction &CGF, llvm::Value *NumThreads,
SourceLocation Loc) override;
/// \brief Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32
/// global_tid, int proc_bind) to generate code for 'proc_bind' clause.
void emitProcBindClause(CodeGenFunction &CGF,
OpenMPProcBindClauseKind ProcBind,
SourceLocation Loc) override;
/// \brief Returns address of the threadprivate variable for the current
/// thread.
/// \param VD Threadprivate variable.
/// \param VDAddr Address of the global variable \a VD.
/// \param Loc Location of the reference to threadprivate var.
/// \return Address of the threadprivate variable for the current thread.
Address getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD,
Address VDAddr, SourceLocation Loc) override;
/// \brief Emit a code for initialization of threadprivate variable. It emits
/// a call to runtime library which adds initial value to the newly created
/// threadprivate variable (if it is not constant) and registers destructor
/// for the variable (if any).
/// \param VD Threadprivate variable.
/// \param VDAddr Address of the global variable \a VD.
/// \param Loc Location of threadprivate declaration.
/// \param PerformInit true if initialization expression is not constant.
llvm::Function *
emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr,
SourceLocation Loc, bool PerformInit,
CodeGenFunction *CGF = nullptr) override;
/// Creates artificial threadprivate variable with name \p Name and type \p
/// VarType.
/// \param VarType Type of the artificial threadprivate variable.
/// \param Name Name of the artificial threadprivate variable.
Address getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF,
QualType VarType,
StringRef Name) override;
/// \brief Emit flush of the variables specified in 'omp flush' directive.
/// \param Vars List of variables to flush.
void emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *> Vars,
SourceLocation Loc) override;
/// \brief Emit task region for the task directive. The task region is
/// emitted in several steps:
/// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
/// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
/// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
/// function:
/// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
/// TaskFunction(gtid, tt->part_id, tt->shareds);
/// return 0;
/// }
/// 2. Copy a list of shared variables to field shareds of the resulting
/// structure kmp_task_t returned by the previous call (if any).
/// 3. Copy a pointer to destructions function to field destructions of the
/// resulting structure kmp_task_t.
/// 4. Emit a call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid,
/// kmp_task_t *new_task), where new_task is a resulting structure from
/// previous items.
/// \param D Current task directive.
/// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
/// /*part_id*/, captured_struct */*__context*/);
/// \param SharedsTy A type which contains references the shared variables.
/// \param Shareds Context with the list of shared variables from the \p
/// TaskFunction.
/// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
/// otherwise.
/// \param Data Additional data for task generation like tiednsee, final
/// state, list of privates etc.
void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
const OMPExecutableDirective &D, llvm::Value *TaskFunction,
QualType SharedsTy, Address Shareds, const Expr *IfCond,
const OMPTaskDataTy &Data) override;
/// Emit task region for the taskloop directive. The taskloop region is
/// emitted in several steps:
/// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
/// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
/// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
/// function:
/// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
/// TaskFunction(gtid, tt->part_id, tt->shareds);
/// return 0;
/// }
/// 2. Copy a list of shared variables to field shareds of the resulting
/// structure kmp_task_t returned by the previous call (if any).
/// 3. Copy a pointer to destructions function to field destructions of the
/// resulting structure kmp_task_t.
/// 4. Emit a call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t
/// *task, int if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int
/// nogroup, int sched, kmp_uint64 grainsize, void *task_dup ), where new_task
/// is a resulting structure from
/// previous items.
/// \param D Current task directive.
/// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
/// /*part_id*/, captured_struct */*__context*/);
/// \param SharedsTy A type which contains references the shared variables.
/// \param Shareds Context with the list of shared variables from the \p
/// TaskFunction.
/// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
/// otherwise.
/// \param Data Additional data for task generation like tiednsee, final
/// state, list of privates etc.
void emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
const OMPLoopDirective &D, llvm::Value *TaskFunction,
QualType SharedsTy, Address Shareds, const Expr *IfCond,
const OMPTaskDataTy &Data) override;
/// \brief Emit a code for reduction clause. Next code should be emitted for
/// reduction:
/// \code
///
/// static kmp_critical_name lock = { 0 };
///
/// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
/// ...
/// *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]);
/// ...
/// }
///
/// ...
/// void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
/// switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
/// RedList, reduce_func, &<lock>)) {
/// case 1:
/// ...
/// <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
/// ...
/// __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
/// break;
/// case 2:
/// ...
/// Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
/// ...
/// break;
/// default:;
/// }
/// \endcode
///
/// \param Privates List of private copies for original reduction arguments.
/// \param LHSExprs List of LHS in \a ReductionOps reduction operations.
/// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
/// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
/// or 'operator binop(LHS, RHS)'.
/// \param Options List of options for reduction codegen:
/// WithNowait true if parent directive has also nowait clause, false
/// otherwise.
/// SimpleReduction Emit reduction operation only. Used for omp simd
/// directive on the host.
/// ReductionKind The kind of reduction to perform.
void emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
ArrayRef<const Expr *> Privates,
ArrayRef<const Expr *> LHSExprs,
ArrayRef<const Expr *> RHSExprs,
ArrayRef<const Expr *> ReductionOps,
ReductionOptionsTy Options) override;
/// Emit a code for initialization of task reduction clause. Next code
/// should be emitted for reduction:
/// \code
///
/// _task_red_item_t red_data[n];
/// ...
/// red_data[i].shar = &origs[i];
/// red_data[i].size = sizeof(origs[i]);
/// red_data[i].f_init = (void*)RedInit<i>;
/// red_data[i].f_fini = (void*)RedDest<i>;
/// red_data[i].f_comb = (void*)RedOp<i>;
/// red_data[i].flags = <Flag_i>;
/// ...
/// void* tg1 = __kmpc_task_reduction_init(gtid, n, red_data);
/// \endcode
///
/// \param LHSExprs List of LHS in \a Data.ReductionOps reduction operations.
/// \param RHSExprs List of RHS in \a Data.ReductionOps reduction operations.
/// \param Data Additional data for task generation like tiedness, final
/// state, list of privates, reductions etc.
llvm::Value *emitTaskReductionInit(CodeGenFunction &CGF, SourceLocation Loc,
ArrayRef<const Expr *> LHSExprs,
ArrayRef<const Expr *> RHSExprs,
const OMPTaskDataTy &Data) override;
/// Required to resolve existing problems in the runtime. Emits threadprivate
/// variables to store the size of the VLAs/array sections for
/// initializer/combiner/finalizer functions + emits threadprivate variable to
/// store the pointer to the original reduction item for the custom
/// initializer defined by declare reduction construct.
/// \param RCG Allows to reuse an existing data for the reductions.
/// \param N Reduction item for which fixups must be emitted.
void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc,
ReductionCodeGen &RCG, unsigned N) override;
/// Get the address of `void *` type of the privatue copy of the reduction
/// item specified by the \p SharedLVal.
/// \param ReductionsPtr Pointer to the reduction data returned by the
/// emitTaskReductionInit function.
/// \param SharedLVal Address of the original reduction item.
Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc,
llvm::Value *ReductionsPtr,
LValue SharedLVal) override;
/// \brief Emit code for 'taskwait' directive.
void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc) override;
/// \brief Emit code for 'cancellation point' construct.
/// \param CancelRegion Region kind for which the cancellation point must be
/// emitted.
///
void emitCancellationPointCall(CodeGenFunction &CGF, SourceLocation Loc,
OpenMPDirectiveKind CancelRegion) override;
/// \brief Emit code for 'cancel' construct.
/// \param IfCond Condition in the associated 'if' clause, if it was
/// specified, nullptr otherwise.
/// \param CancelRegion Region kind for which the cancel must be emitted.
///
void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
const Expr *IfCond,
OpenMPDirectiveKind CancelRegion) override;
/// \brief Emit outilined function for 'target' directive.
/// \param D Directive to emit.
/// \param ParentName Name of the function that encloses the target region.
/// \param OutlinedFn Outlined function value to be defined by this call.
/// \param OutlinedFnID Outlined function ID value to be defined by this call.
/// \param IsOffloadEntry True if the outlined function is an offload entry.
/// \param CodeGen Code generation sequence for the \a D directive.
/// An outlined function may not be an entry if, e.g. the if clause always
/// evaluates to false.
void emitTargetOutlinedFunction(const OMPExecutableDirective &D,
StringRef ParentName,
llvm::Function *&OutlinedFn,
llvm::Constant *&OutlinedFnID,
bool IsOffloadEntry,
const RegionCodeGenTy &CodeGen) override;
/// \brief Emit the target offloading code associated with \a D. The emitted
/// code attempts offloading the execution to the device, an the event of
/// a failure it executes the host version outlined in \a OutlinedFn.
/// \param D Directive to emit.
/// \param OutlinedFn Host version of the code to be offloaded.
/// \param OutlinedFnID ID of host version of the code to be offloaded.
/// \param IfCond Expression evaluated in if clause associated with the target
/// directive, or null if no if clause is used.
/// \param Device Expression evaluated in device clause associated with the
/// target directive, or null if no device clause is used.
/// \param CapturedVars Values captured in the current region.
void emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D,
llvm::Value *OutlinedFn, llvm::Value *OutlinedFnID,
const Expr *IfCond, const Expr *Device,
ArrayRef<llvm::Value *> CapturedVars) override;
/// \brief Emit the target regions enclosed in \a GD function definition or
/// the function itself in case it is a valid device function. Returns true if
/// \a GD was dealt with successfully.
/// \param GD Function to scan.
bool emitTargetFunctions(GlobalDecl GD) override;
/// \brief Emit the global variable if it is a valid device global variable.
/// Returns true if \a GD was dealt with successfully.
/// \param GD Variable declaration to emit.
bool emitTargetGlobalVariable(GlobalDecl GD) override;
/// \brief Emit the global \a GD if it is meaningful for the target. Returns
/// if it was emitted successfully.
/// \param GD Global to scan.
bool emitTargetGlobal(GlobalDecl GD) override;
/// \brief Creates the offloading descriptor in the event any target region
/// was emitted in the current module and return the function that registers
/// it.
llvm::Function *emitRegistrationFunction() override;
/// \brief Emits code for teams call of the \a OutlinedFn with
/// variables captured in a record which address is stored in \a
/// CapturedStruct.
/// \param OutlinedFn Outlined function to be run by team masters. Type of
/// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
/// \param CapturedVars A pointer to the record with the references to
/// variables used in \a OutlinedFn function.
///
void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D,
SourceLocation Loc, llvm::Value *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars) override;
/// \brief Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32
/// global_tid, kmp_int32 num_teams, kmp_int32 thread_limit) to generate code
/// for num_teams clause.
/// \param NumTeams An integer expression of teams.
/// \param ThreadLimit An integer expression of threads.
void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams,
const Expr *ThreadLimit, SourceLocation Loc) override;
/// \brief Emit the target data mapping code associated with \a D.
/// \param D Directive to emit.
/// \param IfCond Expression evaluated in if clause associated with the
/// target directive, or null if no device clause is used.
/// \param Device Expression evaluated in device clause associated with the
/// target directive, or null if no device clause is used.
/// \param Info A record used to store information that needs to be preserved
/// until the region is closed.
void emitTargetDataCalls(CodeGenFunction &CGF,
const OMPExecutableDirective &D, const Expr *IfCond,
const Expr *Device, const RegionCodeGenTy &CodeGen,
TargetDataInfo &Info) override;
/// \brief Emit the data mapping/movement code associated with the directive
/// \a D that should be of the form 'target [{enter|exit} data | update]'.
/// \param D Directive to emit.
/// \param IfCond Expression evaluated in if clause associated with the target
/// directive, or null if no if clause is used.
/// \param Device Expression evaluated in device clause associated with the
/// target directive, or null if no device clause is used.
void emitTargetDataStandAloneCall(CodeGenFunction &CGF,
const OMPExecutableDirective &D,
const Expr *IfCond,
const Expr *Device) override;
/// Emit initialization for doacross loop nesting support.
/// \param D Loop-based construct used in doacross nesting construct.
void emitDoacrossInit(CodeGenFunction &CGF,
const OMPLoopDirective &D) override;
/// Emit code for doacross ordered directive with 'depend' clause.
/// \param C 'depend' clause with 'sink|source' dependency kind.
void emitDoacrossOrdered(CodeGenFunction &CGF,
const OMPDependClause *C) override;
/// Translates the native parameter of outlined function if this is required
/// for target.
/// \param FD Field decl from captured record for the paramater.
/// \param NativeParam Parameter itself.
const VarDecl *translateParameter(const FieldDecl *FD,
const VarDecl *NativeParam) const override;
/// Gets the address of the native argument basing on the address of the
/// target-specific parameter.
/// \param NativeParam Parameter itself.
/// \param TargetParam Corresponding target-specific parameter.
Address getParameterAddress(CodeGenFunction &CGF, const VarDecl *NativeParam,
const VarDecl *TargetParam) const override;
};
} // namespace CodeGen
} // namespace clang

View File

@ -74,6 +74,15 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) {
// Generate a stoppoint if we are emitting debug info.
EmitStopPoint(S);
// Ignore all OpenMP directives except for simd if OpenMP with Simd is
// enabled.
if (getLangOpts().OpenMP && getLangOpts().OpenMPSimd) {
if (const auto *D = dyn_cast<OMPExecutableDirective>(S)) {
EmitSimpleOMPExecutableDirective(*D);
return;
}
}
switch (S->getStmtClass()) {
case Stmt::NoStmtClass:
case Stmt::CXXCatchStmtClass:

View File

@ -144,6 +144,71 @@ class OMPLoopScope : public CodeGenFunction::RunCleanupsScope {
}
};
class OMPSimdLexicalScope : public CodeGenFunction::LexicalScope {
CodeGenFunction::OMPPrivateScope InlinedShareds;
static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) {
return CGF.LambdaCaptureFields.lookup(VD) ||
(CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) ||
(CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl) &&
cast<BlockDecl>(CGF.CurCodeDecl)->capturesVariable(VD));
}
public:
OMPSimdLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
: CodeGenFunction::LexicalScope(CGF, S.getSourceRange()),
InlinedShareds(CGF) {
for (const auto *C : S.clauses()) {
if (auto *CPI = OMPClauseWithPreInit::get(C)) {
if (auto *PreInit = cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
for (const auto *I : PreInit->decls()) {
if (!I->hasAttr<OMPCaptureNoInitAttr>())
CGF.EmitVarDecl(cast<VarDecl>(*I));
else {
CodeGenFunction::AutoVarEmission Emission =
CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
CGF.EmitAutoVarCleanups(Emission);
}
}
}
} else if (const auto *UDP = dyn_cast<OMPUseDevicePtrClause>(C)) {
for (const Expr *E : UDP->varlists()) {
const Decl *D = cast<DeclRefExpr>(E)->getDecl();
if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(D))
CGF.EmitVarDecl(*OED);
}
}
}
if (!isOpenMPSimdDirective(S.getDirectiveKind()))
CGF.EmitOMPPrivateClause(S, InlinedShareds);
if (const auto *TG = dyn_cast<OMPTaskgroupDirective>(&S)) {
if (const Expr *E = TG->getReductionRef())
CGF.EmitVarDecl(*cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()));
}
const auto *CS = cast_or_null<CapturedStmt>(S.getAssociatedStmt());
while (CS) {
for (auto &C : CS->captures()) {
if (C.capturesVariable() || C.capturesVariableByCopy()) {
auto *VD = C.getCapturedVar();
assert(VD == VD->getCanonicalDecl() &&
"Canonical decl must be captured.");
DeclRefExpr DRE(const_cast<VarDecl *>(VD),
isCapturedVar(CGF, VD) ||
(CGF.CapturedStmtInfo &&
InlinedShareds.isGlobalVarCaptured(VD)),
VD->getType().getNonReferenceType(), VK_LValue,
SourceLocation());
InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address {
return CGF.EmitLValue(&DRE).getAddress();
});
}
}
CS = dyn_cast<CapturedStmt>(CS->getCapturedStmt());
}
(void)InlinedShareds.Privatize();
}
};
} // namespace
static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
@ -863,7 +928,8 @@ bool CodeGenFunction::EmitOMPLastprivateClauseInit(
llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
HasAtLeastOneLastprivate = true;
if (isOpenMPTaskLoopDirective(D.getDirectiveKind()))
if (isOpenMPTaskLoopDirective(D.getDirectiveKind()) &&
!getLangOpts().OpenMPSimd)
break;
auto IRef = C->varlist_begin();
auto IDestRef = C->destination_exprs().begin();
@ -1100,9 +1166,8 @@ void CodeGenFunction::EmitOMPReductionClauseFinal(
if (HasAtLeastOneReduction) {
bool WithNowait = D.getSingleClause<OMPNowaitClause>() ||
isOpenMPParallelDirective(D.getDirectiveKind()) ||
D.getDirectiveKind() == OMPD_simd;
bool SimpleReduction = D.getDirectiveKind() == OMPD_simd ||
D.getDirectiveKind() == OMPD_distribute_simd;
ReductionKind == OMPD_simd;
bool SimpleReduction = ReductionKind == OMPD_simd;
// Emit nowait reduction if nowait clause is present or directive is a
// parallel directive (it always has implicit barrier).
CGM.getOpenMPRuntime().emitReduction(
@ -1570,6 +1635,14 @@ static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF,
CGF.EmitStopPoint(&S);
}
/// Emit a helper variable and return corresponding lvalue.
static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
const DeclRefExpr *Helper) {
auto VDecl = cast<VarDecl>(Helper->getDecl());
CGF.EmitVarDecl(*VDecl);
return CGF.EmitLValue(Helper);
}
static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
PrePostActionTy &Action) {
Action.Enter(CGF);
@ -1581,6 +1654,12 @@ static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
// <Final counter/linear vars updates>;
// }
//
if (isOpenMPDistributeDirective(S.getDirectiveKind()) ||
isOpenMPWorksharingDirective(S.getDirectiveKind()) ||
isOpenMPTaskLoopDirective(S.getDirectiveKind())) {
(void)EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()));
(void)EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()));
}
// Emit: if (PreCond) - begin.
// If the condition constant folds and can be elided, avoid emitting the
@ -1933,14 +2012,6 @@ void CodeGenFunction::EmitOMPDistributeOuterLoop(
emitEmptyOrdered);
}
/// Emit a helper variable and return corresponding lvalue.
static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
const DeclRefExpr *Helper) {
auto VDecl = cast<VarDecl>(Helper->getDecl());
CGF.EmitVarDecl(*VDecl);
return CGF.EmitLValue(Helper);
}
static std::pair<LValue, LValue>
emitDistributeParallelForInnerBounds(CodeGenFunction &CGF,
const OMPExecutableDirective &S) {
@ -4721,3 +4792,35 @@ void CodeGenFunction::EmitOMPTargetUpdateDirective(
OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
}
void CodeGenFunction::EmitSimpleOMPExecutableDirective(
const OMPExecutableDirective &D) {
if (!D.hasAssociatedStmt() || !D.getAssociatedStmt())
return;
auto &&CodeGen = [&D](CodeGenFunction &CGF, PrePostActionTy &Action) {
if (isOpenMPSimdDirective(D.getDirectiveKind())) {
emitOMPSimdRegion(CGF, cast<OMPLoopDirective>(D), Action);
} else {
if (const auto *LD = dyn_cast<OMPLoopDirective>(&D)) {
for (const auto *E : LD->counters()) {
if (const auto *VD = dyn_cast<OMPCapturedExprDecl>(
cast<DeclRefExpr>(E)->getDecl())) {
// Emit only those that were not explicitly referenced in clauses.
if (!CGF.LocalDeclMap.count(VD))
CGF.EmitVarDecl(*VD);
}
}
}
const auto *CS = cast<CapturedStmt>(D.getAssociatedStmt());
while (const auto *CCS = dyn_cast<CapturedStmt>(CS->getCapturedStmt()))
CS = CCS;
CGF.EmitStmt(CS->getCapturedStmt());
}
};
OMPSimdLexicalScope Scope(*this, D);
CGM.getOpenMPRuntime().emitInlinedDirective(
*this,
isOpenMPSimdDirective(D.getDirectiveKind()) ? OMPD_simd
: D.getDirectiveKind(),
CodeGen);
}

View File

@ -419,6 +419,9 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
EmitIfUsed(*this, TerminateHandler);
EmitIfUsed(*this, UnreachableBlock);
for (const auto &FuncletAndParent : TerminateFunclets)
EmitIfUsed(*this, FuncletAndParent.second);
if (CGM.getCodeGenOpts().EmitDeclMetadata)
EmitDeclMetadata();

View File

@ -34,6 +34,7 @@
#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Debug.h"
@ -1420,6 +1421,9 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::BasicBlock *TerminateHandler;
llvm::BasicBlock *TrapBB;
/// Terminate funclets keyed by parent funclet pad.
llvm::MapVector<llvm::Value *, llvm::BasicBlock *> TerminateFunclets;
/// True if we need emit the life-time markers.
const bool ShouldEmitLifetimeMarkers;
@ -1808,6 +1812,10 @@ class CodeGenFunction : public CodeGenTypeCache {
/// getTerminateLandingPad - Return a landing pad that just calls terminate.
llvm::BasicBlock *getTerminateLandingPad();
/// getTerminateLandingPad - Return a cleanup funclet that just calls
/// terminate.
llvm::BasicBlock *getTerminateFunclet();
/// getTerminateHandler - Return a handler (not a landing pad, just
/// a catch handler) that just calls terminate. This is used when
/// a terminate scope encloses a try.
@ -2655,6 +2663,9 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::Value *EmitSEHExceptionInfo();
llvm::Value *EmitSEHAbnormalTermination();
/// Emit simple code for OpenMP directives in Simd-only mode.
void EmitSimpleOMPExecutableDirective(const OMPExecutableDirective &D);
/// Scan the outlined statement for captures from the parent function. For
/// each capture, mark the capture as escaped and emit a call to
/// llvm.localrecover. Insert the localrecover result into the LocalDeclMap.

View File

@ -208,6 +208,9 @@ void CodeGenModule::createOpenMPRuntime() {
OpenMPRuntime.reset(new CGOpenMPRuntimeNVPTX(*this));
break;
default:
if (LangOpts.OpenMPSimd)
OpenMPRuntime.reset(new CGOpenMPSIMDRuntime(*this));
else
OpenMPRuntime.reset(new CGOpenMPRuntime(*this));
break;
}
@ -4515,6 +4518,9 @@ llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
}
void CodeGenModule::EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
// Do not emit threadprivates in simd-only mode.
if (LangOpts.OpenMP && LangOpts.OpenMPSimd)
return;
for (auto RefExpr : D->varlists()) {
auto *VD = cast<VarDecl>(cast<DeclRefExpr>(RefExpr)->getDecl());
bool PerformInit =

View File

@ -62,6 +62,7 @@
#include "llvm/Option/OptSpecifier.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
@ -70,6 +71,7 @@
#include "llvm/Support/Program.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/StringSaver.h"
#include <map>
#include <memory>
#include <utility>
@ -92,7 +94,8 @@ Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple,
CCPrintHeadersFilename(nullptr), CCLogDiagnosticsFilename(nullptr),
CCCPrintBindings(false), CCPrintHeaders(false), CCLogDiagnostics(false),
CCGenDiagnostics(false), DefaultTargetTriple(DefaultTargetTriple),
CCCGenericGCCName(""), CheckInputsExist(true), CCCUsePCH(true),
CCCGenericGCCName(""), Saver(Alloc),
CheckInputsExist(true), CCCUsePCH(true),
GenReproducer(false), SuppressMissingInputWarning(false) {
// Provide a sane fallback if no VFS is specified.
@ -103,6 +106,13 @@ Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple,
Dir = llvm::sys::path::parent_path(ClangExecutable);
InstalledDir = Dir; // Provide a sensible default installed dir.
#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
SystemConfigDir = CLANG_CONFIG_FILE_SYSTEM_DIR;
#endif
#if defined(CLANG_CONFIG_FILE_USER_DIR)
UserConfigDir = CLANG_CONFIG_FILE_USER_DIR;
#endif
// Compute the path to the resource directory.
StringRef ClangResourceDir(CLANG_RESOURCE_DIR);
SmallString<128> P(Dir);
@ -600,6 +610,216 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
//
}
/// Looks the given directories for the specified file.
///
/// \param[out] FilePath File path, if the file was found.
/// \param[in] Dirs Directories used for the search.
/// \param[in] FileName Name of the file to search for.
/// \return True if file was found.
///
/// Looks for file specified by FileName sequentially in directories specified
/// by Dirs.
///
static bool searchForFile(SmallVectorImpl<char> &FilePath,
ArrayRef<std::string> Dirs,
StringRef FileName) {
SmallString<128> WPath;
for (const StringRef &Dir : Dirs) {
if (Dir.empty())
continue;
WPath.clear();
llvm::sys::path::append(WPath, Dir, FileName);
llvm::sys::path::native(WPath);
if (llvm::sys::fs::is_regular_file(WPath)) {
FilePath = std::move(WPath);
return true;
}
}
return false;
}
bool Driver::readConfigFile(StringRef FileName) {
// Try reading the given file.
SmallVector<const char *, 32> NewCfgArgs;
if (!llvm::cl::readConfigFile(FileName, Saver, NewCfgArgs)) {
Diag(diag::err_drv_cannot_read_config_file) << FileName;
return true;
}
// Read options from config file.
llvm::SmallString<128> CfgFileName(FileName);
llvm::sys::path::native(CfgFileName);
ConfigFile = CfgFileName.str();
bool ContainErrors;
CfgOptions = llvm::make_unique<InputArgList>(
ParseArgStrings(NewCfgArgs, ContainErrors));
if (ContainErrors) {
CfgOptions.reset();
return true;
}
if (CfgOptions->hasArg(options::OPT_config)) {
CfgOptions.reset();
Diag(diag::err_drv_nested_config_file);
return true;
}
// Claim all arguments that come from a configuration file so that the driver
// does not warn on any that is unused.
for (Arg *A : *CfgOptions)
A->claim();
return false;
}
bool Driver::loadConfigFile() {
std::string CfgFileName;
bool FileSpecifiedExplicitly = false;
// Process options that change search path for config files.
if (CLOptions) {
if (CLOptions->hasArg(options::OPT_config_system_dir_EQ)) {
SmallString<128> CfgDir;
CfgDir.append(
CLOptions->getLastArgValue(options::OPT_config_system_dir_EQ));
if (!CfgDir.empty()) {
if (llvm::sys::fs::make_absolute(CfgDir).value() != 0)
SystemConfigDir.clear();
else
SystemConfigDir = std::string(CfgDir.begin(), CfgDir.end());
}
}
if (CLOptions->hasArg(options::OPT_config_user_dir_EQ)) {
SmallString<128> CfgDir;
CfgDir.append(
CLOptions->getLastArgValue(options::OPT_config_user_dir_EQ));
if (!CfgDir.empty()) {
if (llvm::sys::fs::make_absolute(CfgDir).value() != 0)
UserConfigDir.clear();
else
UserConfigDir = std::string(CfgDir.begin(), CfgDir.end());
}
}
}
// First try to find config file specified in command line.
if (CLOptions) {
std::vector<std::string> ConfigFiles =
CLOptions->getAllArgValues(options::OPT_config);
if (ConfigFiles.size() > 1) {
Diag(diag::err_drv_duplicate_config);
return true;
}
if (!ConfigFiles.empty()) {
CfgFileName = ConfigFiles.front();
assert(!CfgFileName.empty());
// If argument contains directory separator, treat it as a path to
// configuration file.
if (llvm::sys::path::has_parent_path(CfgFileName)) {
SmallString<128> CfgFilePath;
if (llvm::sys::path::is_relative(CfgFileName))
llvm::sys::fs::current_path(CfgFilePath);
llvm::sys::path::append(CfgFilePath, CfgFileName);
if (!llvm::sys::fs::is_regular_file(CfgFilePath)) {
Diag(diag::err_drv_config_file_not_exist) << CfgFilePath;
return true;
}
return readConfigFile(CfgFilePath);
}
FileSpecifiedExplicitly = true;
}
}
// If config file is not specified explicitly, try to deduce configuration
// from executable name. For instance, an executable 'armv7l-clang' will
// search for config file 'armv7l-clang.cfg'.
if (CfgFileName.empty() && !ClangNameParts.TargetPrefix.empty())
CfgFileName = ClangNameParts.TargetPrefix + '-' + ClangNameParts.ModeSuffix;
if (CfgFileName.empty())
return false;
// Determine architecture part of the file name, if it is present.
StringRef CfgFileArch = CfgFileName;
size_t ArchPrefixLen = CfgFileArch.find('-');
if (ArchPrefixLen == StringRef::npos)
ArchPrefixLen = CfgFileArch.size();
llvm::Triple CfgTriple;
CfgFileArch = CfgFileArch.take_front(ArchPrefixLen);
CfgTriple = llvm::Triple(llvm::Triple::normalize(CfgFileArch));
if (CfgTriple.getArch() == llvm::Triple::ArchType::UnknownArch)
ArchPrefixLen = 0;
if (!StringRef(CfgFileName).endswith(".cfg"))
CfgFileName += ".cfg";
// If config file starts with architecture name and command line options
// redefine architecture (with options like -m32 -LE etc), try finding new
// config file with that architecture.
SmallString<128> FixedConfigFile;
size_t FixedArchPrefixLen = 0;
if (ArchPrefixLen) {
// Get architecture name from config file name like 'i386.cfg' or
// 'armv7l-clang.cfg'.
// Check if command line options changes effective triple.
llvm::Triple EffectiveTriple = computeTargetTriple(*this,
CfgTriple.getTriple(), *CLOptions);
if (CfgTriple.getArch() != EffectiveTriple.getArch()) {
FixedConfigFile = EffectiveTriple.getArchName();
FixedArchPrefixLen = FixedConfigFile.size();
// Append the rest of original file name so that file name transforms
// like: i386-clang.cfg -> x86_64-clang.cfg.
if (ArchPrefixLen < CfgFileName.size())
FixedConfigFile += CfgFileName.substr(ArchPrefixLen);
}
}
// Prepare list of directories where config file is searched for.
SmallVector<std::string, 3> CfgFileSearchDirs;
CfgFileSearchDirs.push_back(UserConfigDir);
CfgFileSearchDirs.push_back(SystemConfigDir);
CfgFileSearchDirs.push_back(Dir);
// Try to find config file. First try file with corrected architecture.
llvm::SmallString<128> CfgFilePath;
if (!FixedConfigFile.empty()) {
if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile))
return readConfigFile(CfgFilePath);
// If 'x86_64-clang.cfg' was not found, try 'x86_64.cfg'.
FixedConfigFile.resize(FixedArchPrefixLen);
FixedConfigFile.append(".cfg");
if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile))
return readConfigFile(CfgFilePath);
}
// Then try original file name.
if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName))
return readConfigFile(CfgFilePath);
// Finally try removing driver mode part: 'x86_64-clang.cfg' -> 'x86_64.cfg'.
if (!ClangNameParts.ModeSuffix.empty() &&
!ClangNameParts.TargetPrefix.empty()) {
CfgFileName.assign(ClangNameParts.TargetPrefix);
CfgFileName.append(".cfg");
if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName))
return readConfigFile(CfgFilePath);
}
// Report error but only if config file was specified explicitly, by option
// --config. If it was deduced from executable name, it is not an error.
if (FileSpecifiedExplicitly) {
Diag(diag::err_drv_config_file_not_found) << CfgFileName;
for (const std::string &SearchDir : CfgFileSearchDirs)
if (!SearchDir.empty())
Diag(diag::note_drv_config_file_searched_in) << SearchDir;
return true;
}
return false;
}
Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
llvm::PrettyStackTraceString CrashInfo("Compilation construction");
@ -623,12 +843,35 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
// FIXME: What are we going to do with -V and -b?
// Arguments specified in command line.
bool ContainsError;
CLOptions = llvm::make_unique<InputArgList>(
ParseArgStrings(ArgList.slice(1), ContainsError));
// Try parsing configuration file.
if (!ContainsError)
ContainsError = loadConfigFile();
bool HasConfigFile = !ContainsError && (CfgOptions.get() != nullptr);
// All arguments, from both config file and command line.
InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions)
: std::move(*CLOptions));
if (HasConfigFile)
for (auto *Opt : *CLOptions) {
const Arg *BaseArg = &Opt->getBaseArg();
if (BaseArg == Opt)
BaseArg = nullptr;
Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(),
Args.size(), BaseArg);
Copy->getValues() = Opt->getValues();
if (Opt->isClaimed())
Copy->claim();
Args.append(Copy);
}
// FIXME: This stuff needs to go into the Compilation, not the driver.
bool CCCPrintPhases;
bool ContainsError;
InputArgList Args = ParseArgStrings(ArgList.slice(1), ContainsError);
// Silence driver warnings if requested
Diags.setIgnoreAllWarnings(Args.hasArg(options::OPT_w));
@ -1144,6 +1387,10 @@ void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const {
// Print out the install directory.
OS << "InstalledDir: " << InstalledDir << '\n';
// If configuration file was used, print its path.
if (!ConfigFile.empty())
OS << "Configuration file: " << ConfigFile << '\n';
}
/// PrintDiagnosticCategories - Implement the --print-diagnostic-categories
@ -1250,6 +1497,15 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
SuppressMissingInputWarning = true;
}
if (C.getArgs().hasArg(options::OPT_v)) {
if (!SystemConfigDir.empty())
llvm::errs() << "System configuration file directory: "
<< SystemConfigDir << "\n";
if (!UserConfigDir.empty())
llvm::errs() << "User configuration file directory: "
<< UserConfigDir << "\n";
}
const ToolChain &TC = C.getDefaultToolChain();
if (C.getArgs().hasArg(options::OPT_v))

View File

@ -3901,6 +3901,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// semantic analysis, etc.
break;
}
} else {
Args.AddLastArg(CmdArgs, options::OPT_fopenmp_simd,
options::OPT_fno_openmp_simd);
Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
}
const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();

View File

@ -1192,6 +1192,13 @@ struct DarwinPlatform {
return OSVersion;
}
void setOSVersion(StringRef S) {
assert(Kind == TargetArg && "Unexpected kind!");
OSVersion = S;
}
bool hasOSVersion() const { return HasOSVersion; }
/// Returns true if the target OS was explicitly specified.
bool isExplicitlySpecified() const { return Kind <= DeploymentTargetEnv; }
@ -1235,17 +1242,21 @@ struct DarwinPlatform {
llvm_unreachable("Unsupported Darwin Source Kind");
}
static DarwinPlatform createFromTarget(llvm::Triple::OSType OS,
StringRef OSVersion, Arg *A,
llvm::Triple::EnvironmentType Env) {
DarwinPlatform Result(TargetArg, getPlatformFromOS(OS), OSVersion, A);
switch (Env) {
static DarwinPlatform createFromTarget(const llvm::Triple &TT,
StringRef OSVersion, Arg *A) {
DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()), OSVersion,
A);
switch (TT.getEnvironment()) {
case llvm::Triple::Simulator:
Result.Environment = DarwinEnvironmentKind::Simulator;
break;
default:
break;
}
unsigned Major, Minor, Micro;
TT.getOSVersion(Major, Minor, Micro);
if (Major == 0)
Result.HasOSVersion = false;
return Result;
}
static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform,
@ -1295,6 +1306,7 @@ struct DarwinPlatform {
DarwinPlatformKind Platform;
DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment;
std::string OSVersion;
bool HasOSVersion = true;
Arg *Argument;
StringRef EnvVarName;
};
@ -1489,9 +1501,8 @@ Optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
Triple.getOS() == llvm::Triple::UnknownOS)
return None;
std::string OSVersion = getOSVersion(Triple.getOS(), Triple, TheDriver);
return DarwinPlatform::createFromTarget(Triple.getOS(), OSVersion,
Args.getLastArg(options::OPT_target),
Triple.getEnvironment());
return DarwinPlatform::createFromTarget(Triple, OSVersion,
Args.getLastArg(options::OPT_target));
}
} // namespace
@ -1537,14 +1548,22 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
(VersionTuple(TargetMajor, TargetMinor, TargetMicro) !=
VersionTuple(ArgMajor, ArgMinor, ArgMicro) ||
TargetExtra != ArgExtra))) {
// Select the OS version from the -m<os>-version-min argument when
// the -target does not include an OS version.
if (OSTarget->getPlatform() == OSVersionArgTarget->getPlatform() &&
!OSTarget->hasOSVersion()) {
OSTarget->setOSVersion(OSVersionArgTarget->getOSVersion());
} else {
// Warn about -m<os>-version-min that doesn't match the OS version
// that's specified in the target.
std::string OSVersionArg = OSVersionArgTarget->getAsString(Args, Opts);
std::string OSVersionArg =
OSVersionArgTarget->getAsString(Args, Opts);
std::string TargetArg = OSTarget->getAsString(Args, Opts);
getDriver().Diag(clang::diag::warn_drv_overriding_flag_option)
<< OSVersionArg << TargetArg;
}
}
}
} else {
// The OS target can be specified using the -m<os>version-min argument.
OSTarget = getDeploymentTargetFromOSVersionArg(Args, getDriver());

View File

@ -2407,16 +2407,22 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
// Check if -fopenmp is specified.
Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 1 : 0;
// Check if -fopenmp-simd is specified.
Opts.OpenMPSimd = !Opts.OpenMP && Args.hasFlag(options::OPT_fopenmp_simd,
options::OPT_fno_openmp_simd,
/*Default=*/false);
Opts.OpenMPUseTLS =
Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls);
Opts.OpenMPIsDevice =
Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_device);
if (Opts.OpenMP) {
int Version =
getLastArgIntValue(Args, OPT_fopenmp_version_EQ, Opts.OpenMP, Diags);
if (Version != 0)
if (Opts.OpenMP || Opts.OpenMPSimd) {
if (int Version =
getLastArgIntValue(Args, OPT_fopenmp_version_EQ,
Opts.OpenMPSimd ? 45 : Opts.OpenMP, Diags))
Opts.OpenMP = Version;
else if (Opts.OpenMPSimd)
Opts.OpenMP = 45;
// Provide diagnostic when a given target is not expected to be an OpenMP
// device or host.
if (!Opts.OpenMPIsDevice) {

View File

@ -1021,8 +1021,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
Builder.defineMacro("_OPENMP", "201511");
break;
default:
// Default version is OpenMP 3.1
Builder.defineMacro("_OPENMP", "201107");
// Default version is OpenMP 3.1, in Simd only mode - 4.5
Builder.defineMacro("_OPENMP", LangOpts.OpenMPSimd ? "201511" : "201107");
break;
}

View File

@ -217,8 +217,8 @@ _mm_div_pd(__m128d __a, __m128d __b)
/// \brief Calculates the square root of the lower double-precision value of
/// the second operand and returns it in the lower 64 bits of the result.
/// The upper 64 bits of the result are copied from the upper double-
/// precision value of the first operand.
/// The upper 64 bits of the result are copied from the upper
/// double-precision value of the first operand.
///
/// \headerfile <x86intrin.h>
///
@ -260,8 +260,8 @@ _mm_sqrt_pd(__m128d __a)
/// \brief Compares lower 64-bit double-precision values of both operands, and
/// returns the lesser of the pair of values in the lower 64-bits of the
/// result. The upper 64 bits of the result are copied from the upper double-
/// precision value of the first operand.
/// result. The upper 64 bits of the result are copied from the upper
/// double-precision value of the first operand.
///
/// \headerfile <x86intrin.h>
///
@ -304,8 +304,8 @@ _mm_min_pd(__m128d __a, __m128d __b)
/// \brief Compares lower 64-bit double-precision values of both operands, and
/// returns the greater of the pair of values in the lower 64-bits of the
/// result. The upper 64 bits of the result are copied from the upper double-
/// precision value of the first operand.
/// result. The upper 64 bits of the result are copied from the upper
/// double-precision value of the first operand.
///
/// \headerfile <x86intrin.h>
///
@ -983,8 +983,10 @@ _mm_cmpnge_sd(__m128d __a, __m128d __b)
}
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] for equality. The
/// comparison yields 0 for false, 1 for true.
/// the two 128-bit floating-point vectors of [2 x double] for equality.
///
/// The comparison yields 0 for false, 1 for true. If either of the two
/// lower double-precision values is NaN, 0 is returned.
///
/// \headerfile <x86intrin.h>
///
@ -996,7 +998,8 @@ _mm_cmpnge_sd(__m128d __a, __m128d __b)
/// \param __b
/// A 128-bit vector of [2 x double]. The lower double-precision value is
/// compared to the lower double-precision value of \a __a.
/// \returns An integer containing the comparison results.
/// \returns An integer containing the comparison results. If either of the two
/// lower double-precision values is NaN, 0 is returned.
static __inline__ int __DEFAULT_FN_ATTRS
_mm_comieq_sd(__m128d __a, __m128d __b)
{
@ -1008,7 +1011,8 @@ _mm_comieq_sd(__m128d __a, __m128d __b)
/// the value in the first parameter is less than the corresponding value in
/// the second parameter.
///
/// The comparison yields 0 for false, 1 for true.
/// The comparison yields 0 for false, 1 for true. If either of the two
/// lower double-precision values is NaN, 0 is returned.
///
/// \headerfile <x86intrin.h>
///
@ -1020,7 +1024,8 @@ _mm_comieq_sd(__m128d __a, __m128d __b)
/// \param __b
/// A 128-bit vector of [2 x double]. The lower double-precision value is
/// compared to the lower double-precision value of \a __a.
/// \returns An integer containing the comparison results.
/// \returns An integer containing the comparison results. If either of the two
/// lower double-precision values is NaN, 0 is returned.
static __inline__ int __DEFAULT_FN_ATTRS
_mm_comilt_sd(__m128d __a, __m128d __b)
{
@ -1032,7 +1037,8 @@ _mm_comilt_sd(__m128d __a, __m128d __b)
/// the value in the first parameter is less than or equal to the
/// corresponding value in the second parameter.
///
/// The comparison yields 0 for false, 1 for true.
/// The comparison yields 0 for false, 1 for true. If either of the two
/// lower double-precision values is NaN, 0 is returned.
///
/// \headerfile <x86intrin.h>
///
@ -1044,7 +1050,8 @@ _mm_comilt_sd(__m128d __a, __m128d __b)
/// \param __b
/// A 128-bit vector of [2 x double]. The lower double-precision value is
/// compared to the lower double-precision value of \a __a.
/// \returns An integer containing the comparison results.
/// \returns An integer containing the comparison results. If either of the two
/// lower double-precision values is NaN, 0 is returned.
static __inline__ int __DEFAULT_FN_ATTRS
_mm_comile_sd(__m128d __a, __m128d __b)
{
@ -1056,7 +1063,8 @@ _mm_comile_sd(__m128d __a, __m128d __b)
/// the value in the first parameter is greater than the corresponding value
/// in the second parameter.
///
/// The comparison yields 0 for false, 1 for true.
/// The comparison yields 0 for false, 1 for true. If either of the two
/// lower double-precision values is NaN, 0 is returned.
///
/// \headerfile <x86intrin.h>
///
@ -1068,7 +1076,8 @@ _mm_comile_sd(__m128d __a, __m128d __b)
/// \param __b
/// A 128-bit vector of [2 x double]. The lower double-precision value is
/// compared to the lower double-precision value of \a __a.
/// \returns An integer containing the comparison results.
/// \returns An integer containing the comparison results. If either of the two
/// lower double-precision values is NaN, 0 is returned.
static __inline__ int __DEFAULT_FN_ATTRS
_mm_comigt_sd(__m128d __a, __m128d __b)
{
@ -1080,7 +1089,8 @@ _mm_comigt_sd(__m128d __a, __m128d __b)
/// the value in the first parameter is greater than or equal to the
/// corresponding value in the second parameter.
///
/// The comparison yields 0 for false, 1 for true.
/// The comparison yields 0 for false, 1 for true. If either of the two
/// lower double-precision values is NaN, 0 is returned.
///
/// \headerfile <x86intrin.h>
///
@ -1092,7 +1102,8 @@ _mm_comigt_sd(__m128d __a, __m128d __b)
/// \param __b
/// A 128-bit vector of [2 x double]. The lower double-precision value is
/// compared to the lower double-precision value of \a __a.
/// \returns An integer containing the comparison results.
/// \returns An integer containing the comparison results. If either of the two
/// lower double-precision values is NaN, 0 is returned.
static __inline__ int __DEFAULT_FN_ATTRS
_mm_comige_sd(__m128d __a, __m128d __b)
{
@ -1104,7 +1115,8 @@ _mm_comige_sd(__m128d __a, __m128d __b)
/// the value in the first parameter is unequal to the corresponding value in
/// the second parameter.
///
/// The comparison yields 0 for false, 1 for true.
/// The comparison yields 0 for false, 1 for true. If either of the two
/// lower double-precision values is NaN, 1 is returned.
///
/// \headerfile <x86intrin.h>
///
@ -1116,7 +1128,8 @@ _mm_comige_sd(__m128d __a, __m128d __b)
/// \param __b
/// A 128-bit vector of [2 x double]. The lower double-precision value is
/// compared to the lower double-precision value of \a __a.
/// \returns An integer containing the comparison results.
/// \returns An integer containing the comparison results. If either of the two
/// lower double-precision values is NaN, 1 is returned.
static __inline__ int __DEFAULT_FN_ATTRS
_mm_comineq_sd(__m128d __a, __m128d __b)
{
@ -1127,7 +1140,7 @@ _mm_comineq_sd(__m128d __a, __m128d __b)
/// the two 128-bit floating-point vectors of [2 x double] for equality. The
/// comparison yields 0 for false, 1 for true.
///
/// If either of the two lower double-precision values is NaN, 1 is returned.
/// If either of the two lower double-precision values is NaN, 0 is returned.
///
/// \headerfile <x86intrin.h>
///
@ -1140,7 +1153,7 @@ _mm_comineq_sd(__m128d __a, __m128d __b)
/// A 128-bit vector of [2 x double]. The lower double-precision value is
/// compared to the lower double-precision value of \a __a.
/// \returns An integer containing the comparison results. If either of the two
/// lower double-precision values is NaN, 1 is returned.
/// lower double-precision values is NaN, 0 is returned.
static __inline__ int __DEFAULT_FN_ATTRS
_mm_ucomieq_sd(__m128d __a, __m128d __b)
{
@ -1153,7 +1166,7 @@ _mm_ucomieq_sd(__m128d __a, __m128d __b)
/// the second parameter.
///
/// The comparison yields 0 for false, 1 for true. If either of the two lower
/// double-precision values is NaN, 1 is returned.
/// double-precision values is NaN, 0 is returned.
///
/// \headerfile <x86intrin.h>
///
@ -1166,7 +1179,7 @@ _mm_ucomieq_sd(__m128d __a, __m128d __b)
/// A 128-bit vector of [2 x double]. The lower double-precision value is
/// compared to the lower double-precision value of \a __a.
/// \returns An integer containing the comparison results. If either of the two
/// lower double-precision values is NaN, 1 is returned.
/// lower double-precision values is NaN, 0 is returned.
static __inline__ int __DEFAULT_FN_ATTRS
_mm_ucomilt_sd(__m128d __a, __m128d __b)
{
@ -1179,7 +1192,7 @@ _mm_ucomilt_sd(__m128d __a, __m128d __b)
/// corresponding value in the second parameter.
///
/// The comparison yields 0 for false, 1 for true. If either of the two lower
/// double-precision values is NaN, 1 is returned.
/// double-precision values is NaN, 0 is returned.
///
/// \headerfile <x86intrin.h>
///
@ -1192,7 +1205,7 @@ _mm_ucomilt_sd(__m128d __a, __m128d __b)
/// A 128-bit vector of [2 x double]. The lower double-precision value is
/// compared to the lower double-precision value of \a __a.
/// \returns An integer containing the comparison results. If either of the two
/// lower double-precision values is NaN, 1 is returned.
/// lower double-precision values is NaN, 0 is returned.
static __inline__ int __DEFAULT_FN_ATTRS
_mm_ucomile_sd(__m128d __a, __m128d __b)
{
@ -1257,7 +1270,7 @@ _mm_ucomige_sd(__m128d __a, __m128d __b)
/// the second parameter.
///
/// The comparison yields 0 for false, 1 for true. If either of the two lower
/// double-precision values is NaN, 0 is returned.
/// double-precision values is NaN, 1 is returned.
///
/// \headerfile <x86intrin.h>
///
@ -1270,7 +1283,7 @@ _mm_ucomige_sd(__m128d __a, __m128d __b)
/// A 128-bit vector of [2 x double]. The lower double-precision value is
/// compared to the lower double-precision value of \a __a.
/// \returns An integer containing the comparison result. If either of the two
/// lower double-precision values is NaN, 0 is returned.
/// lower double-precision values is NaN, 1 is returned.
static __inline__ int __DEFAULT_FN_ATTRS
_mm_ucomineq_sd(__m128d __a, __m128d __b)
{
@ -1935,14 +1948,15 @@ _mm_store_pd(double *__dp, __m128d __a)
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c>VMOVDDUP + VMOVAPD / MOVLHPS + MOVAPS </c> instruction.
/// This intrinsic corresponds to the
/// <c> VMOVDDUP + VMOVAPD / MOVLHPS + MOVAPS </c> instruction.
///
/// \param __dp
/// A pointer to a memory location that can store two double-precision
/// values.
/// \param __a
/// A 128-bit vector of [2 x double] whose lower 64 bits are copied to each
/// of the values in \a dp.
/// of the values in \a __dp.
static __inline__ void __DEFAULT_FN_ATTRS
_mm_store1_pd(double *__dp, __m128d __a)
{
@ -1950,18 +1964,20 @@ _mm_store1_pd(double *__dp, __m128d __a)
_mm_store_pd(__dp, __a);
}
/// \brief Stores a 128-bit vector of [2 x double] into an aligned memory
/// location.
/// \brief Moves the lower 64 bits of a 128-bit vector of [2 x double] twice to
/// the upper and lower 64 bits of a memory location.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> VMOVAPD / MOVAPD </c> instruction.
/// This intrinsic corresponds to the
/// <c> VMOVDDUP + VMOVAPD / MOVLHPS + MOVAPS </c> instruction.
///
/// \param __dp
/// A pointer to a 128-bit memory location. The address of the memory
/// location has to be 16-byte aligned.
/// A pointer to a memory location that can store two double-precision
/// values.
/// \param __a
/// A 128-bit vector of [2 x double] containing the values to be stored.
/// A 128-bit vector of [2 x double] whose lower 64 bits are copied to each
/// of the values in \a __dp.
static __inline__ void __DEFAULT_FN_ATTRS
_mm_store_pd1(double *__dp, __m128d __a)
{
@ -3846,8 +3862,7 @@ _mm_set1_epi8(char __b)
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> VPUNPCKLQDQ / PUNPCKLQDQ </c>
/// instruction.
/// This intrinsic does not correspond to a specific instruction.
///
/// \param __q0
/// A 64-bit integral value used to initialize the lower 64 bits of the
@ -4018,7 +4033,7 @@ _mm_storeu_si128(__m128i *__p, __m128i __b)
/// specified unaligned memory location. When a mask bit is 1, the
/// corresponding byte is written, otherwise it is not written.
///
/// To minimize caching, the date is flagged as non-temporal (unlikely to be
/// To minimize caching, the data is flagged as non-temporal (unlikely to be
/// used again soon). Exception and trap behavior for elements not selected
/// for storage to memory are implementation dependent.
///
@ -4532,8 +4547,8 @@ _mm_unpackhi_epi32(__m128i __a, __m128i __b)
return (__m128i)__builtin_shufflevector((__v4si)__a, (__v4si)__b, 2, 4+2, 3, 4+3);
}
/// \brief Unpacks the high-order (odd-indexed) values from two 128-bit vectors
/// of [2 x i64] and interleaves them into a 128-bit vector of [2 x i64].
/// \brief Unpacks the high-order 64-bit elements from two 128-bit vectors of
/// [2 x i64] and interleaves them into a 128-bit vector of [2 x i64].
///
/// \headerfile <x86intrin.h>
///
@ -4665,7 +4680,7 @@ _mm_unpacklo_epi64(__m128i __a, __m128i __b)
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic has no corresponding instruction.
/// This intrinsic corresponds to the <c> MOVDQ2Q </c> instruction.
///
/// \param __a
/// A 128-bit integer vector operand. The lower 64 bits are moved to the
@ -4682,7 +4697,7 @@ _mm_movepi64_pi64(__m128i __a)
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> VMOVQ / MOVQ / MOVD </c> instruction.
/// This intrinsic corresponds to the <c> MOVD+VMOVQ </c> instruction.
///
/// \param __a
/// A 64-bit value.
@ -4712,8 +4727,8 @@ _mm_move_epi64(__m128i __a)
return __builtin_shufflevector((__v2di)__a, (__m128i){ 0 }, 0, 2);
}
/// \brief Unpacks the high-order (odd-indexed) values from two 128-bit vectors
/// of [2 x double] and interleaves them into a 128-bit vector of [2 x
/// \brief Unpacks the high-order 64-bit elements from two 128-bit vectors of
/// [2 x double] and interleaves them into a 128-bit vector of [2 x
/// double].
///
/// \headerfile <x86intrin.h>
@ -4733,7 +4748,7 @@ _mm_unpackhi_pd(__m128d __a, __m128d __b)
return __builtin_shufflevector((__v2df)__a, (__v2df)__b, 1, 2+1);
}
/// \brief Unpacks the low-order (even-indexed) values from two 128-bit vectors
/// \brief Unpacks the low-order 64-bit elements from two 128-bit vectors
/// of [2 x double] and interleaves them into a 128-bit vector of [2 x
/// double].
///
@ -4792,9 +4807,9 @@ _mm_movemask_pd(__m128d __a)
/// A 128-bit vector of [2 x double].
/// \param i
/// An 8-bit immediate value. The least significant two bits specify which
/// elements to copy from a and b: \n
/// Bit[0] = 0: lower element of a copied to lower element of result. \n
/// Bit[0] = 1: upper element of a copied to lower element of result. \n
/// elements to copy from \a a and \a b: \n
/// Bit[0] = 0: lower element of \a a copied to lower element of result. \n
/// Bit[0] = 1: upper element of \a a copied to lower element of result. \n
/// Bit[1] = 0: lower element of \a b copied to upper element of result. \n
/// Bit[1] = 1: upper element of \a b copied to upper element of result. \n
/// \returns A 128-bit vector of [2 x double] containing the shuffled values.

View File

@ -115,8 +115,8 @@ _mm_hsub_ps(__m128 __a, __m128 __b)
return __builtin_ia32_hsubps((__v4sf)__a, (__v4sf)__b);
}
/// \brief Moves and duplicates high-order (odd-indexed) values from a 128-bit
/// vector of [4 x float] to float values stored in a 128-bit vector of
/// \brief Moves and duplicates odd-indexed values from a 128-bit vector
/// of [4 x float] to float values stored in a 128-bit vector of
/// [4 x float].
///
/// \headerfile <x86intrin.h>
@ -137,7 +137,7 @@ _mm_movehdup_ps(__m128 __a)
return __builtin_shufflevector((__v4sf)__a, (__v4sf)__a, 1, 1, 3, 3);
}
/// \brief Duplicates low-order (even-indexed) values from a 128-bit vector of
/// \brief Duplicates even-indexed values from a 128-bit vector of
/// [4 x float] to float values stored in a 128-bit vector of [4 x float].
///
/// \headerfile <x86intrin.h>

View File

@ -648,7 +648,7 @@ _mm_mul_epi32 (__m128i __V1, __m128i __V2)
/// input vectors are used as an input for dot product; otherwise that input
/// is treated as zero. Bits [1:0] determine which elements of the result
/// will receive a copy of the final dot product, with bit [0] corresponding
/// to the lowest element and bit [3] corresponding to the highest element of
/// to the lowest element and bit [1] corresponding to the highest element of
/// each [2 x double] vector. If a bit is set, the dot product is returned in
/// the corresponding element; otherwise that element is set to zero.
#define _mm_dp_pd(X, Y, M) __extension__ ({\
@ -866,8 +866,8 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
/// 11: Copies the selected bits from \a Y to result bits [127:96]. \n
/// Bits[3:0]: If any of these bits are set, the corresponding result
/// element is cleared.
/// \returns A 128-bit vector of [4 x float] containing the copied single-
/// precision floating point elements from the operands.
/// \returns A 128-bit vector of [4 x float] containing the copied
/// single-precision floating point elements from the operands.
#define _mm_insert_ps(X, Y, N) __builtin_ia32_insertps128((X), (Y), (N))
/// \brief Extracts a 32-bit integer from a 128-bit vector of [4 x float] and

View File

@ -43,13 +43,13 @@ using namespace clang;
///
/// Called type-id in C++.
TypeResult Parser::ParseTypeName(SourceRange *Range,
Declarator::TheContext Context,
DeclaratorContext Context,
AccessSpecifier AS,
Decl **OwnedType,
ParsedAttributes *Attrs) {
DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
if (DSC == DSC_normal)
DSC = DSC_type_specifier;
if (DSC == DeclSpecContext::DSC_normal)
DSC = DeclSpecContext::DSC_type_specifier;
// Parse the common declaration-specifiers piece.
DeclSpec DS(AttrFactory);
@ -1639,7 +1639,7 @@ void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs,
/// ParseDeclaration - Parse a full 'declaration', which consists of
/// declaration-specifiers, some number of declarators, and a semicolon.
/// 'Context' should be a Declarator::TheContext value. This returns the
/// 'Context' should be a DeclaratorContext value. This returns the
/// location of the semicolon in DeclEnd.
///
/// declaration: [C99 6.7]
@ -1653,7 +1653,7 @@ void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs,
/// [C++11/C11] static_assert-declaration
/// others... [FIXME]
///
Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context,
SourceLocation &DeclEnd,
ParsedAttributesWithRange &attrs) {
ParenBraceBracketBalancer BalancerRAIIObj(*this);
@ -1714,7 +1714,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
/// of a simple-declaration. If we find that we are, we also parse the
/// for-range-initializer, and place it here.
Parser::DeclGroupPtrTy
Parser::ParseSimpleDeclaration(unsigned Context,
Parser::ParseSimpleDeclaration(DeclaratorContext Context,
SourceLocation &DeclEnd,
ParsedAttributesWithRange &Attrs,
bool RequireSemi, ForRangeInit *FRI) {
@ -1753,7 +1753,7 @@ Parser::ParseSimpleDeclaration(unsigned Context,
/// Returns true if this might be the start of a declarator, or a common typo
/// for a declarator.
bool Parser::MightBeDeclarator(unsigned Context) {
bool Parser::MightBeDeclarator(DeclaratorContext Context) {
switch (Tok.getKind()) {
case tok::annot_cxxscope:
case tok::annot_template_id:
@ -1772,11 +1772,12 @@ bool Parser::MightBeDeclarator(unsigned Context) {
return getLangOpts().CPlusPlus;
case tok::l_square: // Might be an attribute on an unnamed bit-field.
return Context == Declarator::MemberContext && getLangOpts().CPlusPlus11 &&
NextToken().is(tok::l_square);
return Context == DeclaratorContext::MemberContext &&
getLangOpts().CPlusPlus11 && NextToken().is(tok::l_square);
case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
return Context == Declarator::MemberContext || getLangOpts().CPlusPlus;
return Context == DeclaratorContext::MemberContext ||
getLangOpts().CPlusPlus;
case tok::identifier:
switch (NextToken().getKind()) {
@ -1802,8 +1803,9 @@ bool Parser::MightBeDeclarator(unsigned Context) {
// At namespace scope, 'identifier:' is probably a typo for 'identifier::'
// and in block scope it's probably a label. Inside a class definition,
// this is a bit-field.
return Context == Declarator::MemberContext ||
(getLangOpts().CPlusPlus && Context == Declarator::FileContext);
return Context == DeclaratorContext::MemberContext ||
(getLangOpts().CPlusPlus &&
Context == DeclaratorContext::FileContext);
case tok::identifier: // Possible virt-specifier.
return getLangOpts().CPlusPlus11 && isCXX11VirtSpecifier(NextToken());
@ -1902,11 +1904,11 @@ void Parser::SkipMalformedDecl() {
/// definition or a group of object declarations, actually parse the
/// result.
Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
unsigned Context,
DeclaratorContext Context,
SourceLocation *DeclEnd,
ForRangeInit *FRI) {
// Parse the first declarator.
ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
ParsingDeclarator D(*this, DS, Context);
ParseDeclarator(D);
// Bail out if the first declarator didn't seem well-formed.
@ -1953,7 +1955,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// Function definitions are only allowed at file scope and in C++ classes.
// The C++ inline method definition case is handled elsewhere, so we only
// need to handle the file scope definition case.
if (Context == Declarator::FileContext) {
if (Context == DeclaratorContext::FileContext) {
if (isStartOfFunctionDefinition(D)) {
if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
Diag(Tok, diag::err_function_declared_typedef);
@ -2024,7 +2026,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
if (FirstDecl)
DeclsInGroup.push_back(FirstDecl);
bool ExpectSemi = Context != Declarator::ForContext;
bool ExpectSemi = Context != DeclaratorContext::ForContext;
// If we don't have a comma, it is either the end of the list (a ';') or an
// error, bail out.
@ -2070,7 +2072,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
*DeclEnd = Tok.getLocation();
if (ExpectSemi &&
ExpectAndConsumeSemi(Context == Declarator::FileContext
ExpectAndConsumeSemi(Context == DeclaratorContext::FileContext
? diag::err_invalid_token_after_toplevel_declarator
: diag::err_expected_semi_declaration)) {
// Okay, there was no semicolon and one was expected. If we see a
@ -2199,7 +2201,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
// FIXME: This check should be for a variable template instantiation only.
// Check that this is a valid instantiation
if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
if (D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {
// If the declarator-id is not a template-id, issue a diagnostic and
// recover by ignoring the 'template' keyword.
Diag(Tok, diag::err_template_defn_explicit_instantiation)
@ -2273,8 +2275,8 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
if (Init.isInvalid()) {
SmallVector<tok::TokenKind, 2> StopTokens;
StopTokens.push_back(tok::comma);
if (D.getContext() == Declarator::ForContext ||
D.getContext() == Declarator::InitStmtContext)
if (D.getContext() == DeclaratorContext::ForContext ||
D.getContext() == DeclaratorContext::InitStmtContext)
StopTokens.push_back(tok::r_paren);
SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
Actions.ActOnInitializerError(ThisDecl);
@ -2397,7 +2399,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
}
// Issue diagnostic and remove constexpr specfier if present.
if (DS.isConstexprSpecified() && DSC != DSC_condition) {
if (DS.isConstexprSpecified() && DSC != DeclSpecContext::DSC_condition) {
Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
DS.ClearConstexprSpec();
}
@ -2486,7 +2488,7 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
// classes.
if (ParsedType T = Actions.ActOnMSVCUnknownTypeName(
*Tok.getIdentifierInfo(), Tok.getLocation(),
DSC == DSC_template_type_arg)) {
DSC == DeclSpecContext::DSC_template_type_arg)) {
const char *PrevSpec;
unsigned DiagID;
DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T,
@ -2540,18 +2542,20 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
// Parse this as a tag as if the missing tag were present.
if (TagKind == tok::kw_enum)
ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal);
ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
DeclSpecContext::DSC_normal);
else
ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
/*EnteringContext*/ false, DSC_normal, Attrs);
/*EnteringContext*/ false,
DeclSpecContext::DSC_normal, Attrs);
return true;
}
}
// Determine whether this identifier could plausibly be the name of something
// being declared (with a missing type).
if (!isTypeSpecifier(DSC) &&
(!SS || DSC == DSC_top_level || DSC == DSC_class)) {
if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
DSC == DeclSpecContext::DSC_class)) {
// Look ahead to the next token to try to figure out what this declaration
// was supposed to be.
switch (NextToken().getKind()) {
@ -2575,7 +2579,8 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
// If we're in a context where we could be declaring a constructor,
// check whether this is a constructor declaration with a bogus name.
if (DSC == DSC_class || (DSC == DSC_top_level && SS)) {
if (DSC == DeclSpecContext::DSC_class ||
(DSC == DeclSpecContext::DSC_top_level && SS)) {
IdentifierInfo *II = Tok.getIdentifierInfo();
if (Actions.isCurrentClassNameTypo(II, SS)) {
Diag(Loc, diag::err_constructor_bad_name)
@ -2655,23 +2660,23 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
/// context.
///
/// \param Context the declarator context, which is one of the
/// Declarator::TheContext enumerator values.
/// DeclaratorContext enumerator values.
Parser::DeclSpecContext
Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) {
if (Context == Declarator::MemberContext)
return DSC_class;
if (Context == Declarator::FileContext)
return DSC_top_level;
if (Context == Declarator::TemplateParamContext)
return DSC_template_param;
if (Context == Declarator::TemplateTypeArgContext)
return DSC_template_type_arg;
if (Context == Declarator::TrailingReturnContext)
return DSC_trailing;
if (Context == Declarator::AliasDeclContext ||
Context == Declarator::AliasTemplateContext)
return DSC_alias_declaration;
return DSC_normal;
Parser::getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context) {
if (Context == DeclaratorContext::MemberContext)
return DeclSpecContext::DSC_class;
if (Context == DeclaratorContext::FileContext)
return DeclSpecContext::DSC_top_level;
if (Context == DeclaratorContext::TemplateParamContext)
return DeclSpecContext::DSC_template_param;
if (Context == DeclaratorContext::TemplateTypeArgContext)
return DeclSpecContext::DSC_template_type_arg;
if (Context == DeclaratorContext::TrailingReturnContext)
return DeclSpecContext::DSC_trailing;
if (Context == DeclaratorContext::AliasDeclContext ||
Context == DeclaratorContext::AliasTemplateContext)
return DeclSpecContext::DSC_alias_declaration;
return DeclSpecContext::DSC_normal;
}
/// ParseAlignArgument - Parse the argument to an alignment-specifier.
@ -2751,7 +2756,8 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
LateParsedAttrList *LateAttrs) {
assert(DS.hasTagDefinition() && "shouldn't call this");
bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
DSContext == DeclSpecContext::DSC_top_level);
if (getLangOpts().CPlusPlus &&
Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
@ -2885,7 +2891,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
DS.SetRangeEnd(SourceLocation());
}
bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
DSContext == DeclSpecContext::DSC_top_level);
bool AttrsLastTime = false;
ParsedAttributesWithRange attrs(AttrFactory);
// We use Sema's policy to get bool macros right.
@ -2955,8 +2962,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Scope::FunctionPrototypeScope |
Scope::AtCatchScope)) == 0;
bool AllowNestedNameSpecifiers
= DSContext == DSC_top_level ||
(DSContext == DSC_class && DS.isFriendSpecified());
= DSContext == DeclSpecContext::DSC_top_level ||
(DSContext == DeclSpecContext::DSC_class && DS.isFriendSpecified());
Actions.CodeCompleteDeclSpec(getCurScope(), DS,
AllowNonIdentifiers,
@ -2967,9 +2974,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
CCC = Sema::PCC_LocalDeclarationSpecifiers;
else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate
CCC = DSContext == DeclSpecContext::DSC_class ? Sema::PCC_MemberTemplate
: Sema::PCC_Template;
else if (DSContext == DSC_class)
else if (DSContext == DeclSpecContext::DSC_class)
CCC = Sema::PCC_Class;
else if (CurParsedObjCImpl)
CCC = Sema::PCC_ObjCImplementation;
@ -3013,7 +3020,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// To improve diagnostics for this case, parse the declaration as a
// constructor (and reject the extra template arguments later).
TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
if ((DSContext == DeclSpecContext::DSC_top_level ||
DSContext == DeclSpecContext::DSC_class) &&
TemplateId->Name &&
Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS) &&
isConstructorDeclarator(/*Unqualified*/ false)) {
@ -3055,7 +3063,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// Check whether this is a constructor declaration. If we're in a
// context where the identifier could be a class name, and it has the
// shape of a constructor declaration, process it as one.
if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
if ((DSContext == DeclSpecContext::DSC_top_level ||
DSContext == DeclSpecContext::DSC_class) &&
Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
&SS) &&
isConstructorDeclarator(/*Unqualified*/ false))
@ -3193,7 +3202,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
if (DS.isTypeAltiVecVector())
goto DoneWithDeclSpec;
if (DSContext == DSC_objc_method_result && isObjCInstancetype()) {
if (DSContext == DeclSpecContext::DSC_objc_method_result &&
isObjCInstancetype()) {
ParsedType TypeRep = Actions.ActOnObjCInstanceType(Loc);
assert(TypeRep);
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
@ -3227,7 +3237,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// If we're in a context where the identifier could be a class name,
// check whether this is a constructor declaration.
if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
if (getLangOpts().CPlusPlus && DSContext == DeclSpecContext::DSC_class &&
Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
isConstructorDeclarator(/*Unqualified*/true))
goto DoneWithDeclSpec;
@ -3235,7 +3245,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// Likewise, if this is a context where the identifier could be a template
// name, check whether this is a deduction guide declaration.
if (getLangOpts().CPlusPlus17 &&
(DSContext == DSC_class || DSContext == DSC_top_level) &&
(DSContext == DeclSpecContext::DSC_class ||
DSContext == DeclSpecContext::DSC_top_level) &&
Actions.isDeductionGuideName(getCurScope(), *Tok.getIdentifierInfo(),
Tok.getLocation()) &&
isConstructorDeclarator(/*Unqualified*/ true,
@ -3281,7 +3292,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// If we're in a context where the template-id could be a
// constructor name or specialization, check whether this is a
// constructor declaration.
if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
if (getLangOpts().CPlusPlus && DSContext == DeclSpecContext::DSC_class &&
Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
isConstructorDeclarator(TemplateId->SS.isEmpty()))
goto DoneWithDeclSpec;
@ -3451,7 +3462,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// friend
case tok::kw_friend:
if (DSContext == DSC_class)
if (DSContext == DeclSpecContext::DSC_class)
isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
else {
PrevSpec = ""; // not actually used by the diagnostic
@ -4070,7 +4081,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
// Enum definitions should not be parsed in a trailing-return-type.
bool AllowDeclaration = DSC != DSC_trailing;
bool AllowDeclaration = DSC != DeclSpecContext::DSC_trailing;
bool AllowFixedUnderlyingType = AllowDeclaration &&
(getLangOpts().CPlusPlus11 || getLangOpts().MicrosoftExt ||
@ -4296,14 +4307,14 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
bool IsDependent = false;
const char *PrevSpec = nullptr;
unsigned DiagID;
Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
StartLoc, SS, Name, NameLoc, attrs.getList(),
AS, DS.getModulePrivateSpecLoc(), TParams,
Owned, IsDependent, ScopedEnumKWLoc,
IsScopedUsingClassTag, BaseType,
DSC == DSC_type_specifier,
DSC == DSC_template_param ||
DSC == DSC_template_type_arg, &SkipBody);
Decl *TagDecl = Actions.ActOnTag(
getCurScope(), DeclSpec::TST_enum, TUK, StartLoc, SS, Name, NameLoc,
attrs.getList(), AS, DS.getModulePrivateSpecLoc(), TParams, Owned,
IsDependent, ScopedEnumKWLoc, IsScopedUsingClassTag, BaseType,
DSC == DeclSpecContext::DSC_type_specifier,
DSC == DeclSpecContext::DSC_template_param ||
DSC == DeclSpecContext::DSC_template_type_arg,
&SkipBody);
if (SkipBody.ShouldSkip) {
assert(TUK == Sema::TUK_Definition && "can only skip a definition");
@ -5175,7 +5186,7 @@ void Parser::ParseDeclarator(Declarator &D) {
}
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang,
unsigned TheContext) {
DeclaratorContext TheContext) {
if (Kind == tok::star || Kind == tok::caret)
return true;
@ -5194,8 +5205,9 @@ static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang,
// (The same thing can in theory happen after a trailing-return-type, but
// since those are a C++11 feature, there is no rejects-valid issue there.)
if (Kind == tok::ampamp)
return Lang.CPlusPlus11 || (TheContext != Declarator::ConversionIdContext &&
TheContext != Declarator::CXXNewContext);
return Lang.CPlusPlus11 ||
(TheContext != DeclaratorContext::ConversionIdContext &&
TheContext != DeclaratorContext::CXXNewContext);
return false;
}
@ -5249,8 +5261,9 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
(Tok.is(tok::identifier) &&
(NextToken().is(tok::coloncolon) || NextToken().is(tok::less))) ||
Tok.is(tok::annot_cxxscope))) {
bool EnteringContext = D.getContext() == Declarator::FileContext ||
D.getContext() == Declarator::MemberContext;
bool EnteringContext =
D.getContext() == DeclaratorContext::FileContext ||
D.getContext() == DeclaratorContext::MemberContext;
CXXScopeSpec SS;
ParseOptionalCXXScopeSpecifier(SS, nullptr, EnteringContext);
@ -5316,7 +5329,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
// GNU attributes are not allowed here in a new-type-id, but Declspec and
// C++11 attributes are allowed.
unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
((D.getContext() != Declarator::CXXNewContext)
((D.getContext() != DeclaratorContext::CXXNewContext)
? AR_GNUAttributesParsed
: AR_GNUAttributesParsedAndRejected);
ParseTypeQualifierListOpt(DS, Reqs, true, !D.mayOmitIdentifier());
@ -5470,15 +5483,16 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
// Don't parse FOO:BAR as if it were a typo for FOO::BAR inside a class, in
// this context it is a bitfield. Also in range-based for statement colon
// may delimit for-range-declaration.
ColonProtectionRAIIObject X(*this,
D.getContext() == Declarator::MemberContext ||
(D.getContext() == Declarator::ForContext &&
ColonProtectionRAIIObject X(
*this, D.getContext() == DeclaratorContext::MemberContext ||
(D.getContext() == DeclaratorContext::ForContext &&
getLangOpts().CPlusPlus11));
// ParseDeclaratorInternal might already have parsed the scope.
if (D.getCXXScopeSpec().isEmpty()) {
bool EnteringContext = D.getContext() == Declarator::FileContext ||
D.getContext() == Declarator::MemberContext;
bool EnteringContext =
D.getContext() == DeclaratorContext::FileContext ||
D.getContext() == DeclaratorContext::MemberContext;
ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), nullptr,
EnteringContext);
}
@ -5507,9 +5521,9 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
// been expanded or contains auto; otherwise, it is parsed as part of the
// parameter-declaration-clause.
if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
!((D.getContext() == Declarator::PrototypeContext ||
D.getContext() == Declarator::LambdaExprParameterContext ||
D.getContext() == Declarator::BlockLiteralContext) &&
!((D.getContext() == DeclaratorContext::PrototypeContext ||
D.getContext() == DeclaratorContext::LambdaExprParameterContext ||
D.getContext() == DeclaratorContext::BlockLiteralContext) &&
NextToken().is(tok::r_paren) &&
!D.hasGroupingParens() &&
!Actions.containsUnexpandedParameterPacks(D) &&
@ -5541,14 +5555,15 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
AllowDeductionGuide = false;
} else if (D.getCXXScopeSpec().isSet()) {
AllowConstructorName =
(D.getContext() == Declarator::FileContext ||
D.getContext() == Declarator::MemberContext);
(D.getContext() == DeclaratorContext::FileContext ||
D.getContext() == DeclaratorContext::MemberContext);
AllowDeductionGuide = false;
} else {
AllowConstructorName = (D.getContext() == Declarator::MemberContext);
AllowConstructorName =
(D.getContext() == DeclaratorContext::MemberContext);
AllowDeductionGuide =
(D.getContext() == Declarator::FileContext ||
D.getContext() == Declarator::MemberContext);
(D.getContext() == DeclaratorContext::FileContext ||
D.getContext() == DeclaratorContext::MemberContext);
}
SourceLocation TemplateKWLoc;
@ -5604,15 +5619,15 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
// An identifier within parens is unlikely to be intended to be anything
// other than a name being "declared".
DiagnoseIdentifier = true;
else if (D.getContext() == Declarator::TemplateTypeArgContext)
else if (D.getContext() == DeclaratorContext::TemplateTypeArgContext)
// T<int N> is an accidental identifier; T<int N indicates a missing '>'.
DiagnoseIdentifier =
NextToken().isOneOf(tok::comma, tok::greater, tok::greatergreater);
else if (D.getContext() == Declarator::AliasDeclContext ||
D.getContext() == Declarator::AliasTemplateContext)
else if (D.getContext() == DeclaratorContext::AliasDeclContext ||
D.getContext() == DeclaratorContext::AliasTemplateContext)
// The most likely error is that the ';' was forgotten.
DiagnoseIdentifier = NextToken().isOneOf(tok::comma, tok::semi);
else if (D.getContext() == Declarator::TrailingReturnContext &&
else if (D.getContext() == DeclaratorContext::TrailingReturnContext &&
!isCXX11VirtSpecifier(Tok))
DiagnoseIdentifier = NextToken().isOneOf(
tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
@ -5659,7 +5674,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
LLVM_BUILTIN_TRAP;
if (Tok.is(tok::l_square))
return ParseMisplacedBracketDeclarator(D);
if (D.getContext() == Declarator::MemberContext) {
if (D.getContext() == DeclaratorContext::MemberContext) {
// Objective-C++: Detect C++ keywords and try to prevent further errors by
// treating these keyword as valid member names.
if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus &&
@ -6042,9 +6057,9 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
bool IsCXX11MemberFunction =
getLangOpts().CPlusPlus11 &&
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
(D.getContext() == Declarator::MemberContext
(D.getContext() == DeclaratorContext::MemberContext
? !D.getDeclSpec().isFriendSpecified()
: D.getContext() == Declarator::FileContext &&
: D.getContext() == DeclaratorContext::FileContext &&
D.getCXXScopeSpec().isValid() &&
Actions.CurContext->isRecord());
Sema::CXXThisScopeRAII ThisScope(Actions,
@ -6309,10 +6324,10 @@ void Parser::ParseParameterDeclarationClause(
// Parse the declarator. This is "PrototypeContext" or
// "LambdaExprParameterContext", because we must accept either
// 'declarator' or 'abstract-declarator' here.
Declarator ParmDeclarator(DS,
D.getContext() == Declarator::LambdaExprContext ?
Declarator::LambdaExprParameterContext :
Declarator::PrototypeContext);
Declarator ParmDeclarator(
DS, D.getContext() == DeclaratorContext::LambdaExprContext
? DeclaratorContext::LambdaExprParameterContext
: DeclaratorContext::PrototypeContext);
ParseDeclarator(ParmDeclarator);
// Parse GNU attributes, if present.
@ -6355,7 +6370,7 @@ void Parser::ParseParameterDeclarationClause(
SourceLocation EqualLoc = Tok.getLocation();
// Parse the default argument
if (D.getContext() == Declarator::MemberContext) {
if (D.getContext() == DeclaratorContext::MemberContext) {
// If we're inside a class definition, cache the tokens
// corresponding to the default argument. We'll actually parse
// them when we see the end of the class definition.

View File

@ -55,7 +55,7 @@ using namespace clang;
/// namespace-alias-definition: [C++ 7.3.2: namespace.alias]
/// 'namespace' identifier '=' qualified-namespace-specifier ';'
///
Parser::DeclGroupPtrTy Parser::ParseNamespace(unsigned Context,
Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context,
SourceLocation &DeclEnd,
SourceLocation InlineLoc) {
assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
@ -307,7 +307,7 @@ Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
/// 'extern' string-literal '{' declaration-seq[opt] '}'
/// 'extern' string-literal declaration
///
Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {
assert(isTokenStringLiteral() && "Not a string literal!");
ExprResult Lang = ParseStringLiteralExpression(false);
@ -434,7 +434,7 @@ Decl *Parser::ParseExportDeclaration() {
/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
/// using-directive. Assumes that current token is 'using'.
Parser::DeclGroupPtrTy
Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
Parser::ParseUsingDirectiveOrDeclaration(DeclaratorContext Context,
const ParsedTemplateInfo &TemplateInfo,
SourceLocation &DeclEnd,
ParsedAttributesWithRange &attrs) {
@ -482,7 +482,7 @@ Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
/// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
/// namespace-name attributes[opt] ;
///
Decl *Parser::ParseUsingDirective(unsigned Context,
Decl *Parser::ParseUsingDirective(DeclaratorContext Context,
SourceLocation UsingLoc,
SourceLocation &DeclEnd,
ParsedAttributes &attrs) {
@ -551,7 +551,8 @@ Decl *Parser::ParseUsingDirective(unsigned Context,
/// using-declarator:
/// 'typename'[opt] nested-name-specifier unqualified-id
///
bool Parser::ParseUsingDeclarator(unsigned Context, UsingDeclarator &D) {
bool Parser::ParseUsingDeclarator(DeclaratorContext Context,
UsingDeclarator &D) {
D.clear();
// Ignore optional 'typename'.
@ -582,7 +583,8 @@ bool Parser::ParseUsingDeclarator(unsigned Context, UsingDeclarator &D) {
// or the simple-template-id's template-name in the last component of the
// nested-name-specifier, the name is [...] considered to name the
// constructor.
if (getLangOpts().CPlusPlus11 && Context == Declarator::MemberContext &&
if (getLangOpts().CPlusPlus11 &&
Context == DeclaratorContext::MemberContext &&
Tok.is(tok::identifier) &&
(NextToken().is(tok::semi) || NextToken().is(tok::comma) ||
NextToken().is(tok::ellipsis)) &&
@ -629,7 +631,7 @@ bool Parser::ParseUsingDeclarator(unsigned Context, UsingDeclarator &D) {
/// 'using' identifier attribute-specifier-seq[opt] = type-id ;
///
Parser::DeclGroupPtrTy
Parser::ParseUsingDeclaration(unsigned Context,
Parser::ParseUsingDeclaration(DeclaratorContext Context,
const ParsedTemplateInfo &TemplateInfo,
SourceLocation UsingLoc, SourceLocation &DeclEnd,
AccessSpecifier AS) {
@ -699,7 +701,7 @@ Parser::ParseUsingDeclaration(unsigned Context,
// "typename" keyword is allowed for identifiers only,
// because it may be a type definition.
if (D.TypenameLoc.isValid() &&
D.Name.getKind() != UnqualifiedId::IK_Identifier) {
D.Name.getKind() != UnqualifiedIdKind::IK_Identifier) {
Diag(D.Name.getSourceRange().getBegin(),
diag::err_typename_identifiers_only)
<< FixItHint::CreateRemoval(SourceRange(D.TypenameLoc));
@ -753,7 +755,7 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator(
// Type alias templates cannot be specialized.
int SpecKind = -1;
if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
D.Name.getKind() == UnqualifiedId::IK_TemplateId)
D.Name.getKind() == UnqualifiedIdKind::IK_TemplateId)
SpecKind = 0;
if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
SpecKind = 1;
@ -773,7 +775,7 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator(
}
// Name must be an identifier.
if (D.Name.getKind() != UnqualifiedId::IK_Identifier) {
if (D.Name.getKind() != UnqualifiedIdKind::IK_Identifier) {
Diag(D.Name.StartLocation, diag::err_alias_declaration_not_identifier);
// No removal fixit: can't recover from this.
SkipUntil(tok::semi);
@ -791,10 +793,10 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator(
<< FixItHint::CreateRemoval(SourceRange(D.EllipsisLoc));
Decl *DeclFromDeclSpec = nullptr;
TypeResult TypeAlias =
ParseTypeName(nullptr,
TemplateInfo.Kind ? Declarator::AliasTemplateContext
: Declarator::AliasDeclContext,
TypeResult TypeAlias = ParseTypeName(
nullptr,
TemplateInfo.Kind ? DeclaratorContext::AliasTemplateContext
: DeclaratorContext::AliasDeclContext,
AS, &DeclFromDeclSpec, &Attrs);
if (OwnedType)
*OwnedType = DeclFromDeclSpec;
@ -1094,7 +1096,7 @@ TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
EndLocation = ParseDecltypeSpecifier(DS);
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
}
@ -1195,7 +1197,7 @@ TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type,
Actions.getASTContext().getPrintingPolicy());
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
}
@ -1612,14 +1614,15 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// new struct s;
// or
// &T::operator struct s;
// For these, DSC is DSC_type_specifier or DSC_alias_declaration.
// For these, DSC is DeclSpecContext::DSC_type_specifier or
// DeclSpecContext::DSC_alias_declaration.
// If there are attributes after class name, parse them.
MaybeParseCXX11Attributes(Attributes);
const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
Sema::TagUseKind TUK;
if (DSC == DSC_trailing)
if (DSC == DeclSpecContext::DSC_trailing)
TUK = Sema::TUK_Reference;
else if (Tok.is(tok::l_brace) ||
(getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
@ -1881,15 +1884,14 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
// Declaration or definition of a class type
TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
SS, Name, NameLoc, attrs.getList(), AS,
DS.getModulePrivateSpecLoc(),
TParams, Owned, IsDependent,
SourceLocation(), false,
clang::TypeResult(),
DSC == DSC_type_specifier,
DSC == DSC_template_param ||
DSC == DSC_template_type_arg, &SkipBody);
TagOrTempResult = Actions.ActOnTag(
getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc,
attrs.getList(), AS, DS.getModulePrivateSpecLoc(), TParams, Owned,
IsDependent, SourceLocation(), false, clang::TypeResult(),
DSC == DeclSpecContext::DSC_type_specifier,
DSC == DeclSpecContext::DSC_template_param ||
DSC == DeclSpecContext::DSC_template_type_arg,
&SkipBody);
// If ActOnTag said the type was dependent, try again with the
// less common call.
@ -2509,7 +2511,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
SourceLocation DeclEnd;
return DeclGroupPtrTy::make(
DeclGroupRef(ParseTemplateDeclarationOrSpecialization(
Declarator::MemberContext, DeclEnd, AS, AccessAttrs)));
DeclaratorContext::MemberContext, DeclEnd, AS, AccessAttrs)));
}
// Handle: member-declaration ::= '__extension__' member-declaration
@ -2545,7 +2547,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
}
SourceLocation DeclEnd;
// Otherwise, it must be a using-declaration or an alias-declaration.
return ParseUsingDeclaration(Declarator::MemberContext, TemplateInfo,
return ParseUsingDeclaration(DeclaratorContext::MemberContext, TemplateInfo,
UsingLoc, DeclEnd, AS);
}
@ -2559,7 +2561,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
if (MalformedTypeSpec)
DS.SetTypeSpecError();
ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class,
ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DeclSpecContext::DSC_class,
&CommonLateParsedAttrs);
// Turn off colon protection that was set for declspec.
@ -2569,7 +2571,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// may get this far before the problem becomes obvious.
if (DS.hasTagDefinition() &&
TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate &&
DiagnoseMissingSemiAfterTagDefinition(DS, AS, DSC_class,
DiagnoseMissingSemiAfterTagDefinition(DS, AS, DeclSpecContext::DSC_class,
&CommonLateParsedAttrs))
return nullptr;
@ -2593,7 +2595,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
return Actions.ConvertDeclToDeclGroup(TheDecl);
}
ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
ParsingDeclarator DeclaratorInfo(*this, DS, DeclaratorContext::MemberContext);
VirtSpecifiers VS;
// Hold late-parsed attributes so we can attach a Decl to them later.
@ -2852,7 +2854,7 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
break;
if (Tok.isAtStartOfLine() &&
!MightBeDeclarator(Declarator::MemberContext)) {
!MightBeDeclarator(DeclaratorContext::MemberContext)) {
// This comma was followed by a line-break and something which can't be
// the start of a declarator. The comma was probably a typo for a
// semicolon.
@ -3709,7 +3711,7 @@ TypeResult Parser::ParseTrailingReturnType(SourceRange &Range) {
ConsumeToken();
return ParseTypeName(&Range, Declarator::TrailingReturnContext);
return ParseTypeName(&Range, DeclaratorContext::TrailingReturnContext);
}
/// \brief We have just started parsing the definition of a new class,

View File

@ -1000,7 +1000,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ,
Actions.getASTContext().getPrintingPolicy());
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
TypeResult Ty = Actions.ActOnTypeName(getCurScope(),
DeclaratorInfo);
if (Ty.isInvalid())
@ -1209,7 +1209,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
PrevSpec, DiagID, Type,
Actions.getASTContext().getPrintingPolicy());
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
if (Ty.isInvalid())
break;
@ -1824,7 +1824,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
if (isTypeIdUnambiguously()) {
DeclSpec DS(AttrFactory);
ParseSpecifierQualifierList(DS);
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
ParseDeclarator(DeclaratorInfo);
SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation());
@ -2381,7 +2381,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// Parse the type declarator.
DeclSpec DS(AttrFactory);
ParseSpecifierQualifierList(DS);
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
ParseDeclarator(DeclaratorInfo);
// If our type is followed by an identifier and either ':' or ']', then
@ -2858,7 +2858,7 @@ void Parser::ParseBlockId(SourceLocation CaretLoc) {
ParseSpecifierQualifierList(DS);
// Parse the block-declarator.
Declarator DeclaratorInfo(DS, Declarator::BlockLiteralContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::BlockLiteralContext);
DeclaratorInfo.setFunctionDefinitionKind(FDK_Definition);
ParseDeclarator(DeclaratorInfo);
@ -2897,7 +2897,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
// Parse the return type if present.
DeclSpec DS(AttrFactory);
Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
Declarator ParamInfo(DS, DeclaratorContext::BlockLiteralContext);
ParamInfo.setFunctionDefinitionKind(FDK_Definition);
// FIXME: Since the return type isn't actually parsed, it can't be used to
// fill ParamInfo with an initial valid range, so do it manually.

View File

@ -292,8 +292,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
break;
}
if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId &&
TemplateName.getKind() != UnqualifiedId::IK_LiteralOperatorId) {
if (TemplateName.getKind() != UnqualifiedIdKind::IK_OperatorFunctionId &&
TemplateName.getKind() != UnqualifiedIdKind::IK_LiteralOperatorId) {
Diag(TemplateName.getSourceRange().getBegin(),
diag::err_id_after_template_in_nested_name_spec)
<< TemplateName.getSourceRange();
@ -1090,7 +1090,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
// Parse lambda-declarator[opt].
DeclSpec DS(AttrFactory);
Declarator D(DS, Declarator::LambdaExprContext);
Declarator D(DS, DeclaratorContext::LambdaExprContext);
TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
Actions.PushLambdaScope();
@ -1353,7 +1353,7 @@ ExprResult Parser::ParseCXXCasts() {
ParseSpecifierQualifierList(DS);
// Parse the abstract-declarator, if present.
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
ParseDeclarator(DeclaratorInfo);
SourceLocation RAngleBracketLoc = Tok.getLocation();
@ -1660,7 +1660,7 @@ ExprResult Parser::ParseCXXThis() {
/// In C++1z onwards, the type specifier can also be a template-name.
ExprResult
Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
Declarator DeclaratorInfo(DS, Declarator::FunctionalCastContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::FunctionalCastContext);
ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
assert((Tok.is(tok::l_paren) ||
@ -1767,8 +1767,9 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,
: diag::ext_init_statement)
<< (CK == Sema::ConditionKind::Switch);
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
DeclGroupPtrTy DG = ParseSimpleDeclaration(
Declarator::InitStmtContext, DeclEnd, attrs, /*RequireSemi=*/true);
DeclGroupPtrTy DG =
ParseSimpleDeclaration(DeclaratorContext::InitStmtContext, DeclEnd,
attrs, /*RequireSemi=*/true);
*InitStmt = Actions.ActOnDeclStmt(DG, DeclStart, DeclEnd);
return ParseCXXCondition(nullptr, Loc, CK);
}
@ -1781,10 +1782,10 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,
// type-specifier-seq
DeclSpec DS(AttrFactory);
DS.takeAttributesFrom(attrs);
ParseSpecifierQualifierList(DS, AS_none, DSC_condition);
ParseSpecifierQualifierList(DS, AS_none, DeclSpecContext::DSC_condition);
// declarator
Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::ConditionContext);
ParseDeclarator(DeclaratorInfo);
// simple-asm-expr[opt]
@ -1982,7 +1983,7 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
/// type-specifier type-specifier-seq[opt]
///
bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
ParseSpecifierQualifierList(DS, AS_none, DSC_type_specifier);
ParseSpecifierQualifierList(DS, AS_none, DeclSpecContext::DSC_type_specifier);
DS.Finish(Actions, Actions.getASTContext().getPrintingPolicy());
return false;
}
@ -2033,9 +2034,9 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
TemplateTy Template;
TemplateNameKind TNK = TNK_Non_template;
switch (Id.getKind()) {
case UnqualifiedId::IK_Identifier:
case UnqualifiedId::IK_OperatorFunctionId:
case UnqualifiedId::IK_LiteralOperatorId:
case UnqualifiedIdKind::IK_Identifier:
case UnqualifiedIdKind::IK_OperatorFunctionId:
case UnqualifiedIdKind::IK_LiteralOperatorId:
if (AssumeTemplateId) {
// We defer the injected-class-name checks until we've found whether
// this template-id is used to form a nested-name-specifier or not.
@ -2058,11 +2059,11 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
// parse correctly as a template, so suggest the keyword 'template'
// before 'getAs' and treat this as a dependent template name.
std::string Name;
if (Id.getKind() == UnqualifiedId::IK_Identifier)
if (Id.getKind() == UnqualifiedIdKind::IK_Identifier)
Name = Id.Identifier->getName();
else {
Name = "operator ";
if (Id.getKind() == UnqualifiedId::IK_OperatorFunctionId)
if (Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId)
Name += getOperatorSpelling(Id.OperatorFunctionId.Operator);
else
Name += Id.Identifier->getName();
@ -2079,7 +2080,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
}
break;
case UnqualifiedId::IK_ConstructorName: {
case UnqualifiedIdKind::IK_ConstructorName: {
UnqualifiedId TemplateName;
bool MemberOfUnknownSpecialization;
TemplateName.setIdentifier(Name, NameLoc);
@ -2090,7 +2091,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
break;
}
case UnqualifiedId::IK_DestructorName: {
case UnqualifiedIdKind::IK_DestructorName: {
UnqualifiedId TemplateName;
bool MemberOfUnknownSpecialization;
TemplateName.setIdentifier(Name, NameLoc);
@ -2129,16 +2130,18 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
true, LAngleLoc, TemplateArgs, RAngleLoc))
return true;
if (Id.getKind() == UnqualifiedId::IK_Identifier ||
Id.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) {
if (Id.getKind() == UnqualifiedIdKind::IK_Identifier ||
Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId ||
Id.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) {
// Form a parsed representation of the template-id to be stored in the
// UnqualifiedId.
// FIXME: Store name for literal operator too.
IdentifierInfo *TemplateII =
Id.getKind() == UnqualifiedId::IK_Identifier ? Id.Identifier : nullptr;
OverloadedOperatorKind OpKind = Id.getKind() == UnqualifiedId::IK_Identifier
Id.getKind() == UnqualifiedIdKind::IK_Identifier ? Id.Identifier
: nullptr;
OverloadedOperatorKind OpKind =
Id.getKind() == UnqualifiedIdKind::IK_Identifier
? OO_None
: Id.OperatorFunctionId.Operator;
@ -2162,7 +2165,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
if (Type.isInvalid())
return true;
if (Id.getKind() == UnqualifiedId::IK_ConstructorName)
if (Id.getKind() == UnqualifiedIdKind::IK_ConstructorName)
Id.setConstructorName(Type.get(), NameLoc, RAngleLoc);
else
Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc);
@ -2395,7 +2398,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
// Parse the conversion-declarator, which is merely a sequence of
// ptr-operators.
Declarator D(DS, Declarator::ConversionIdContext);
Declarator D(DS, DeclaratorContext::ConversionIdContext);
ParseDeclaratorInternal(D, /*DirectDeclParser=*/nullptr);
// Finish up the type.
@ -2556,8 +2559,8 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
//
// template-id:
// operator-function-id < template-argument-list[opt] >
if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId ||
Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) &&
if ((Result.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId ||
Result.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) &&
(TemplateSpecified || Tok.is(tok::less)))
return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc,
nullptr, SourceLocation(),
@ -2696,7 +2699,7 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
SourceRange TypeIdParens;
DeclSpec DS(AttrFactory);
Declarator DeclaratorInfo(DS, Declarator::CXXNewContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::CXXNewContext);
if (Tok.is(tok::l_paren)) {
// If it turns out to be a placement, we change the type location.
BalancedDelimiterTracker T(*this, tok::l_paren);
@ -3172,7 +3175,7 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
if (ParseAs >= CompoundLiteral) {
// Parse the type declarator.
DeclSpec DS(AttrFactory);
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
{
ColonProtectionRAIIObject InnerColonProtection(*this);
ParseSpecifierQualifierList(DS);

View File

@ -1140,14 +1140,14 @@ bool Parser::isTokIdentifier_in() const {
/// 'null_unspecified'
///
void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
Declarator::TheContext Context) {
assert(Context == Declarator::ObjCParameterContext ||
Context == Declarator::ObjCResultContext);
DeclaratorContext Context) {
assert(Context == DeclaratorContext::ObjCParameterContext ||
Context == DeclaratorContext::ObjCResultContext);
while (1) {
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCPassingType(getCurScope(), DS,
Context == Declarator::ObjCParameterContext);
Context == DeclaratorContext::ObjCParameterContext);
return cutOffParsing();
}
@ -1242,12 +1242,12 @@ static void takeDeclAttributes(ParsedAttributes &attrs,
/// '(' objc-type-qualifiers[opt] ')'
///
ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
Declarator::TheContext context,
DeclaratorContext context,
ParsedAttributes *paramAttrs) {
assert(context == Declarator::ObjCParameterContext ||
context == Declarator::ObjCResultContext);
assert(context == DeclaratorContext::ObjCParameterContext ||
context == DeclaratorContext::ObjCResultContext);
assert((paramAttrs != nullptr) ==
(context == Declarator::ObjCParameterContext));
(context == DeclaratorContext::ObjCParameterContext));
assert(Tok.is(tok::l_paren) && "expected (");
@ -1265,9 +1265,9 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
// Parse an abstract declarator.
DeclSpec declSpec(AttrFactory);
declSpec.setObjCQualifiers(&DS);
DeclSpecContext dsContext = DSC_normal;
if (context == Declarator::ObjCResultContext)
dsContext = DSC_objc_method_result;
DeclSpecContext dsContext = DeclSpecContext::DSC_normal;
if (context == DeclaratorContext::ObjCResultContext)
dsContext = DeclSpecContext::DSC_objc_method_result;
ParseSpecifierQualifierList(declSpec, AS_none, dsContext);
Declarator declarator(declSpec, context);
ParseDeclarator(declarator);
@ -1288,7 +1288,7 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
// If we're parsing a parameter, steal all the decl attributes
// and add them to the decl spec.
if (context == Declarator::ObjCParameterContext)
if (context == DeclaratorContext::ObjCParameterContext)
takeDeclAttributes(*paramAttrs, declarator);
}
}
@ -1352,7 +1352,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
ParsedType ReturnType;
ObjCDeclSpec DSRet;
if (Tok.is(tok::l_paren))
ReturnType = ParseObjCTypeName(DSRet, Declarator::ObjCResultContext,
ReturnType = ParseObjCTypeName(DSRet, DeclaratorContext::ObjCResultContext,
nullptr);
// If attributes exist before the method, parse them.
@ -1416,7 +1416,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
ArgInfo.Type = nullptr;
if (Tok.is(tok::l_paren)) // Parse the argument type if present.
ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec,
Declarator::ObjCParameterContext,
DeclaratorContext::ObjCParameterContext,
&paramAttrs);
// If attributes exist before the argument name, parse them.
@ -1494,7 +1494,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
DeclSpec DS(AttrFactory);
ParseDeclarationSpecifiers(DS);
// Parse the declarator.
Declarator ParmDecl(DS, Declarator::PrototypeContext);
Declarator ParmDecl(DS, DeclaratorContext::PrototypeContext);
ParseDeclarator(ParmDecl);
IdentifierInfo *ParmII = ParmDecl.getIdentifier();
Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
@ -1703,7 +1703,7 @@ void Parser::parseObjCTypeArgsOrProtocolQualifiers(
typeArg, Actions.getASTContext().getPrintingPolicy());
// Form a declarator to turn this into a type.
Declarator D(DS, Declarator::TypeNameContext);
Declarator D(DS, DeclaratorContext::TypeNameContext);
TypeResult fullTypeArg = Actions.ActOnTypeName(getCurScope(), D);
if (fullTypeArg.isUsable()) {
typeArgs.push_back(fullTypeArg.get());
@ -2543,7 +2543,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
if (Tok.isNot(tok::ellipsis)) {
DeclSpec DS(AttrFactory);
ParseDeclarationSpecifiers(DS);
Declarator ParmDecl(DS, Declarator::ObjCCatchContext);
Declarator ParmDecl(DS, DeclaratorContext::ObjCCatchContext);
ParseDeclarator(ParmDecl);
// Inform the actions module about the declarator, so it
@ -2945,7 +2945,7 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
// We have a class message. Turn the simple-type-specifier or
// typename-specifier we parsed into a type and parse the
// remainder of the class message.
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext);
TypeResult Type = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
if (Type.isInvalid())
return true;

View File

@ -250,7 +250,8 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
do {
ColonProtectionRAIIObject ColonRAII(*this);
SourceRange Range;
TypeResult TR = ParseTypeName(&Range, Declarator::PrototypeContext, AS);
TypeResult TR =
ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS);
if (TR.isUsable()) {
auto ReductionType =
Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);

View File

@ -211,7 +211,7 @@ Parser::ParseStatementOrDeclarationAfterAttributes(StmtVector &Stmts,
Allowed == ACK_Any) &&
isDeclarationStatement()) {
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
DeclGroupPtrTy Decl = ParseDeclaration(Declarator::BlockContext,
DeclGroupPtrTy Decl = ParseDeclaration(DeclaratorContext::BlockContext,
DeclEnd, Attrs);
return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
}
@ -1021,8 +1021,8 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
ExtensionRAIIObject O(Diags);
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
DeclGroupPtrTy Res = ParseDeclaration(Declarator::BlockContext, DeclEnd,
attrs);
DeclGroupPtrTy Res =
ParseDeclaration(DeclaratorContext::BlockContext, DeclEnd, attrs);
R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
} else {
// Otherwise this was a unary __extension__ marker.
@ -1631,7 +1631,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
DeclGroupPtrTy DG = ParseSimpleDeclaration(
Declarator::ForContext, DeclEnd, attrs, false,
DeclaratorContext::ForContext, DeclEnd, attrs, false,
MightBeForRangeStmt ? &ForRangeInit : nullptr);
FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
if (ForRangeInit.ParsedForRangeDecl()) {
@ -2181,7 +2181,7 @@ StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {
if (ParseCXXTypeSpecifierSeq(DS))
return StmtError();
Declarator ExDecl(DS, Declarator::CXXCatchContext);
Declarator ExDecl(DS, DeclaratorContext::CXXCatchContext);
ParseDeclarator(ExDecl);
ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl);
} else

View File

@ -24,7 +24,7 @@ using namespace clang;
/// \brief Parse a template declaration, explicit instantiation, or
/// explicit specialization.
Decl *
Parser::ParseDeclarationStartingWithTemplate(unsigned Context,
Parser::ParseDeclarationStartingWithTemplate(DeclaratorContext Context,
SourceLocation &DeclEnd,
AccessSpecifier AS,
AttributeList *AccessAttrs) {
@ -57,7 +57,7 @@ Parser::ParseDeclarationStartingWithTemplate(unsigned Context,
/// explicit-specialization: [ C++ temp.expl.spec]
/// 'template' '<' '>' declaration
Decl *
Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
Parser::ParseTemplateDeclarationOrSpecialization(DeclaratorContext Context,
SourceLocation &DeclEnd,
AccessSpecifier AS,
AttributeList *AccessAttrs) {
@ -169,7 +169,7 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
/// \returns the new declaration.
Decl *
Parser::ParseSingleDeclarationAfterTemplate(
unsigned Context,
DeclaratorContext Context,
const ParsedTemplateInfo &TemplateInfo,
ParsingDeclRAIIObject &DiagsFromTParams,
SourceLocation &DeclEnd,
@ -186,7 +186,7 @@ Parser::ParseSingleDeclarationAfterTemplate(
return ParseStaticAssertDeclaration(DeclEnd);
}
if (Context == Declarator::MemberContext) {
if (Context == DeclaratorContext::MemberContext) {
// We are parsing a member template.
ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
&DiagsFromTParams);
@ -234,7 +234,7 @@ Parser::ParseSingleDeclarationAfterTemplate(
DS.takeAttributesFrom(prefixAttrs);
// Parse the declarator.
ParsingDeclarator DeclaratorInfo(*this, DS, (Declarator::TheContext)Context);
ParsingDeclarator DeclaratorInfo(*this, DS, (DeclaratorContext)Context);
ParseDeclarator(DeclaratorInfo);
// Error parsing the declarator?
if (!DeclaratorInfo.hasName()) {
@ -255,7 +255,7 @@ Parser::ParseSingleDeclarationAfterTemplate(
// Function definitions are only allowed at file scope and in C++ classes.
// The C++ inline method definition case is handled elsewhere, so we only
// need to handle the file scope definition case.
if (Context != Declarator::FileContext) {
if (Context != DeclaratorContext::FileContext) {
Diag(Tok, diag::err_function_definition_not_allowed);
SkipMalformedDecl();
return nullptr;
@ -271,7 +271,8 @@ Parser::ParseSingleDeclarationAfterTemplate(
}
if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
if (DeclaratorInfo.getName().getKind() != UnqualifiedId::IK_TemplateId) {
if (DeclaratorInfo.getName().getKind() !=
UnqualifiedIdKind::IK_TemplateId) {
// If the declarator-id is not a template-id, issue a diagnostic and
// recover by ignoring the 'template' keyword.
Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
@ -369,7 +370,7 @@ bool Parser::ParseTemplateParameters(
/// template-parameter
/// template-parameter-list ',' template-parameter
bool
Parser::ParseTemplateParameterList(unsigned Depth,
Parser::ParseTemplateParameterList(const unsigned Depth,
SmallVectorImpl<NamedDecl*> &TemplateParams) {
while (1) {
@ -546,7 +547,7 @@ NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
ParsedType DefaultArg;
if (TryConsumeToken(tok::equal, EqualLoc))
DefaultArg = ParseTypeName(/*Range=*/nullptr,
Declarator::TemplateTypeArgContext).get();
DeclaratorContext::TemplateTypeArgContext).get();
return Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, EllipsisLoc,
KeyLoc, ParamName, NameLoc, Depth, Position,
@ -676,10 +677,10 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
// declarators (parts of declarators?) are accepted for parameters.
DeclSpec DS(AttrFactory);
ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
DSC_template_param);
DeclSpecContext::DSC_template_param);
// Parse this as a typename.
Declarator ParamDecl(DS, Declarator::TemplateParamContext);
Declarator ParamDecl(DS, DeclaratorContext::TemplateParamContext);
ParseDeclarator(ParamDecl);
if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {
Diag(Tok.getLocation(), diag::err_expected_template_parameter);
@ -1015,12 +1016,12 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
Tok.setKind(tok::annot_template_id);
IdentifierInfo *TemplateII =
TemplateName.getKind() == UnqualifiedId::IK_Identifier
TemplateName.getKind() == UnqualifiedIdKind::IK_Identifier
? TemplateName.Identifier
: nullptr;
OverloadedOperatorKind OpKind =
TemplateName.getKind() == UnqualifiedId::IK_Identifier
TemplateName.getKind() == UnqualifiedIdKind::IK_Identifier
? OO_None
: TemplateName.OperatorFunctionId.Operator;
@ -1193,8 +1194,8 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() {
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
if (isCXXTypeId(TypeIdAsTemplateArgument)) {
SourceLocation Loc = Tok.getLocation();
TypeResult TypeArg = ParseTypeName(/*Range=*/nullptr,
Declarator::TemplateTypeArgContext);
TypeResult TypeArg = ParseTypeName(
/*Range=*/nullptr, DeclaratorContext::TemplateTypeArgContext);
if (TypeArg.isInvalid())
return ParsedTemplateArgument();
@ -1297,7 +1298,7 @@ Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
/// 'extern' [opt] 'template' declaration
///
/// Note that the 'extern' is a GNU extension and C++11 feature.
Decl *Parser::ParseExplicitInstantiation(unsigned Context,
Decl *Parser::ParseExplicitInstantiation(DeclaratorContext Context,
SourceLocation ExternLoc,
SourceLocation TemplateLoc,
SourceLocation &DeclEnd,

View File

@ -783,7 +783,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
// A function definition cannot start with any of these keywords.
{
SourceLocation DeclEnd;
return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs);
return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs);
}
case tok::kw_static:
@ -793,7 +793,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
<< 0;
SourceLocation DeclEnd;
return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs);
return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs);
}
goto dont_know;
@ -804,7 +804,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
// Inline namespaces. Allowed as an extension even in C++03.
if (NextKind == tok::kw_namespace) {
SourceLocation DeclEnd;
return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs);
return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs);
}
// Parse (then ignore) 'inline' prior to a template instantiation. This is
@ -813,7 +813,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
<< 1;
SourceLocation DeclEnd;
return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs);
return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs);
}
}
goto dont_know;
@ -828,7 +828,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc);
SourceLocation DeclEnd;
return Actions.ConvertDeclToDeclGroup(
ParseExplicitInstantiation(Declarator::FileContext,
ParseExplicitInstantiation(DeclaratorContext::FileContext,
ExternLoc, TemplateLoc, DeclEnd));
}
goto dont_know;
@ -919,12 +919,13 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
AccessSpecifier AS) {
MaybeParseMicrosoftAttributes(DS.getAttributes());
// Parse the common declaration-specifiers piece.
ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level);
ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS,
DeclSpecContext::DSC_top_level);
// If we had a free-standing type definition with a missing semicolon, we
// may get this far before the problem becomes obvious.
if (DS.hasTagDefinition() &&
DiagnoseMissingSemiAfterTagDefinition(DS, AS, DSC_top_level))
if (DS.hasTagDefinition() && DiagnoseMissingSemiAfterTagDefinition(
DS, AS, DeclSpecContext::DSC_top_level))
return nullptr;
// C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
@ -1004,11 +1005,11 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
if (getLangOpts().CPlusPlus && isTokenStringLiteral() &&
DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
Decl *TheDecl = ParseLinkage(DS, Declarator::FileContext);
Decl *TheDecl = ParseLinkage(DS, DeclaratorContext::FileContext);
return Actions.ConvertDeclToDeclGroup(TheDecl);
}
return ParseDeclGroup(DS, Declarator::FileContext);
return ParseDeclGroup(DS, DeclaratorContext::FileContext);
}
Parser::DeclGroupPtrTy
@ -1313,7 +1314,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
}
// Parse the first declarator attached to this declspec.
Declarator ParmDeclarator(DS, Declarator::KNRTypeListContext);
Declarator ParmDeclarator(DS, DeclaratorContext::KNRTypeListContext);
ParseDeclarator(ParmDeclarator);
// Handle the full declarator list.

View File

@ -30,7 +30,7 @@ using namespace clang;
void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
assert(TemplateId && "NULL template-id annotation?");
Kind = IK_TemplateId;
Kind = UnqualifiedIdKind::IK_TemplateId;
this->TemplateId = TemplateId;
StartLocation = TemplateId->TemplateNameLoc;
EndLocation = TemplateId->RAngleLoc;
@ -38,7 +38,7 @@ void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
assert(TemplateId && "NULL template-id annotation?");
Kind = IK_ConstructorTemplateId;
Kind = UnqualifiedIdKind::IK_ConstructorTemplateId;
this->TemplateId = TemplateId;
StartLocation = TemplateId->TemplateNameLoc;
EndLocation = TemplateId->RAngleLoc;
@ -387,16 +387,16 @@ bool Declarator::isDeclarationOfFunction() const {
}
bool Declarator::isStaticMember() {
assert(getContext() == MemberContext);
assert(getContext() == DeclaratorContext::MemberContext);
return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||
(getName().Kind == UnqualifiedId::IK_OperatorFunctionId &&
(getName().Kind == UnqualifiedIdKind::IK_OperatorFunctionId &&
CXXMethodDecl::isStaticOverloadedOperator(
getName().OperatorFunctionId.Operator));
}
bool Declarator::isCtorOrDtor() {
return (getName().getKind() == UnqualifiedId::IK_ConstructorName) ||
(getName().getKind() == UnqualifiedId::IK_DestructorName);
return (getName().getKind() == UnqualifiedIdKind::IK_ConstructorName) ||
(getName().getKind() == UnqualifiedIdKind::IK_DestructorName);
}
bool DeclSpec::hasTagDefinition() const {
@ -1281,7 +1281,7 @@ bool DeclSpec::isMissingDeclaratorOk() {
void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc,
OverloadedOperatorKind Op,
SourceLocation SymbolLocations[3]) {
Kind = IK_OperatorFunctionId;
Kind = UnqualifiedIdKind::IK_OperatorFunctionId;
StartLocation = OperatorLoc;
EndLocation = OperatorLoc;
OperatorFunctionId.Operator = Op;

View File

@ -4171,8 +4171,8 @@ void Sema::CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D,
AddTypeQualifierResults(DS, Results, LangOpts);
if (LangOpts.CPlusPlus11) {
Results.AddResult("noexcept");
if (D.getContext() == Declarator::MemberContext && !D.isCtorOrDtor() &&
!D.isStaticMember()) {
if (D.getContext() == DeclaratorContext::MemberContext &&
!D.isCtorOrDtor() && !D.isStaticMember()) {
if (!VS || !VS->isFinalSpecified())
Results.AddResult("final");
if (!VS || !VS->isOverrideSpecified())

View File

@ -4746,7 +4746,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
}
// Mock up a declarator.
Declarator Dc(DS, Declarator::MemberContext);
Declarator Dc(DS, DeclaratorContext::MemberContext);
TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S);
assert(TInfo && "couldn't build declarator info for anonymous struct/union");
@ -4843,7 +4843,7 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
assert(Record && "expected a record!");
// Mock up a declarator.
Declarator Dc(DS, Declarator::TypeNameContext);
Declarator Dc(DS, DeclaratorContext::TypeNameContext);
TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S);
assert(TInfo && "couldn't build declarator info for anonymous struct");
@ -4897,13 +4897,13 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
switch (Name.getKind()) {
case UnqualifiedId::IK_ImplicitSelfParam:
case UnqualifiedId::IK_Identifier:
case UnqualifiedIdKind::IK_ImplicitSelfParam:
case UnqualifiedIdKind::IK_Identifier:
NameInfo.setName(Name.Identifier);
NameInfo.setLoc(Name.StartLocation);
return NameInfo;
case UnqualifiedId::IK_DeductionGuideName: {
case UnqualifiedIdKind::IK_DeductionGuideName: {
// C++ [temp.deduct.guide]p3:
// The simple-template-id shall name a class template specialization.
// The template-name shall be the same identifier as the template-name
@ -4931,7 +4931,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
return NameInfo;
}
case UnqualifiedId::IK_OperatorFunctionId:
case UnqualifiedIdKind::IK_OperatorFunctionId:
NameInfo.setName(Context.DeclarationNames.getCXXOperatorName(
Name.OperatorFunctionId.Operator));
NameInfo.setLoc(Name.StartLocation);
@ -4941,14 +4941,14 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
= Name.EndLocation.getRawEncoding();
return NameInfo;
case UnqualifiedId::IK_LiteralOperatorId:
case UnqualifiedIdKind::IK_LiteralOperatorId:
NameInfo.setName(Context.DeclarationNames.getCXXLiteralOperatorName(
Name.Identifier));
NameInfo.setLoc(Name.StartLocation);
NameInfo.setCXXLiteralOperatorNameLoc(Name.EndLocation);
return NameInfo;
case UnqualifiedId::IK_ConversionFunctionId: {
case UnqualifiedIdKind::IK_ConversionFunctionId: {
TypeSourceInfo *TInfo;
QualType Ty = GetTypeFromParser(Name.ConversionFunctionId, &TInfo);
if (Ty.isNull())
@ -4960,7 +4960,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
return NameInfo;
}
case UnqualifiedId::IK_ConstructorName: {
case UnqualifiedIdKind::IK_ConstructorName: {
TypeSourceInfo *TInfo;
QualType Ty = GetTypeFromParser(Name.ConstructorName, &TInfo);
if (Ty.isNull())
@ -4972,7 +4972,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
return NameInfo;
}
case UnqualifiedId::IK_ConstructorTemplateId: {
case UnqualifiedIdKind::IK_ConstructorTemplateId: {
// In well-formed code, we can only have a constructor
// template-id that refers to the current context, so go there
// to find the actual type being constructed.
@ -4995,7 +4995,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
return NameInfo;
}
case UnqualifiedId::IK_DestructorName: {
case UnqualifiedIdKind::IK_DestructorName: {
TypeSourceInfo *TInfo;
QualType Ty = GetTypeFromParser(Name.DestructorName, &TInfo);
if (Ty.isNull())
@ -5007,7 +5007,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
return NameInfo;
}
case UnqualifiedId::IK_TemplateId: {
case UnqualifiedIdKind::IK_TemplateId: {
TemplateName TName = Name.TemplateId->Template.get();
SourceLocation TNameLoc = Name.TemplateId->TemplateNameLoc;
return Context.getNameForTemplate(TName, TNameLoc);
@ -5670,8 +5670,8 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr)
<< 1;
if (D.getName().Kind != UnqualifiedId::IK_Identifier) {
if (D.getName().Kind == UnqualifiedId::IK_DeductionGuideName)
if (D.getName().Kind != UnqualifiedIdKind::IK_Identifier) {
if (D.getName().Kind == UnqualifiedIdKind::IK_DeductionGuideName)
Diag(D.getName().StartLocation,
diag::err_deduction_guide_invalid_specifier)
<< "typedef";
@ -6425,7 +6425,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
TemplateParams = MatchTemplateParametersToScopeSpecifier(
D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
D.getCXXScopeSpec(),
D.getName().getKind() == UnqualifiedId::IK_TemplateId
D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId
? D.getName().TemplateId
: nullptr,
TemplateParamLists,
@ -6433,7 +6433,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
if (TemplateParams) {
if (!TemplateParams->size() &&
D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {
// There is an extraneous 'template<>' for this variable. Complain
// about it, but allow the declaration of the variable.
Diag(TemplateParams->getTemplateLoc(),
@ -6443,7 +6443,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
TemplateParams->getRAngleLoc());
TemplateParams = nullptr;
} else {
if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
if (D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId) {
// This is an explicit specialization or a partial specialization.
// FIXME: Check that we can declare a specialization here.
IsVariableTemplateSpecialization = true;
@ -6464,8 +6464,8 @@ NamedDecl *Sema::ActOnVariableDeclarator(
}
}
} else {
assert(
(Invalid || D.getName().getKind() != UnqualifiedId::IK_TemplateId) &&
assert((Invalid ||
D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) &&
"should have a 'template<>' for this decl");
}
@ -8261,7 +8261,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
MatchTemplateParametersToScopeSpecifier(
D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
D.getCXXScopeSpec(),
D.getName().getKind() == UnqualifiedId::IK_TemplateId
D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId
? D.getName().TemplateId
: nullptr,
TemplateParamLists, isFriend, isMemberSpecialization,
@ -8318,7 +8318,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// and clearly the user wants a template specialization. So
// we need to insert '<>' after the name.
SourceLocation InsertLoc;
if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
if (D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {
InsertLoc = D.getName().getSourceRange().getEnd();
InsertLoc = getLocForEndOfToken(InsertLoc);
}
@ -8719,7 +8719,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// If the declarator is a template-id, translate the parser's template
// argument list into our AST format.
if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
if (D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId) {
TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
@ -10893,7 +10893,7 @@ Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
DS.SetTypeSpecType(DeclSpec::TST_auto, IdentLoc, PrevSpec, DiagID,
getPrintingPolicy());
Declarator D(DS, Declarator::ForContext);
Declarator D(DS, DeclaratorContext::ForContext);
D.SetIdentifier(Ident, IdentLoc);
D.takeAttributes(Attrs, AttrEnd);
@ -11809,7 +11809,7 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
// Use the identifier location for the type source range.
DS.SetRangeStart(FTI.Params[i].IdentLoc);
DS.SetRangeEnd(FTI.Params[i].IdentLoc);
Declarator ParamD(DS, Declarator::KNRTypeListContext);
Declarator ParamD(DS, DeclaratorContext::KNRTypeListContext);
ParamD.SetIdentifier(FTI.Params[i].Ident, FTI.Params[i].IdentLoc);
FTI.Params[i].Param = ActOnParamDeclarator(S, ParamD);
}
@ -12574,7 +12574,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
(void)Error; // Silence warning.
assert(!Error && "Error setting up implicit decl!");
SourceLocation NoLoc;
Declarator D(DS, Declarator::BlockContext);
Declarator D(DS, DeclaratorContext::BlockContext);
D.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/false,
/*IsAmbiguous=*/false,
/*LParenLoc=*/NoLoc,

View File

@ -712,7 +712,7 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
Diag(Decomp.getLSquareLoc(),
!getLangOpts().CPlusPlus17
? diag::ext_decomp_decl
: D.getContext() == Declarator::ConditionContext
: D.getContext() == DeclaratorContext::ConditionContext
? diag::ext_decomp_decl_cond
: diag::warn_cxx14_compat_decomp_decl)
<< Decomp.getSourceRange();
@ -8986,15 +8986,15 @@ Decl *Sema::ActOnUsingDeclaration(Scope *S,
}
switch (Name.getKind()) {
case UnqualifiedId::IK_ImplicitSelfParam:
case UnqualifiedId::IK_Identifier:
case UnqualifiedId::IK_OperatorFunctionId:
case UnqualifiedId::IK_LiteralOperatorId:
case UnqualifiedId::IK_ConversionFunctionId:
case UnqualifiedIdKind::IK_ImplicitSelfParam:
case UnqualifiedIdKind::IK_Identifier:
case UnqualifiedIdKind::IK_OperatorFunctionId:
case UnqualifiedIdKind::IK_LiteralOperatorId:
case UnqualifiedIdKind::IK_ConversionFunctionId:
break;
case UnqualifiedId::IK_ConstructorName:
case UnqualifiedId::IK_ConstructorTemplateId:
case UnqualifiedIdKind::IK_ConstructorName:
case UnqualifiedIdKind::IK_ConstructorTemplateId:
// C++11 inheriting constructors.
Diag(Name.getLocStart(),
getLangOpts().CPlusPlus11 ?
@ -9006,17 +9006,17 @@ Decl *Sema::ActOnUsingDeclaration(Scope *S,
return nullptr;
case UnqualifiedId::IK_DestructorName:
case UnqualifiedIdKind::IK_DestructorName:
Diag(Name.getLocStart(), diag::err_using_decl_destructor)
<< SS.getRange();
return nullptr;
case UnqualifiedId::IK_TemplateId:
case UnqualifiedIdKind::IK_TemplateId:
Diag(Name.getLocStart(), diag::err_using_decl_template_id)
<< SourceRange(Name.TemplateId->LAngleLoc, Name.TemplateId->RAngleLoc);
return nullptr;
case UnqualifiedId::IK_DeductionGuideName:
case UnqualifiedIdKind::IK_DeductionGuideName:
llvm_unreachable("cannot parse qualified deduction guide name");
}
@ -10040,7 +10040,7 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S,
Previous.clear();
}
assert(Name.Kind == UnqualifiedId::IK_Identifier &&
assert(Name.Kind == UnqualifiedIdKind::IK_Identifier &&
"name in alias declaration must be an identifier");
TypeAliasDecl *NewTD = TypeAliasDecl::Create(Context, CurContext, UsingLoc,
Name.StartLocation,
@ -12215,30 +12215,27 @@ void Sema::DefineImplicitLambdaToFunctionPointerConversion(
SourceLocation CurrentLocation,
CXXConversionDecl *Conv) {
SynthesizedFunctionScope Scope(*this, Conv);
assert(!Conv->getReturnType()->isUndeducedType());
CXXRecordDecl *Lambda = Conv->getParent();
CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator();
// If we are defining a specialization of a conversion to function-ptr
// cache the deduced template arguments for this specialization
// so that we can use them to retrieve the corresponding call-operator
// and static-invoker.
const TemplateArgumentList *DeducedTemplateArgs = nullptr;
FunctionDecl *CallOp = Lambda->getLambdaCallOperator();
FunctionDecl *Invoker = Lambda->getLambdaStaticInvoker();
// Retrieve the corresponding call-operator specialization.
if (Lambda->isGenericLambda()) {
assert(Conv->isFunctionTemplateSpecialization());
FunctionTemplateDecl *CallOpTemplate =
CallOp->getDescribedFunctionTemplate();
DeducedTemplateArgs = Conv->getTemplateSpecializationArgs();
void *InsertPos = nullptr;
FunctionDecl *CallOpSpec = CallOpTemplate->findSpecialization(
DeducedTemplateArgs->asArray(),
InsertPos);
assert(CallOpSpec &&
"Conversion operator must have a corresponding call operator");
CallOp = cast<CXXMethodDecl>(CallOpSpec);
if (auto *TemplateArgs = Conv->getTemplateSpecializationArgs()) {
CallOp = InstantiateFunctionDeclaration(
CallOp->getDescribedFunctionTemplate(), TemplateArgs, CurrentLocation);
if (!CallOp)
return;
Invoker = InstantiateFunctionDeclaration(
Invoker->getDescribedFunctionTemplate(), TemplateArgs, CurrentLocation);
if (!Invoker)
return;
}
if (CallOp->isInvalidDecl())
return;
// Mark the call operator referenced (and add to pending instantiations
// if necessary).
// For both the conversion and static-invoker template specializations
@ -12246,22 +12243,14 @@ void Sema::DefineImplicitLambdaToFunctionPointerConversion(
// to the PendingInstantiations.
MarkFunctionReferenced(CurrentLocation, CallOp);
// Retrieve the static invoker...
CXXMethodDecl *Invoker = Lambda->getLambdaStaticInvoker();
// ... and get the corresponding specialization for a generic lambda.
if (Lambda->isGenericLambda()) {
assert(DeducedTemplateArgs &&
"Must have deduced template arguments from Conversion Operator");
FunctionTemplateDecl *InvokeTemplate =
Invoker->getDescribedFunctionTemplate();
void *InsertPos = nullptr;
FunctionDecl *InvokeSpec = InvokeTemplate->findSpecialization(
DeducedTemplateArgs->asArray(),
InsertPos);
assert(InvokeSpec &&
"Must have a corresponding static invoker specialization");
Invoker = cast<CXXMethodDecl>(InvokeSpec);
}
// Fill in the __invoke function with a dummy implementation. IR generation
// will fill in the actual details. Update its type in case it contained
// an 'auto'.
Invoker->markUsed(Context);
Invoker->setReferenced();
Invoker->setType(Conv->getReturnType()->getPointeeType());
Invoker->setBody(new (Context) CompoundStmt(Conv->getLocation()));
// Construct the body of the conversion function { return __invoke; }.
Expr *FunctionRef = BuildDeclRefExpr(Invoker, Invoker->getType(),
VK_LValue, Conv->getLocation()).get();
@ -12269,16 +12258,9 @@ void Sema::DefineImplicitLambdaToFunctionPointerConversion(
Stmt *Return = BuildReturnStmt(Conv->getLocation(), FunctionRef).get();
Conv->setBody(CompoundStmt::Create(Context, Return, Conv->getLocation(),
Conv->getLocation()));
Conv->markUsed(Context);
Conv->setReferenced();
// Fill in the __invoke function with a dummy implementation. IR generation
// will fill in the actual details.
Invoker->markUsed(Context);
Invoker->setReferenced();
Invoker->setBody(new (Context) CompoundStmt(Conv->getLocation()));
if (ASTMutationListener *L = getASTMutationListener()) {
L->CompletedImplicitDefinition(Conv);
L->CompletedImplicitDefinition(Invoker);
@ -13625,7 +13607,7 @@ Decl *Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
// Try to convert the decl specifier to a type. This works for
// friend templates because ActOnTag never produces a ClassTemplateDecl
// for a TUK_Friend.
Declarator TheDeclarator(DS, Declarator::MemberContext);
Declarator TheDeclarator(DS, DeclaratorContext::MemberContext);
TypeSourceInfo *TSI = GetTypeForDeclarator(TheDeclarator, S);
QualType T = TSI->getType();
if (TheDeclarator.isInvalidType())
@ -13799,7 +13781,8 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
// elaborated-type-specifier, the lookup to determine whether
// the entity has been previously declared shall not consider
// any scopes outside the innermost enclosing namespace.
bool isTemplateId = D.getName().getKind() == UnqualifiedId::IK_TemplateId;
bool isTemplateId =
D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId;
// Find the appropriate context according to the above.
DC = CurContext;
@ -13910,24 +13893,24 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
if (!DC->isRecord()) {
int DiagArg = -1;
switch (D.getName().getKind()) {
case UnqualifiedId::IK_ConstructorTemplateId:
case UnqualifiedId::IK_ConstructorName:
case UnqualifiedIdKind::IK_ConstructorTemplateId:
case UnqualifiedIdKind::IK_ConstructorName:
DiagArg = 0;
break;
case UnqualifiedId::IK_DestructorName:
case UnqualifiedIdKind::IK_DestructorName:
DiagArg = 1;
break;
case UnqualifiedId::IK_ConversionFunctionId:
case UnqualifiedIdKind::IK_ConversionFunctionId:
DiagArg = 2;
break;
case UnqualifiedId::IK_DeductionGuideName:
case UnqualifiedIdKind::IK_DeductionGuideName:
DiagArg = 3;
break;
case UnqualifiedId::IK_Identifier:
case UnqualifiedId::IK_ImplicitSelfParam:
case UnqualifiedId::IK_LiteralOperatorId:
case UnqualifiedId::IK_OperatorFunctionId:
case UnqualifiedId::IK_TemplateId:
case UnqualifiedIdKind::IK_Identifier:
case UnqualifiedIdKind::IK_ImplicitSelfParam:
case UnqualifiedIdKind::IK_LiteralOperatorId:
case UnqualifiedIdKind::IK_OperatorFunctionId:
case UnqualifiedIdKind::IK_TemplateId:
break;
}
// This implies that it has to be an operator or function.

View File

@ -1538,7 +1538,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers(
DS.SetRangeEnd(loc);
// Form the declarator.
Declarator D(DS, Declarator::TypeNameContext);
Declarator D(DS, DeclaratorContext::TypeNameContext);
// If we have a typedef of an Objective-C class type that is missing a '*',
// add the '*'.

View File

@ -1711,7 +1711,7 @@ Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id,
TemplateArgumentListInfo &Buffer,
DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *&TemplateArgs) {
if (Id.getKind() == UnqualifiedId::IK_TemplateId) {
if (Id.getKind() == UnqualifiedIdKind::IK_TemplateId) {
Buffer.setLAngleLoc(Id.TemplateId->LAngleLoc);
Buffer.setRAngleLoc(Id.TemplateId->RAngleLoc);
@ -2071,8 +2071,9 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
// Perform the required lookup.
LookupResult R(*this, NameInfo,
(Id.getKind() == UnqualifiedId::IK_ImplicitSelfParam)
? LookupObjCImplicitSelfParam : LookupOrdinaryName);
(Id.getKind() == UnqualifiedIdKind::IK_ImplicitSelfParam)
? LookupObjCImplicitSelfParam
: LookupOrdinaryName);
if (TemplateArgs) {
// Lookup the template name again to correctly establish the context in
// which it was found. This is really unfortunate as we already did the
@ -2243,7 +2244,7 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
// In C++1y, if this is a variable template id, then check it
// in BuildTemplateIdExpr().
// The single lookup result must be a variable template declaration.
if (Id.getKind() == UnqualifiedId::IK_TemplateId && Id.TemplateId &&
if (Id.getKind() == UnqualifiedIdKind::IK_TemplateId && Id.TemplateId &&
Id.TemplateId->Kind == TNK_Var_template) {
assert(R.getAsSingle<VarTemplateDecl>() &&
"There should only be one declaration found.");
@ -2401,7 +2402,7 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
IdentifierInfo &II = Context.Idents.get("self");
UnqualifiedId SelfName;
SelfName.setIdentifier(&II, SourceLocation());
SelfName.setKind(UnqualifiedId::IK_ImplicitSelfParam);
SelfName.setKind(UnqualifiedIdKind::IK_ImplicitSelfParam);
CXXScopeSpec SelfScopeSpec;
SourceLocation TemplateKWLoc;
ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc,
@ -12834,7 +12835,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
Scope *CurScope) {
assert(ParamInfo.getIdentifier() == nullptr &&
"block-id should have no identifier!");
assert(ParamInfo.getContext() == Declarator::BlockLiteralContext);
assert(ParamInfo.getContext() == DeclaratorContext::BlockLiteralContext);
BlockScopeInfo *CurBlock = getCurBlock();
TypeSourceInfo *Sig = GetTypeForDeclarator(ParamInfo, CurScope);

View File

@ -356,7 +356,7 @@ ParsedType Sema::getDestructorTypeForDecltype(const DeclSpec &DS,
bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
const UnqualifiedId &Name) {
assert(Name.getKind() == UnqualifiedId::IK_LiteralOperatorId);
assert(Name.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId);
if (!SS.isValid())
return false;
@ -6716,11 +6716,11 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
SourceLocation CCLoc,
SourceLocation TildeLoc,
UnqualifiedId &SecondTypeName) {
assert((FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId ||
FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) &&
assert((FirstTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId ||
FirstTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) &&
"Invalid first type name in pseudo-destructor");
assert((SecondTypeName.getKind() == UnqualifiedId::IK_TemplateId ||
SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) &&
assert((SecondTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId ||
SecondTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) &&
"Invalid second type name in pseudo-destructor");
QualType ObjectType;
@ -6742,7 +6742,7 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
QualType DestructedType;
TypeSourceInfo *DestructedTypeInfo = nullptr;
PseudoDestructorTypeStorage Destructed;
if (SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) {
if (SecondTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) {
ParsedType T = getTypeName(*SecondTypeName.Identifier,
SecondTypeName.StartLocation,
S, &SS, true, false, ObjectTypePtrForLookup,
@ -6800,9 +6800,9 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
// Convert the name of the scope type (the type prior to '::') into a type.
TypeSourceInfo *ScopeTypeInfo = nullptr;
QualType ScopeType;
if (FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId ||
if (FirstTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId ||
FirstTypeName.Identifier) {
if (FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) {
if (FirstTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) {
ParsedType T = getTypeName(*FirstTypeName.Identifier,
FirstTypeName.StartLocation,
S, &SS, true, false, ObjectTypePtrForLookup,

View File

@ -1707,7 +1707,7 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
// Warn about the explicit constructor calls Microsoft extension.
if (getLangOpts().MicrosoftExt &&
Id.getKind() == UnqualifiedId::IK_ConstructorName)
Id.getKind() == UnqualifiedIdKind::IK_ConstructorName)
Diag(Id.getSourceRange().getBegin(),
diag::ext_ms_explicit_constructor_call);

View File

@ -1167,6 +1167,24 @@ void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope,
PopFunctionScopeInfo();
}
QualType Sema::getLambdaConversionFunctionResultType(
const FunctionProtoType *CallOpProto) {
// The function type inside the pointer type is the same as the call
// operator with some tweaks. The calling convention is the default free
// function convention, and the type qualifications are lost.
const FunctionProtoType::ExtProtoInfo CallOpExtInfo =
CallOpProto->getExtProtoInfo();
FunctionProtoType::ExtProtoInfo InvokerExtInfo = CallOpExtInfo;
CallingConv CC = Context.getDefaultCallingConvention(
CallOpProto->isVariadic(), /*IsCXXMethod=*/false);
InvokerExtInfo.ExtInfo = InvokerExtInfo.ExtInfo.withCallingConv(CC);
InvokerExtInfo.TypeQuals = 0;
assert(InvokerExtInfo.RefQualifier == RQ_None &&
"Lambda's call operator should not have a reference qualifier");
return Context.getFunctionType(CallOpProto->getReturnType(),
CallOpProto->getParamTypes(), InvokerExtInfo);
}
/// \brief Add a lambda's conversion to function pointer, as described in
/// C++11 [expr.prim.lambda]p6.
static void addFunctionPointerConversion(Sema &S,
@ -1182,25 +1200,9 @@ static void addFunctionPointerConversion(Sema &S,
return;
// Add the conversion to function pointer.
const FunctionProtoType *CallOpProto =
CallOperator->getType()->getAs<FunctionProtoType>();
const FunctionProtoType::ExtProtoInfo CallOpExtInfo =
CallOpProto->getExtProtoInfo();
QualType PtrToFunctionTy;
QualType InvokerFunctionTy;
{
FunctionProtoType::ExtProtoInfo InvokerExtInfo = CallOpExtInfo;
CallingConv CC = S.Context.getDefaultCallingConvention(
CallOpProto->isVariadic(), /*IsCXXMethod=*/false);
InvokerExtInfo.ExtInfo = InvokerExtInfo.ExtInfo.withCallingConv(CC);
InvokerExtInfo.TypeQuals = 0;
assert(InvokerExtInfo.RefQualifier == RQ_None &&
"Lambda's call operator should not have a reference qualifier");
InvokerFunctionTy =
S.Context.getFunctionType(CallOpProto->getReturnType(),
CallOpProto->getParamTypes(), InvokerExtInfo);
PtrToFunctionTy = S.Context.getPointerType(InvokerFunctionTy);
}
QualType InvokerFunctionTy = S.getLambdaConversionFunctionResultType(
CallOperator->getType()->castAs<FunctionProtoType>());
QualType PtrToFunctionTy = S.Context.getPointerType(InvokerFunctionTy);
// Create the type of the conversion function.
FunctionProtoType::ExtProtoInfo ConvExtInfo(
@ -1357,19 +1359,8 @@ static void addBlockPointerConversion(Sema &S,
SourceRange IntroducerRange,
CXXRecordDecl *Class,
CXXMethodDecl *CallOperator) {
const FunctionProtoType *Proto =
CallOperator->getType()->getAs<FunctionProtoType>();
// The function type inside the block pointer type is the same as the call
// operator with some tweaks. The calling convention is the default free
// function convention, and the type qualifications are lost.
FunctionProtoType::ExtProtoInfo BlockEPI = Proto->getExtProtoInfo();
BlockEPI.ExtInfo =
BlockEPI.ExtInfo.withCallingConv(S.Context.getDefaultCallingConvention(
Proto->isVariadic(), /*IsCXXMethod=*/false));
BlockEPI.TypeQuals = 0;
QualType FunctionTy = S.Context.getFunctionType(
Proto->getReturnType(), Proto->getParamTypes(), BlockEPI);
QualType FunctionTy = S.getLambdaConversionFunctionResultType(
CallOperator->getType()->castAs<FunctionProtoType>());
QualType BlockPtrTy = S.Context.getBlockPointerType(FunctionTy);
FunctionProtoType::ExtProtoInfo ConversionEPI(

View File

@ -5145,7 +5145,8 @@ Sema::PerformObjectArgumentInitialization(Expr *From,
*this, From->getLocStart(), From->getType(), FromClassification, Method,
Method->getParent());
if (ICS.isBad()) {
if (ICS.Bad.Kind == BadConversionSequence::bad_qualifiers) {
switch (ICS.Bad.Kind) {
case BadConversionSequence::bad_qualifiers: {
Qualifiers FromQs = FromRecordType.getQualifiers();
Qualifiers ToQs = DestType.getQualifiers();
unsigned CVR = FromQs.getCVRQualifiers() & ~ToQs.getCVRQualifiers();
@ -5158,10 +5159,28 @@ Sema::PerformObjectArgumentInitialization(Expr *From,
<< Method->getDeclName();
return ExprError();
}
break;
}
case BadConversionSequence::lvalue_ref_to_rvalue:
case BadConversionSequence::rvalue_ref_to_lvalue: {
bool IsRValueQualified =
Method->getRefQualifier() == RefQualifierKind::RQ_RValue;
Diag(From->getLocStart(), diag::err_member_function_call_bad_ref)
<< Method->getDeclName() << FromClassification.isRValue()
<< IsRValueQualified;
Diag(Method->getLocation(), diag::note_previous_decl)
<< Method->getDeclName();
return ExprError();
}
case BadConversionSequence::no_conversion:
case BadConversionSequence::unrelated_class:
break;
}
return Diag(From->getLocStart(),
diag::err_implicit_object_parameter_init)
diag::err_member_function_call_bad_type)
<< ImplicitParamRecordType << FromRecordType << From->getSourceRange();
}
@ -11309,9 +11328,6 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
return Matched;
}
// Resolve and fix an overloaded expression that can be resolved
// because it identifies a single function template specialization.
//

View File

@ -14,6 +14,7 @@
#include "clang/Sema/SemaInternal.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
@ -3228,6 +3229,12 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
SourceLocation ReturnLoc,
Expr *&RetExpr,
AutoType *AT) {
// If this is the conversion function for a lambda, we choose to deduce it
// type from the corresponding call operator, not from the synthesized return
// statement within it. See Sema::DeduceReturnType.
if (isLambdaConversionOperator(FD))
return false;
TypeLoc OrigResultType = getReturnTypeLoc(FD);
QualType Deduced;

View File

@ -169,16 +169,16 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
MemberOfUnknownSpecialization = false;
switch (Name.getKind()) {
case UnqualifiedId::IK_Identifier:
case UnqualifiedIdKind::IK_Identifier:
TName = DeclarationName(Name.Identifier);
break;
case UnqualifiedId::IK_OperatorFunctionId:
case UnqualifiedIdKind::IK_OperatorFunctionId:
TName = Context.DeclarationNames.getCXXOperatorName(
Name.OperatorFunctionId.Operator);
break;
case UnqualifiedId::IK_LiteralOperatorId:
case UnqualifiedIdKind::IK_LiteralOperatorId:
TName = Context.DeclarationNames.getCXXLiteralOperatorName(Name.Identifier);
break;
@ -3557,7 +3557,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
TemplateParameterList *TemplateParams, StorageClass SC,
bool IsPartialSpecialization) {
// D must be variable template id.
assert(D.getName().getKind() == UnqualifiedId::IK_TemplateId &&
assert(D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId &&
"Variable template specialization is declared with a template it.");
TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
@ -4084,8 +4084,8 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
// We found something; return it.
auto *LookupRD = dyn_cast<CXXRecordDecl>(LookupCtx);
if (!AllowInjectedClassName && SS.isSet() && LookupRD &&
Name.getKind() == UnqualifiedId::IK_Identifier && Name.Identifier &&
LookupRD->getIdentifier() == Name.Identifier) {
Name.getKind() == UnqualifiedIdKind::IK_Identifier &&
Name.Identifier && LookupRD->getIdentifier() == Name.Identifier) {
// C++14 [class.qual]p2:
// In a lookup in which function names are not ignored and the
// nested-name-specifier nominates a class C, if the name specified
@ -4107,17 +4107,17 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
NestedNameSpecifier *Qualifier = SS.getScopeRep();
switch (Name.getKind()) {
case UnqualifiedId::IK_Identifier:
case UnqualifiedIdKind::IK_Identifier:
Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,
Name.Identifier));
return TNK_Dependent_template_name;
case UnqualifiedId::IK_OperatorFunctionId:
case UnqualifiedIdKind::IK_OperatorFunctionId:
Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,
Name.OperatorFunctionId.Operator));
return TNK_Function_template;
case UnqualifiedId::IK_LiteralOperatorId:
case UnqualifiedIdKind::IK_LiteralOperatorId:
llvm_unreachable("literal operator id cannot have a dependent scope");
default:
@ -9044,7 +9044,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
return true;
}
if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
if (D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {
// C++1y [temp.explicit]p3:
// If the explicit instantiation is for a variable, the unqualified-id
// in the declaration shall be a template-id.
@ -9126,7 +9126,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
// argument list into our AST format.
bool HasExplicitTemplateArgs = false;
TemplateArgumentListInfo TemplateArgs;
if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
if (D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId) {
TemplateArgs = makeTemplateArgumentListInfo(*this, *D.getName().TemplateId);
HasExplicitTemplateArgs = true;
}
@ -9292,7 +9292,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
//
// C++98 has the same restriction, just worded differently.
FunctionTemplateDecl *FunTmpl = Specialization->getPrimaryTemplate();
if (D.getName().getKind() != UnqualifiedId::IK_TemplateId && !FunTmpl &&
if (D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId && !FunTmpl &&
D.getCXXScopeSpec().isSet() &&
!ScopeSpecifierHasTemplateId(D.getCXXScopeSpec()))
Diag(D.getIdentifierLoc(),

View File

@ -3940,117 +3940,6 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(
return TDK_Success;
}
/// \brief Given a function declaration (e.g. a generic lambda conversion
/// function) that contains an 'auto' in its result type, substitute it
/// with TypeToReplaceAutoWith. Be careful to pass in the type you want
/// to replace 'auto' with and not the actual result type you want
/// to set the function to.
static inline void
SubstAutoWithinFunctionReturnType(FunctionDecl *F,
QualType TypeToReplaceAutoWith, Sema &S) {
assert(!TypeToReplaceAutoWith->getContainedAutoType());
QualType AutoResultType = F->getReturnType();
assert(AutoResultType->getContainedAutoType());
QualType DeducedResultType = S.SubstAutoType(AutoResultType,
TypeToReplaceAutoWith);
S.Context.adjustDeducedFunctionResultType(F, DeducedResultType);
}
/// \brief Given a specialized conversion operator of a generic lambda
/// create the corresponding specializations of the call operator and
/// the static-invoker. If the return type of the call operator is auto,
/// deduce its return type and check if that matches the
/// return type of the destination function ptr.
static inline Sema::TemplateDeductionResult
SpecializeCorrespondingLambdaCallOperatorAndInvoker(
CXXConversionDecl *ConversionSpecialized,
SmallVectorImpl<DeducedTemplateArgument> &DeducedArguments,
QualType ReturnTypeOfDestFunctionPtr,
TemplateDeductionInfo &TDInfo,
Sema &S) {
CXXRecordDecl *LambdaClass = ConversionSpecialized->getParent();
assert(LambdaClass && LambdaClass->isGenericLambda());
CXXMethodDecl *CallOpGeneric = LambdaClass->getLambdaCallOperator();
QualType CallOpResultType = CallOpGeneric->getReturnType();
const bool GenericLambdaCallOperatorHasDeducedReturnType =
CallOpResultType->getContainedAutoType();
FunctionTemplateDecl *CallOpTemplate =
CallOpGeneric->getDescribedFunctionTemplate();
FunctionDecl *CallOpSpecialized = nullptr;
// Use the deduced arguments of the conversion function, to specialize our
// generic lambda's call operator.
if (Sema::TemplateDeductionResult Result
= S.FinishTemplateArgumentDeduction(CallOpTemplate,
DeducedArguments,
0, CallOpSpecialized, TDInfo))
return Result;
// If we need to deduce the return type, do so (instantiates the callop).
if (GenericLambdaCallOperatorHasDeducedReturnType &&
CallOpSpecialized->getReturnType()->isUndeducedType())
S.DeduceReturnType(CallOpSpecialized,
CallOpSpecialized->getPointOfInstantiation(),
/*Diagnose*/ true);
// Check to see if the return type of the destination ptr-to-function
// matches the return type of the call operator.
if (!S.Context.hasSameType(CallOpSpecialized->getReturnType(),
ReturnTypeOfDestFunctionPtr))
return Sema::TDK_NonDeducedMismatch;
// Since we have succeeded in matching the source and destination
// ptr-to-functions (now including return type), and have successfully
// specialized our corresponding call operator, we are ready to
// specialize the static invoker with the deduced arguments of our
// ptr-to-function.
FunctionDecl *InvokerSpecialized = nullptr;
FunctionTemplateDecl *InvokerTemplate = LambdaClass->
getLambdaStaticInvoker()->getDescribedFunctionTemplate();
#ifndef NDEBUG
Sema::TemplateDeductionResult LLVM_ATTRIBUTE_UNUSED Result =
#endif
S.FinishTemplateArgumentDeduction(InvokerTemplate, DeducedArguments, 0,
InvokerSpecialized, TDInfo);
assert(Result == Sema::TDK_Success &&
"If the call operator succeeded so should the invoker!");
// Set the result type to match the corresponding call operator
// specialization's result type.
if (GenericLambdaCallOperatorHasDeducedReturnType &&
InvokerSpecialized->getReturnType()->isUndeducedType()) {
// Be sure to get the type to replace 'auto' with and not
// the full result type of the call op specialization
// to substitute into the 'auto' of the invoker and conversion
// function.
// For e.g.
// int* (*fp)(int*) = [](auto* a) -> auto* { return a; };
// We don't want to subst 'int*' into 'auto' to get int**.
QualType TypeToReplaceAutoWith = CallOpSpecialized->getReturnType()
->getContainedAutoType()
->getDeducedType();
SubstAutoWithinFunctionReturnType(InvokerSpecialized,
TypeToReplaceAutoWith, S);
SubstAutoWithinFunctionReturnType(ConversionSpecialized,
TypeToReplaceAutoWith, S);
}
// Ensure that static invoker doesn't have a const qualifier.
// FIXME: When creating the InvokerTemplate in SemaLambda.cpp
// do not use the CallOperator's TypeSourceInfo which allows
// the const qualifier to leak through.
const FunctionProtoType *InvokerFPT = InvokerSpecialized->
getType().getTypePtr()->castAs<FunctionProtoType>();
FunctionProtoType::ExtProtoInfo EPI = InvokerFPT->getExtProtoInfo();
EPI.TypeQuals = 0;
InvokerSpecialized->setType(S.Context.getFunctionType(
InvokerFPT->getReturnType(), InvokerFPT->getParamTypes(), EPI));
return Sema::TDK_Success;
}
/// \brief Deduce template arguments for a templated conversion
/// function (C++ [temp.deduct.conv]) and, if successful, produce a
/// conversion function template specialization.
@ -4158,35 +4047,6 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *ConversionTemplate,
= FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0,
ConversionSpecialized, Info);
Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized);
// If the conversion operator is being invoked on a lambda closure to convert
// to a ptr-to-function, use the deduced arguments from the conversion
// function to specialize the corresponding call operator.
// e.g., int (*fp)(int) = [](auto a) { return a; };
if (Result == TDK_Success && isLambdaConversionOperator(ConversionGeneric)) {
// Get the return type of the destination ptr-to-function we are converting
// to. This is necessary for matching the lambda call operator's return
// type to that of the destination ptr-to-function's return type.
assert(A->isPointerType() &&
"Can only convert from lambda to ptr-to-function");
const FunctionType *ToFunType =
A->getPointeeType().getTypePtr()->getAs<FunctionType>();
const QualType DestFunctionPtrReturnType = ToFunType->getReturnType();
// Create the corresponding specializations of the call operator and
// the static-invoker; and if the return type is auto,
// deduce the return type and check if it matches the
// DestFunctionPtrReturnType.
// For instance:
// auto L = [](auto a) { return f(a); };
// int (*fp)(int) = L;
// char (*fp2)(int) = L; <-- Not OK.
Result = SpecializeCorrespondingLambdaCallOperatorAndInvoker(
Specialization, Deduced, DestFunctionPtrReturnType,
Info, *this);
}
return Result;
}
@ -4536,6 +4396,43 @@ bool Sema::DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
bool Diagnose) {
assert(FD->getReturnType()->isUndeducedType());
// For a lambda's conversion operator, deduce any 'auto' or 'decltype(auto)'
// within the return type from the call operator's type.
if (isLambdaConversionOperator(FD)) {
CXXRecordDecl *Lambda = cast<CXXMethodDecl>(FD)->getParent();
FunctionDecl *CallOp = Lambda->getLambdaCallOperator();
// For a generic lambda, instantiate the call operator if needed.
if (auto *Args = FD->getTemplateSpecializationArgs()) {
CallOp = InstantiateFunctionDeclaration(
CallOp->getDescribedFunctionTemplate(), Args, Loc);
if (!CallOp || CallOp->isInvalidDecl())
return true;
// We might need to deduce the return type by instantiating the definition
// of the operator() function.
if (CallOp->getReturnType()->isUndeducedType())
InstantiateFunctionDefinition(Loc, CallOp);
}
if (CallOp->isInvalidDecl())
return true;
assert(!CallOp->getReturnType()->isUndeducedType() &&
"failed to deduce lambda return type");
// Build the new return type from scratch.
QualType RetType = getLambdaConversionFunctionResultType(
CallOp->getType()->castAs<FunctionProtoType>());
if (FD->getReturnType()->getAs<PointerType>())
RetType = Context.getPointerType(RetType);
else {
assert(FD->getReturnType()->getAs<BlockPointerType>());
RetType = Context.getBlockPointerType(RetType);
}
Context.adjustDeducedFunctionResultType(FD, RetType);
return false;
}
if (FD->getTemplateInstantiationPattern())
InstantiateFunctionDefinition(Loc, FD);

View File

@ -3729,6 +3729,30 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
return false;
}
/// Instantiate (or find existing instantiation of) a function template with a
/// given set of template arguments.
///
/// Usually this should not be used, and template argument deduction should be
/// used in its place.
FunctionDecl *
Sema::InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD,
const TemplateArgumentList *Args,
SourceLocation Loc) {
FunctionDecl *FD = FTD->getTemplatedDecl();
sema::TemplateDeductionInfo Info(Loc);
InstantiatingTemplate Inst(
*this, Loc, FTD, Args->asArray(),
CodeSynthesisContext::ExplicitTemplateArgumentSubstitution, Info);
if (Inst.isInvalid())
return nullptr;
ContextRAII SavedContext(*this, FD);
MultiLevelTemplateArgumentList MArgs(*Args);
return cast_or_null<FunctionDecl>(SubstDecl(FD, FD->getParent(), MArgs));
}
/// In the MS ABI, we need to instantiate default arguments of dllexported
/// default constructors along with the constructor definition. This allows IR
/// gen to emit a constructor closure which calls the default constructor with
@ -3812,7 +3836,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
PendingInstantiations.push_back(
std::make_pair(Function, PointOfInstantiation));
} else if (TSK == TSK_ImplicitInstantiation) {
if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() &&
!getSourceManager().isInSystemHeader(PatternDecl->getLocStart())) {
Diag(PointOfInstantiation, diag::warn_func_template_missing)
<< Function;
Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
@ -4347,7 +4372,8 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
std::make_pair(Var, PointOfInstantiation));
} else if (TSK == TSK_ImplicitInstantiation) {
// Warn about missing definition at the end of translation unit.
if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() &&
!getSourceManager().isInSystemHeader(PatternDecl->getLocStart())) {
Diag(PointOfInstantiation, diag::warn_var_template_missing)
<< Var;
Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);

View File

@ -47,7 +47,7 @@ enum TypeDiagSelector {
/// isOmittedBlockReturnType - Return true if this declarator is missing a
/// return type because this is a omitted return type on a block literal.
static bool isOmittedBlockReturnType(const Declarator &D) {
if (D.getContext() != Declarator::BlockLiteralContext ||
if (D.getContext() != DeclaratorContext::BlockLiteralContext ||
D.getDeclSpec().hasTypeSpecifier())
return false;
@ -1291,11 +1291,12 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
// The declspec is always missing in a lambda expr context; it is either
// specified with a trailing return type or inferred.
if (S.getLangOpts().CPlusPlus14 &&
declarator.getContext() == Declarator::LambdaExprContext) {
declarator.getContext() == DeclaratorContext::LambdaExprContext) {
// In C++1y, a lambda's implicit return type is 'auto'.
Result = Context.getAutoDeductType();
break;
} else if (declarator.getContext() == Declarator::LambdaExprContext ||
} else if (declarator.getContext() ==
DeclaratorContext::LambdaExprContext ||
checkOmittedBlockReturnType(S, declarator,
Context.DependentTy)) {
Result = Context.DependentTy;
@ -1572,7 +1573,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
// Before we process any type attributes, synthesize a block literal
// function declarator if necessary.
if (declarator.getContext() == Declarator::BlockLiteralContext)
if (declarator.getContext() == DeclaratorContext::BlockLiteralContext)
maybeSynthesizeBlockSignature(state, Result);
// Apply any type attributes from the decl spec. This may cause the
@ -2702,7 +2703,7 @@ static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy,
// If the qualifiers come from a conversion function type, don't diagnose
// them -- they're not necessarily redundant, since such a conversion
// operator can be explicitly called as "x.operator const int()".
if (D.getName().getKind() == UnqualifiedId::IK_ConversionFunctionId)
if (D.getName().getKind() == UnqualifiedIdKind::IK_ConversionFunctionId)
return;
// Just parens all the way out to the decl specifiers. Diagnose any qualifiers
@ -2728,11 +2729,11 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
TagDecl *OwnedTagDecl = nullptr;
switch (D.getName().getKind()) {
case UnqualifiedId::IK_ImplicitSelfParam:
case UnqualifiedId::IK_OperatorFunctionId:
case UnqualifiedId::IK_Identifier:
case UnqualifiedId::IK_LiteralOperatorId:
case UnqualifiedId::IK_TemplateId:
case UnqualifiedIdKind::IK_ImplicitSelfParam:
case UnqualifiedIdKind::IK_OperatorFunctionId:
case UnqualifiedIdKind::IK_Identifier:
case UnqualifiedIdKind::IK_LiteralOperatorId:
case UnqualifiedIdKind::IK_TemplateId:
T = ConvertDeclSpecToType(state);
if (!D.isInvalidType() && D.getDeclSpec().isTypeSpecOwned()) {
@ -2742,9 +2743,9 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
}
break;
case UnqualifiedId::IK_ConstructorName:
case UnqualifiedId::IK_ConstructorTemplateId:
case UnqualifiedId::IK_DestructorName:
case UnqualifiedIdKind::IK_ConstructorName:
case UnqualifiedIdKind::IK_ConstructorTemplateId:
case UnqualifiedIdKind::IK_DestructorName:
// Constructors and destructors don't have return types. Use
// "void" instead.
T = SemaRef.Context.VoidTy;
@ -2752,13 +2753,13 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
D.getDeclSpec().getAttributes().getList());
break;
case UnqualifiedId::IK_DeductionGuideName:
case UnqualifiedIdKind::IK_DeductionGuideName:
// Deduction guides have a trailing return type and no type in their
// decl-specifier sequence. Use a placeholder return type for now.
T = SemaRef.Context.DependentTy;
break;
case UnqualifiedId::IK_ConversionFunctionId:
case UnqualifiedIdKind::IK_ConversionFunctionId:
// The result type of a conversion function is the type that it
// converts to.
T = SemaRef.GetTypeFromParser(D.getName().ConversionFunctionId,
@ -2780,16 +2781,16 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
(Auto && Auto->getKeyword() != AutoTypeKeyword::GNUAutoType);
switch (D.getContext()) {
case Declarator::LambdaExprContext:
case DeclaratorContext::LambdaExprContext:
// Declared return type of a lambda-declarator is implicit and is always
// 'auto'.
break;
case Declarator::ObjCParameterContext:
case Declarator::ObjCResultContext:
case Declarator::PrototypeContext:
case DeclaratorContext::ObjCParameterContext:
case DeclaratorContext::ObjCResultContext:
case DeclaratorContext::PrototypeContext:
Error = 0;
break;
case Declarator::LambdaExprParameterContext:
case DeclaratorContext::LambdaExprParameterContext:
// In C++14, generic lambdas allow 'auto' in their parameters.
if (!SemaRef.getLangOpts().CPlusPlus14 ||
!Auto || Auto->getKeyword() != AutoTypeKeyword::Auto)
@ -2821,7 +2822,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
T, QualType(CorrespondingTemplateParam->getTypeForDecl(), 0));
}
break;
case Declarator::MemberContext: {
case DeclaratorContext::MemberContext: {
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||
D.isFunctionDeclarator())
break;
@ -2837,57 +2838,57 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
Error = 20; // Friend type
break;
}
case Declarator::CXXCatchContext:
case Declarator::ObjCCatchContext:
case DeclaratorContext::CXXCatchContext:
case DeclaratorContext::ObjCCatchContext:
Error = 7; // Exception declaration
break;
case Declarator::TemplateParamContext:
case DeclaratorContext::TemplateParamContext:
if (isa<DeducedTemplateSpecializationType>(Deduced))
Error = 19; // Template parameter
else if (!SemaRef.getLangOpts().CPlusPlus17)
Error = 8; // Template parameter (until C++17)
break;
case Declarator::BlockLiteralContext:
case DeclaratorContext::BlockLiteralContext:
Error = 9; // Block literal
break;
case Declarator::TemplateTypeArgContext:
case DeclaratorContext::TemplateTypeArgContext:
Error = 10; // Template type argument
break;
case Declarator::AliasDeclContext:
case Declarator::AliasTemplateContext:
case DeclaratorContext::AliasDeclContext:
case DeclaratorContext::AliasTemplateContext:
Error = 12; // Type alias
break;
case Declarator::TrailingReturnContext:
case DeclaratorContext::TrailingReturnContext:
if (!SemaRef.getLangOpts().CPlusPlus14 || !IsCXXAutoType)
Error = 13; // Function return type
break;
case Declarator::ConversionIdContext:
case DeclaratorContext::ConversionIdContext:
if (!SemaRef.getLangOpts().CPlusPlus14 || !IsCXXAutoType)
Error = 14; // conversion-type-id
break;
case Declarator::FunctionalCastContext:
case DeclaratorContext::FunctionalCastContext:
if (isa<DeducedTemplateSpecializationType>(Deduced))
break;
LLVM_FALLTHROUGH;
case Declarator::TypeNameContext:
case DeclaratorContext::TypeNameContext:
Error = 15; // Generic
break;
case Declarator::FileContext:
case Declarator::BlockContext:
case Declarator::ForContext:
case Declarator::InitStmtContext:
case Declarator::ConditionContext:
case DeclaratorContext::FileContext:
case DeclaratorContext::BlockContext:
case DeclaratorContext::ForContext:
case DeclaratorContext::InitStmtContext:
case DeclaratorContext::ConditionContext:
// FIXME: P0091R3 (erroneously) does not permit class template argument
// deduction in conditions, for-init-statements, and other declarations
// that are not simple-declarations.
break;
case Declarator::CXXNewContext:
case DeclaratorContext::CXXNewContext:
// FIXME: P0091R3 does not permit class template argument deduction here,
// but we follow GCC and allow it anyway.
if (!IsCXXAutoType && !isa<DeducedTemplateSpecializationType>(Deduced))
Error = 17; // 'new' type
break;
case Declarator::KNRTypeListContext:
case DeclaratorContext::KNRTypeListContext:
Error = 18; // K&R function parameter
break;
}
@ -2916,7 +2917,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
}
SourceRange AutoRange = D.getDeclSpec().getTypeSpecTypeLoc();
if (D.getName().getKind() == UnqualifiedId::IK_ConversionFunctionId)
if (D.getName().getKind() == UnqualifiedIdKind::IK_ConversionFunctionId)
AutoRange = D.getName().getSourceRange();
if (Error != -1) {
@ -2959,47 +2960,47 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
// or enumeration in a type-specifier-seq.
unsigned DiagID = 0;
switch (D.getContext()) {
case Declarator::TrailingReturnContext:
case DeclaratorContext::TrailingReturnContext:
// Class and enumeration definitions are syntactically not allowed in
// trailing return types.
llvm_unreachable("parser should not have allowed this");
break;
case Declarator::FileContext:
case Declarator::MemberContext:
case Declarator::BlockContext:
case Declarator::ForContext:
case Declarator::InitStmtContext:
case Declarator::BlockLiteralContext:
case Declarator::LambdaExprContext:
case DeclaratorContext::FileContext:
case DeclaratorContext::MemberContext:
case DeclaratorContext::BlockContext:
case DeclaratorContext::ForContext:
case DeclaratorContext::InitStmtContext:
case DeclaratorContext::BlockLiteralContext:
case DeclaratorContext::LambdaExprContext:
// C++11 [dcl.type]p3:
// A type-specifier-seq shall not define a class or enumeration unless
// it appears in the type-id of an alias-declaration (7.1.3) that is not
// the declaration of a template-declaration.
case Declarator::AliasDeclContext:
case DeclaratorContext::AliasDeclContext:
break;
case Declarator::AliasTemplateContext:
case DeclaratorContext::AliasTemplateContext:
DiagID = diag::err_type_defined_in_alias_template;
break;
case Declarator::TypeNameContext:
case Declarator::FunctionalCastContext:
case Declarator::ConversionIdContext:
case Declarator::TemplateParamContext:
case Declarator::CXXNewContext:
case Declarator::CXXCatchContext:
case Declarator::ObjCCatchContext:
case Declarator::TemplateTypeArgContext:
case DeclaratorContext::TypeNameContext:
case DeclaratorContext::FunctionalCastContext:
case DeclaratorContext::ConversionIdContext:
case DeclaratorContext::TemplateParamContext:
case DeclaratorContext::CXXNewContext:
case DeclaratorContext::CXXCatchContext:
case DeclaratorContext::ObjCCatchContext:
case DeclaratorContext::TemplateTypeArgContext:
DiagID = diag::err_type_defined_in_type_specifier;
break;
case Declarator::PrototypeContext:
case Declarator::LambdaExprParameterContext:
case Declarator::ObjCParameterContext:
case Declarator::ObjCResultContext:
case Declarator::KNRTypeListContext:
case DeclaratorContext::PrototypeContext:
case DeclaratorContext::LambdaExprParameterContext:
case DeclaratorContext::ObjCParameterContext:
case DeclaratorContext::ObjCResultContext:
case DeclaratorContext::KNRTypeListContext:
// C++ [dcl.fct]p6:
// Types shall not be defined in return or parameter types.
DiagID = diag::err_type_defined_in_param_type;
break;
case Declarator::ConditionContext:
case DeclaratorContext::ConditionContext:
// C++ 6.4p2:
// The type-specifier-seq shall not contain typedef and shall not declare
// a new class or enumeration.
@ -3048,7 +3049,7 @@ static void warnAboutAmbiguousFunction(Sema &S, Declarator &D,
// Inside a condition, a direct initializer is not permitted. We allow one to
// be parsed in order to give better diagnostics in condition parsing.
if (D.getContext() == Declarator::ConditionContext)
if (D.getContext() == DeclaratorContext::ConditionContext)
return;
SourceRange ParenRange(DeclType.Loc, DeclType.EndLoc);
@ -3164,7 +3165,7 @@ static void warnAboutRedundantParens(Sema &S, Declarator &D, QualType T) {
case DeclaratorChunk::Function:
// In a new-type-id, function chunks require parentheses.
if (D.getContext() == Declarator::CXXNewContext)
if (D.getContext() == DeclaratorContext::CXXNewContext)
return;
// FIXME: "A(f())" deserves a vexing-parse warning, not just a
// redundant-parens warning, but we don't know whether the function
@ -3282,7 +3283,7 @@ getCCForDeclaratorChunk(Sema &S, Declarator &D,
// in a member pointer.
IsCXXInstanceMethod =
D.getTypeObject(I).Kind == DeclaratorChunk::MemberPointer;
} else if (D.getContext() == Declarator::LambdaExprContext) {
} else if (D.getContext() == DeclaratorContext::LambdaExprContext) {
// This can only be a call operator for a lambda, which is an instance
// method.
IsCXXInstanceMethod = true;
@ -3779,8 +3780,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Does this declaration declare a typedef-name?
bool IsTypedefName =
D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef ||
D.getContext() == Declarator::AliasDeclContext ||
D.getContext() == Declarator::AliasTemplateContext;
D.getContext() == DeclaratorContext::AliasDeclContext ||
D.getContext() == DeclaratorContext::AliasTemplateContext;
// Does T refer to a function type with a cv-qualifier or a ref-qualifier?
bool IsQualifiedFunction = T->isFunctionProtoType() &&
@ -3909,14 +3910,14 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
} else {
bool isFunctionOrMethod = false;
switch (auto context = state.getDeclarator().getContext()) {
case Declarator::ObjCParameterContext:
case Declarator::ObjCResultContext:
case Declarator::PrototypeContext:
case Declarator::TrailingReturnContext:
case DeclaratorContext::ObjCParameterContext:
case DeclaratorContext::ObjCResultContext:
case DeclaratorContext::PrototypeContext:
case DeclaratorContext::TrailingReturnContext:
isFunctionOrMethod = true;
LLVM_FALLTHROUGH;
case Declarator::MemberContext:
case DeclaratorContext::MemberContext:
if (state.getDeclarator().isObjCIvar() && !isFunctionOrMethod) {
complainAboutMissingNullability = CAMN_No;
break;
@ -3930,8 +3931,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
LLVM_FALLTHROUGH;
case Declarator::FileContext:
case Declarator::KNRTypeListContext: {
case DeclaratorContext::FileContext:
case DeclaratorContext::KNRTypeListContext: {
complainAboutMissingNullability = CAMN_Yes;
// Nullability inference depends on the type and declarator.
@ -3947,8 +3948,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
if (inAssumeNonNullRegion) {
complainAboutInferringWithinChunk = wrappingKind;
inferNullability = NullabilityKind::NonNull;
inferNullabilityCS = (context == Declarator::ObjCParameterContext ||
context == Declarator::ObjCResultContext);
inferNullabilityCS =
(context == DeclaratorContext::ObjCParameterContext ||
context == DeclaratorContext::ObjCResultContext);
}
break;
@ -3988,26 +3990,26 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
break;
}
case Declarator::ConversionIdContext:
case DeclaratorContext::ConversionIdContext:
complainAboutMissingNullability = CAMN_Yes;
break;
case Declarator::AliasDeclContext:
case Declarator::AliasTemplateContext:
case Declarator::BlockContext:
case Declarator::BlockLiteralContext:
case Declarator::ConditionContext:
case Declarator::CXXCatchContext:
case Declarator::CXXNewContext:
case Declarator::ForContext:
case Declarator::InitStmtContext:
case Declarator::LambdaExprContext:
case Declarator::LambdaExprParameterContext:
case Declarator::ObjCCatchContext:
case Declarator::TemplateParamContext:
case Declarator::TemplateTypeArgContext:
case Declarator::TypeNameContext:
case Declarator::FunctionalCastContext:
case DeclaratorContext::AliasDeclContext:
case DeclaratorContext::AliasTemplateContext:
case DeclaratorContext::BlockContext:
case DeclaratorContext::BlockLiteralContext:
case DeclaratorContext::ConditionContext:
case DeclaratorContext::CXXCatchContext:
case DeclaratorContext::CXXNewContext:
case DeclaratorContext::ForContext:
case DeclaratorContext::InitStmtContext:
case DeclaratorContext::LambdaExprContext:
case DeclaratorContext::LambdaExprParameterContext:
case DeclaratorContext::ObjCCatchContext:
case DeclaratorContext::TemplateParamContext:
case DeclaratorContext::TemplateTypeArgContext:
case DeclaratorContext::TypeNameContext:
case DeclaratorContext::FunctionalCastContext:
// Don't infer in these contexts.
break;
}
@ -4243,7 +4245,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// array type, ...
if (ASM == ArrayType::Static || ATI.TypeQuals) {
if (!(D.isPrototypeContext() ||
D.getContext() == Declarator::KNRTypeListContext)) {
D.getContext() == DeclaratorContext::KNRTypeListContext)) {
S.Diag(DeclType.Loc, diag::err_array_static_outside_prototype) <<
(ASM == ArrayType::Static ? "'static'" : "type qualifier");
// Remove the 'static' and the type qualifiers.
@ -4267,7 +4269,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
const AutoType *AT = T->getContainedAutoType();
// Allow arrays of auto if we are a generic lambda parameter.
// i.e. [](auto (&array)[5]) { return array[0]; }; OK
if (AT && D.getContext() != Declarator::LambdaExprParameterContext) {
if (AT &&
D.getContext() != DeclaratorContext::LambdaExprParameterContext) {
// We've already diagnosed this for decltype(auto).
if (!AT->isDecltypeAuto())
S.Diag(DeclType.Loc, diag::err_illegal_decl_array_of_auto)
@ -4319,14 +4322,14 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
<< T << D.getSourceRange();
D.setInvalidType(true);
} else if (D.getName().getKind() ==
UnqualifiedId::IK_DeductionGuideName) {
UnqualifiedIdKind::IK_DeductionGuideName) {
if (T != Context.DependentTy) {
S.Diag(D.getDeclSpec().getLocStart(),
diag::err_deduction_guide_with_complex_decl)
<< D.getSourceRange();
D.setInvalidType(true);
}
} else if (D.getContext() != Declarator::LambdaExprContext &&
} else if (D.getContext() != DeclaratorContext::LambdaExprContext &&
(T.hasQualifiers() || !isa<AutoType>(T) ||
cast<AutoType>(T)->getKeyword() !=
AutoTypeKeyword::Auto)) {
@ -4347,12 +4350,13 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// C99 6.7.5.3p1: The return type may not be a function or array type.
// For conversion functions, we'll diagnose this particular error later.
if (!D.isInvalidType() && (T->isArrayType() || T->isFunctionType()) &&
(D.getName().getKind() != UnqualifiedId::IK_ConversionFunctionId)) {
(D.getName().getKind() !=
UnqualifiedIdKind::IK_ConversionFunctionId)) {
unsigned diagID = diag::err_func_returning_array_function;
// Last processing chunk in block context means this function chunk
// represents the block.
if (chunkIndex == 0 &&
D.getContext() == Declarator::BlockLiteralContext)
D.getContext() == DeclaratorContext::BlockLiteralContext)
diagID = diag::err_block_returning_array_function;
S.Diag(DeclType.Loc, diagID) << T->isFunctionType() << T;
T = Context.IntTy;
@ -4490,8 +4494,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
if (IsTypedefName && FTI.getExceptionSpecType() && !LangOpts.CPlusPlus17)
S.Diag(FTI.getExceptionSpecLocBeg(),
diag::err_exception_spec_in_typedef)
<< (D.getContext() == Declarator::AliasDeclContext ||
D.getContext() == Declarator::AliasTemplateContext);
<< (D.getContext() == DeclaratorContext::AliasDeclContext ||
D.getContext() == DeclaratorContext::AliasTemplateContext);
// If we see "T var();" or "T var(T());" at block scope, it is probably
// an attempt to initialize a variable, not a function declaration.
@ -4763,7 +4767,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
break;
case DeclaratorChunk::Function: {
const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
if (FTI.NumParams == 0)
if (FTI.NumParams == 0 && !FTI.isVariadic)
S.Diag(DeclType.Loc, diag::warn_strict_prototypes)
<< IsBlock
<< FixItHint::CreateInsertion(FTI.getRParenLoc(), "void");
@ -4791,11 +4795,11 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Core issue 547 also allows cv-qualifiers on function types that are
// top-level template type arguments.
enum { NonMember, Member, DeductionGuide } Kind = NonMember;
if (D.getName().getKind() == UnqualifiedId::IK_DeductionGuideName)
if (D.getName().getKind() == UnqualifiedIdKind::IK_DeductionGuideName)
Kind = DeductionGuide;
else if (!D.getCXXScopeSpec().isSet()) {
if ((D.getContext() == Declarator::MemberContext ||
D.getContext() == Declarator::LambdaExprContext) &&
if ((D.getContext() == DeclaratorContext::MemberContext ||
D.getContext() == DeclaratorContext::LambdaExprContext) &&
!D.getDeclSpec().isFriendSpecified())
Kind = Member;
} else {
@ -4824,7 +4828,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
!(Kind == Member &&
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) &&
!IsTypedefName &&
D.getContext() != Declarator::TemplateTypeArgContext) {
D.getContext() != DeclaratorContext::TemplateTypeArgContext) {
SourceLocation Loc = D.getLocStart();
SourceRange RemovalRange;
unsigned I;
@ -4890,8 +4894,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// only be used in a parameter-declaration. Such a parameter-declaration
// is a parameter pack (14.5.3). [...]
switch (D.getContext()) {
case Declarator::PrototypeContext:
case Declarator::LambdaExprParameterContext:
case DeclaratorContext::PrototypeContext:
case DeclaratorContext::LambdaExprParameterContext:
// C++0x [dcl.fct]p13:
// [...] When it is part of a parameter-declaration-clause, the
// parameter pack is a function parameter pack (14.5.3). The type T
@ -4910,7 +4914,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
T = Context.getPackExpansionType(T, None);
}
break;
case Declarator::TemplateParamContext:
case DeclaratorContext::TemplateParamContext:
// C++0x [temp.param]p15:
// If a template-parameter is a [...] is a parameter-declaration that
// declares a parameter pack (8.3.5), then the template-parameter is a
@ -4928,27 +4932,29 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
: diag::ext_variadic_templates);
break;
case Declarator::FileContext:
case Declarator::KNRTypeListContext:
case Declarator::ObjCParameterContext: // FIXME: special diagnostic here?
case Declarator::ObjCResultContext: // FIXME: special diagnostic here?
case Declarator::TypeNameContext:
case Declarator::FunctionalCastContext:
case Declarator::CXXNewContext:
case Declarator::AliasDeclContext:
case Declarator::AliasTemplateContext:
case Declarator::MemberContext:
case Declarator::BlockContext:
case Declarator::ForContext:
case Declarator::InitStmtContext:
case Declarator::ConditionContext:
case Declarator::CXXCatchContext:
case Declarator::ObjCCatchContext:
case Declarator::BlockLiteralContext:
case Declarator::LambdaExprContext:
case Declarator::ConversionIdContext:
case Declarator::TrailingReturnContext:
case Declarator::TemplateTypeArgContext:
case DeclaratorContext::FileContext:
case DeclaratorContext::KNRTypeListContext:
case DeclaratorContext::ObjCParameterContext: // FIXME: special diagnostic
// here?
case DeclaratorContext::ObjCResultContext: // FIXME: special diagnostic
// here?
case DeclaratorContext::TypeNameContext:
case DeclaratorContext::FunctionalCastContext:
case DeclaratorContext::CXXNewContext:
case DeclaratorContext::AliasDeclContext:
case DeclaratorContext::AliasTemplateContext:
case DeclaratorContext::MemberContext:
case DeclaratorContext::BlockContext:
case DeclaratorContext::ForContext:
case DeclaratorContext::InitStmtContext:
case DeclaratorContext::ConditionContext:
case DeclaratorContext::CXXCatchContext:
case DeclaratorContext::ObjCCatchContext:
case DeclaratorContext::BlockLiteralContext:
case DeclaratorContext::LambdaExprContext:
case DeclaratorContext::ConversionIdContext:
case DeclaratorContext::TrailingReturnContext:
case DeclaratorContext::TemplateTypeArgContext:
// FIXME: We may want to allow parameter packs in block-literal contexts
// in the future.
S.Diag(D.getEllipsisLoc(),
@ -5637,9 +5643,9 @@ TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
// to apply them to the actual parameter declaration.
// Likewise, we don't want to do this for alias declarations, because
// we are actually going to build a declaration from this eventually.
if (D.getContext() != Declarator::ObjCParameterContext &&
D.getContext() != Declarator::AliasDeclContext &&
D.getContext() != Declarator::AliasTemplateContext)
if (D.getContext() != DeclaratorContext::ObjCParameterContext &&
D.getContext() != DeclaratorContext::AliasDeclContext &&
D.getContext() != DeclaratorContext::AliasTemplateContext)
checkUnusedDeclAttributes(D);
if (getLangOpts().CPlusPlus) {
@ -7066,7 +7072,7 @@ static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State,
IsFuncReturnType || IsFuncType ||
// Do not deduce addr space for member types of struct, except the pointee
// type of a pointer member type.
(D.getContext() == Declarator::MemberContext && !IsPointee) ||
(D.getContext() == DeclaratorContext::MemberContext && !IsPointee) ||
// Do not deduce addr space for types used to define a typedef and the
// typedef itself, except the pointee type of a pointer type which is used
// to define the typedef.
@ -7098,7 +7104,7 @@ static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State,
if (IsPointee) {
ImpAddr = LangAS::opencl_generic;
} else {
if (D.getContext() == Declarator::FileContext) {
if (D.getContext() == DeclaratorContext::FileContext) {
ImpAddr = LangAS::opencl_global;
} else {
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||

View File

@ -229,7 +229,6 @@ adjustCallLocations(PathPieces &Pieces,
PathDiagnosticCallPiece *Call = dyn_cast<PathDiagnosticCallPiece>(I->get());
if (!Call) {
assert((*I)->getLocation().asLocation().isValid());
continue;
}

View File

@ -1,10 +1,11 @@
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -verify %s
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBSTDCPP -verify %s
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -verify %s -o %t.report
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBSTDCPP -verify %s -o %t.report
// We do NOT model libcxx03 implementation, but the analyzer should still
// not crash.
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -verify %s
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -DEMULATE_LIBSTDCPP -verify %s
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -verify %s -o %t.report
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -DEMULATE_LIBSTDCPP -verify %s -o %t.report
// RUN: rm -rf %t.report
void clang_analyzer_eval(bool);

View File

@ -1,5 +1,4 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
// expected-no-diagnostics
template<typename T> T &lvalue();
template<typename T> T &&xvalue();
@ -20,6 +19,18 @@ struct X0 {
void g();
void c() const; // expected-note {{'c' declared here}}
void v() volatile; // expected-note {{'v' declared here}}
void r() __restrict__; // expected-note {{'r' declared here}}
void cr() const __restrict__; // expected-note {{'cr' declared here}}
void cv() const volatile;
void vr() volatile __restrict__; // expected-note {{'vr' declared here}}
void cvr() const volatile __restrict__;
void lvalue() &; // expected-note 2 {{'lvalue' declared here}}
void const_lvalue() const&;
void rvalue() &&; // expected-note {{'rvalue' declared here}}
int &operator+(const X0&) &;
float &operator+(const X0&) &&;
@ -32,7 +43,7 @@ struct X0 {
float &h2() const&&;
};
void X0::g() {
void X0::g() { // expected-note {{'g' declared here}}
int &ir1 = f();
int &ir2 = X0::f();
}
@ -69,3 +80,26 @@ void test_ref_qualifier_overloading() {
float &fr3 = xvalue<X0>().h2();
float &fr4 = prvalue<X0>().h2();
}
void test_diagnostics(const volatile X0 &__restrict__ cvr) {
cvr.g(); // expected-error {{'this' argument to member function 'g' has type 'const volatile X0', but function is not marked const or volatile}}
cvr.c(); // expected-error {{not marked volatile}}
cvr.v(); // expected-error {{not marked const}}
cvr.r(); // expected-error {{not marked const or volatile}}
cvr.cr(); // expected-error {{not marked volatile}}
cvr.cv();
cvr.vr(); // expected-error {{not marked const}}
cvr.cvr();
lvalue<X0>().lvalue();
lvalue<X0>().const_lvalue();
lvalue<X0>().rvalue(); // expected-error {{'this' argument to member function 'rvalue' is an lvalue, but function has rvalue ref-qualifier}}
xvalue<X0>().lvalue(); // expected-error {{'this' argument to member function 'lvalue' is an rvalue, but function has non-const lvalue ref-qualifier}}
xvalue<X0>().const_lvalue();
xvalue<X0>().rvalue();
prvalue<X0>().lvalue(); // expected-error {{'this' argument to member function 'lvalue' is an rvalue, but function has non-const lvalue ref-qualifier}}
prvalue<X0>().const_lvalue();
prvalue<X0>().rvalue();
}

View File

@ -215,7 +215,7 @@ template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}}
template<typename T>
void i(T t) {
for (auto u : t) { // expected-error {{invalid range expression of type 'X::A *'; no viable 'begin' function available}} \
expected-error {{member function 'begin' not viable}} \
expected-error {{'this' argument to member function 'begin' has type 'const X::A', but function is not marked const}} \
expected-note {{when looking up 'begin' function}}
}

View File

@ -0,0 +1,6 @@
# Empty lines and line started with # are ignored
-Werror
# Language
-std=c99

View File

@ -0,0 +1,2 @@
# nested inclusion
@config-3.cfg

View File

@ -0,0 +1,2 @@
# nested inclusion
@config/config-4.cfg

View File

@ -0,0 +1 @@
-Wundefined-func-template

View File

@ -0,0 +1,2 @@
-L/usr/local/lib
-stdlib=libc++

View File

@ -0,0 +1,2 @@
--serialize-diagnostics diag.ser
-target

View File

@ -0,0 +1 @@
--config config-5

View File

@ -0,0 +1 @@
-isysroot /opt/data

View File

@ -0,0 +1 @@
-target i386

View File

@ -0,0 +1 @@
-target i383

View File

@ -0,0 +1 @@
-target x86_64

View File

@ -0,0 +1 @@
-target x86_64

View File

@ -0,0 +1 @@
-target x86_64

View File

@ -0,0 +1 @@
-Wall

View File

@ -0,0 +1 @@
-target i386

View File

@ -0,0 +1,54 @@
//--- No more than one '--config' may be specified.
//
// RUN: not %clang --config 1.cfg --config 2.cfg 2>&1 | FileCheck %s -check-prefix CHECK-DUPLICATE
// CHECK-DUPLICATE: no more than one option '--config' is allowed
//--- '--config' must be followed by config file name.
//
// RUN: not %clang --config 2>&1 | FileCheck %s -check-prefix CHECK-MISSING-FILE
// CHECK-MISSING-FILE: argument to '--config' is missing (expected 1 value)
//--- '--config' must not be found in config files.
//
// RUN: not %clang --config %S/Inputs/config-6.cfg 2>&1 | FileCheck %s -check-prefix CHECK-NESTED
// CHECK-NESTED: option '--config' is not allowed inside configuration file
//--- Argument of '--config' must be existing file, if it is specified by path.
//
// RUN: not %clang --config somewhere/nonexistent-config-file 2>&1 | FileCheck %s -check-prefix CHECK-NONEXISTENT
// CHECK-NONEXISTENT: configuration file '{{.*}}somewhere/nonexistent-config-file' does not exist
//--- Argument of '--config' must exist somewhere in well-known directories, if it is specified by bare name.
//
// RUN: not %clang --config-system-dir= --config-user-dir= --config nonexistent-config-file 2>&1 | FileCheck %s -check-prefix CHECK-NOTFOUND0
// CHECK-NOTFOUND0: configuration file 'nonexistent-config-file.cfg' cannot be found
// CHECK-NOTFOUND0-NEXT: was searched for in the directory:
// CHECK-NOTFOUND0-NOT: was searched for in the directory:
//
// RUN: not %clang --config-system-dir= --config-user-dir=%S/Inputs/config2 --config nonexistent-config-file 2>&1 | FileCheck %s -check-prefix CHECK-NOTFOUND1
// CHECK-NOTFOUND1: configuration file 'nonexistent-config-file.cfg' cannot be found
// CHECK-NOTFOUND1-NEXT: was searched for in the directory: {{.*}}/Inputs/config2
// CHECK-NOTFOUND1-NEXT: was searched for in the directory:
// CHECK-NOTFOUND1-NOT: was searched for in the directory:
//
// RUN: not %clang --config-system-dir=%S/Inputs/config --config-user-dir= --config nonexistent-config-file 2>&1 | FileCheck %s -check-prefix CHECK-NOTFOUND2
// CHECK-NOTFOUND2: configuration file 'nonexistent-config-file.cfg' cannot be found
// CHECK-NOTFOUND2-NEXT: was searched for in the directory: {{.*}}/Inputs/config
// CHECK-NOTFOUND2-NEXT: was searched for in the directory:
// CHECK-NOTFOUND2-NOT: was searched for in the directory:
//
// RUN: not %clang --config-system-dir=%S/Inputs/config --config-user-dir=%S/Inputs/config2 --config nonexistent-config-file 2>&1 | FileCheck %s -check-prefix CHECK-NOTFOUND3
// CHECK-NOTFOUND3: configuration file 'nonexistent-config-file.cfg' cannot be found
// CHECK-NOTFOUND3-NEXT: was searched for in the directory: {{.*}}/Inputs/config2
// CHECK-NOTFOUND3-NEXT: was searched for in the directory: {{.*}}/Inputs/config
// CHECK-NOTFOUND3-NEXT: was searched for in the directory:
//--- Argument in config file cannot cross the file boundary
//
// RUN: not %clang --config %S/Inputs/config-5.cfg x86_64-unknown-linux-gnu -c %s 2>&1 | FileCheck %s -check-prefix CHECK-CROSS
// CHECK-CROSS: error: argument to '-target' is missing

72
test/Driver/config-file.c Normal file
View File

@ -0,0 +1,72 @@
//--- Config file search directories
//
// RUN: %clang --config-system-dir=%S/Inputs/config --config-user-dir=%S/Inputs/config2 -o /dev/null -v 2>&1 | FileCheck %s -check-prefix CHECK-DIRS
// CHECK-DIRS: System configuration file directory: {{.*}}/Inputs/config
// CHECK-DIRS: User configuration file directory: {{.*}}/Inputs/config2
//--- Config file (full path) in output of -###
//
// RUN: %clang --config %S/Inputs/config-1.cfg -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-HHH
// CHECK-HHH: Configuration file: {{.*}}Inputs{{.}}config-1.cfg
// CHECK-HHH: -Werror
// CHECK-HHH: -std=c99
//--- Config file (full path) in output of -v
//
// RUN: %clang --config %S/Inputs/config-1.cfg -c %s -o /dev/null -v 2>&1 | FileCheck %s -check-prefix CHECK-V
// CHECK-V: Configuration file: {{.*}}Inputs{{.}}config-1.cfg
// CHECK-V: -Werror
// CHECK-V: -std=c99
//--- Config file in output of -###
//
// RUN: %clang --config-system-dir=%S/Inputs --config-user-dir= --config config-1.cfg -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-HHH2
// CHECK-HHH2: Configuration file: {{.*}}Inputs{{.}}config-1.cfg
// CHECK-HHH2: -Werror
// CHECK-HHH2: -std=c99
//--- Config file in output of -v
//
// RUN: %clang --config-system-dir=%S/Inputs --config-user-dir= --config config-1.cfg -c %s -o /dev/null -v 2>&1 | FileCheck %s -check-prefix CHECK-V2
// CHECK-V2: Configuration file: {{.*}}Inputs{{.}}config-1.cfg
// CHECK-V2: -Werror
// CHECK-V2: -std=c99
//--- Nested config files
//
// RUN: %clang --config-system-dir=%S/Inputs --config-user-dir= --config config-2.cfg -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-NESTED
// CHECK-NESTED: Configuration file: {{.*}}Inputs{{.}}config-2.cfg
// CHECK-NESTED: -Wundefined-func-template
// RUN: %clang --config-system-dir=%S/Inputs --config-user-dir= --config config-2.cfg -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-NESTED2
// CHECK-NESTED2: Configuration file: {{.*}}Inputs{{.}}config-2.cfg
// CHECK-NESTED2: -Wundefined-func-template
// RUN: %clang --config %S/Inputs/config-2a.cfg -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-NESTEDa
// CHECK-NESTEDa: Configuration file: {{.*}}Inputs{{.}}config-2a.cfg
// CHECK-NESTEDa: -isysroot
// CHECK-NESTEDa-SAME: /opt/data
// RUN: %clang --config-system-dir=%S/Inputs --config-user-dir= --config config-2a.cfg -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-NESTED2a
// CHECK-NESTED2a: Configuration file: {{.*}}Inputs{{.}}config-2a.cfg
// CHECK-NESTED2a: -isysroot
// CHECK-NESTED2a-SAME: /opt/data
//--- Unused options in config file do not produce warnings
//
// RUN: %clang --config %S/Inputs/config-4.cfg -c %s -o /dev/null -v 2>&1 | FileCheck %s -check-prefix CHECK-UNUSED
// CHECK-UNUSED-NOT: argument unused during compilation:
//--- User directory is searched first.
//
// RUN: %clang --config-system-dir=%S/Inputs/config --config-user-dir=%S/Inputs/config2 --config config-4 -c %s -o /dev/null -v 2>&1 | FileCheck %s -check-prefix CHECK-PRECEDENCE
// CHECK-PRECEDENCE: Configuration file: {{.*}}Inputs{{.}}config2{{.}}config-4.cfg
// CHECK-PRECEDENCE: -Wall

View File

@ -0,0 +1,51 @@
// REQUIRES: x86-registered-target
//--- Invocation `clang --config x86_64-qqq -m32` loads `i386-qqq.cfg` if the latter exists.
//
// RUN: %clang --config-system-dir=%S/Inputs/config --config-user-dir= --config x86_64-qqq -m32 -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD
// CHECK-RELOAD: Target: i386
// CHECK-RELOAD: Configuration file: {{.*}}Inputs{{.}}config{{.}}i386-qqq.cfg
//--- Invocation `clang --config x86_64-qqq2 -m32` loads `i386.cfg` if the latter exists in another search directory.
//
// RUN: %clang --config-system-dir=%S/Inputs/config --config-user-dir=%S/Inputs/config2 --config x86_64-qqq2 -m32 -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1
// CHECK-RELOAD1: Target: i386
// CHECK-RELOAD1: Configuration file: {{.*}}Inputs{{.}}config2{{.}}i386.cfg
//--- Invocation `clang --config x86_64-qqq2 -m32` loads `x86_64-qqq2.cfg` if `i386-qqq2.cfg` and `i386.cfg` do not exist.
//
// RUN: %clang --config-system-dir=%S/Inputs/config --config-user-dir= --config x86_64-qqq2 -m32 -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD2
// note: target is overriden due to -m32
// CHECK-RELOAD2: Target: i386
// CHECK-RELOAD2: Configuration file: {{.*}}Inputs{{.}}config{{.}}x86_64-qqq2.cfg
//--- Invocation `clang --config i386-qqq3 -m64` loads `x86_64.cfg` if `x86_64-qqq3.cfg` does not exist.
//
// RUN: %clang --config-system-dir=%S/Inputs/config --config-user-dir= --config i386-qqq3 -m64 -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD3
// CHECK-RELOAD3: Target: x86_64
// CHECK-RELOAD3: Configuration file: {{.*}}Inputs{{.}}config{{.}}x86_64.cfg
//--- Invocation `clang --config x86_64-qqq -target i386` loads `i386-qqq.cfg` if the latter exists.
//
// RUN: %clang --config-system-dir=%S/Inputs/config --config-user-dir= --config x86_64-qqq -target i386 -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD4
// CHECK-RELOAD4: Target: i386
// CHECK-RELOAD4: Configuration file: {{.*}}Inputs{{.}}config{{.}}i386-qqq.cfg
//--- Invocation `clang --config x86_64-qqq2 -target i386` loads `x86_64-qqq2.cfg` if `i386-qqq2.cfg` and `i386.cfg` do not exist.
//
// RUN: %clang --config-system-dir=%S/Inputs/config --config-user-dir= --config x86_64-qqq2 -target i386 -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD5
// note: target is overriden due to -target i386
// CHECK-RELOAD5: Target: i386
// CHECK-RELOAD5: Configuration file: {{.*}}Inputs{{.}}config{{.}}x86_64-qqq2.cfg
//--- Invocation `clang --config x86_64-qqq -target i386 -m64` loads `x86_64-qqq.cfg`.
//
// RUN: %clang --config-system-dir=%S/Inputs/config --config-user-dir= --config x86_64-qqq -target i386 -m64 -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD6
// CHECK-RELOAD6: Target: x86_64
// CHECK-RELOAD6: Configuration file: {{.*}}Inputs{{.}}config{{.}}x86_64-qqq.cfg

View File

@ -0,0 +1,98 @@
// REQUIRES: shell
// REQUIRES: x86-registered-target
//--- If config file is specified by relative path (workdir/cfg-s2), it is searched for by that path.
//
// RUN: mkdir -p %T/workdir
// RUN: echo "@subdir/cfg-s2" > %T/workdir/cfg-1
// RUN: mkdir -p %T/workdir/subdir
// RUN: echo "-Wundefined-var-template" > %T/workdir/subdir/cfg-s2
//
// RUN: ( cd %T && %clang --config workdir/cfg-1 -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-REL )
//
// CHECK-REL: Configuration file: {{.*}}/workdir/cfg-1
// CHECK-REL: -Wundefined-var-template
//--- Invocation qqq-clang-g++ tries to find config file qqq-clang-g++.cfg first.
//
// RUN: mkdir -p %T/testdmode
// RUN: [ ! -s %T/testdmode/qqq-clang-g++ ] || rm %T/testdmode/qqq-clang-g++
// RUN: ln -s %clang %T/testdmode/qqq-clang-g++
// RUN: echo "-Wundefined-func-template" > %T/testdmode/qqq-clang-g++.cfg
// RUN: echo "-Werror" > %T/testdmode/qqq.cfg
// RUN: %T/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir= -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix FULL-NAME
//
// FULL-NAME: Configuration file: {{.*}}/testdmode/qqq-clang-g++.cfg
// FULL-NAME: -Wundefined-func-template
// FULL-NAME-NOT: -Werror
//
//--- File specified by --config overrides config inferred from clang executable.
//
// RUN: %T/testdmode/qqq-clang-g++ --config-system-dir=%S/Inputs/config --config-user-dir= --config i386-qqq -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-EXPLICIT
//
// CHECK-EXPLICIT: Configuration file: {{.*}}/Inputs/config/i386-qqq.cfg
//
//--- Invocation qqq-clang-g++ tries to find config file qqq.cfg if qqq-clang-g++.cfg is not found.
//
// RUN: rm %T/testdmode/qqq-clang-g++.cfg
// RUN: %T/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir= -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix SHORT-NAME
//
// SHORT-NAME: Configuration file: {{.*}}/testdmode/qqq.cfg
// SHORT-NAME: -Werror
// SHORT-NAME-NOT: -Wundefined-func-template
//--- Config files are searched for in binary directory as well.
//
// RUN: mkdir -p %T/testbin
// RUN: [ ! -s %T/testbin/clang ] || rm %T/testbin/clang
// RUN: ln -s %clang %T/testbin/clang
// RUN: echo "-Werror" > %T/testbin/aaa.cfg
// RUN: %T/testbin/clang --config-system-dir= --config-user-dir= --config aaa.cfg -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-BIN
//
// CHECK-BIN: Configuration file: {{.*}}/testbin/aaa.cfg
// CHECK-BIN: -Werror
//--- If command line contains options that change triple (for instance, -m32), clang tries
// reloading config file.
//--- When reloading config file, x86_64-clang-g++ tries to find config i386-clang-g++.cfg first.
//
// RUN: mkdir -p %T/testreload
// RUN: [ ! -s %T/testreload/x86_64-clang-g++ ] || rm %T/testreload/x86_64-clang-g++
// RUN: ln -s %clang %T/testreload/x86_64-clang-g++
// RUN: echo "-Wundefined-func-template" > %T/testreload/i386-clang-g++.cfg
// RUN: echo "-Werror" > %T/testreload/i386.cfg
// RUN: %T/testreload/x86_64-clang-g++ --config-system-dir= --config-user-dir= -c -m32 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD
//
// CHECK-RELOAD: Configuration file: {{.*}}/testreload/i386-clang-g++.cfg
// CHECK-RELOAD: -Wundefined-func-template
// CHECK-RELOAD-NOT: -Werror
//--- If config file is specified by --config and its name does not start with architecture, it is used without reloading.
//
// RUN: %T/testreload/x86_64-clang-g++ --config-system-dir=%S/Inputs --config-user-dir= --config config-3 -c -m32 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1a
//
// CHECK-RELOAD1a: Configuration file: {{.*}}/Inputs/config-3.cfg
//
// RUN: %T/testreload/x86_64-clang-g++ --config-system-dir=%S/Inputs --config-user-dir= --config config-3 -c -target i386 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1b
//
// CHECK-RELOAD1b: Configuration file: {{.*}}/Inputs/config-3.cfg
//--- If config file is specified by --config and its name starts with architecture, it is reloaded.
//
// RUN: %T/testreload/x86_64-clang-g++ --config-system-dir=%S/Inputs/config --config-user-dir= --config x86_64-qqq -c -m32 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1c
//
// CHECK-RELOAD1c: Configuration file: {{.*}}/Inputs/config/i386-qqq.cfg
//--- x86_64-clang-g++ tries to find config i386.cfg if i386-clang-g++.cfg is not found.
//
// RUN: rm %T/testreload/i386-clang-g++.cfg
// RUN: %T/testreload/x86_64-clang-g++ --config-system-dir= --config-user-dir= -c -m32 -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1d
//
// CHECK-RELOAD1d: Configuration file: {{.*}}/testreload/i386.cfg
// CHECK-RELOAD1d: -Werror
// CHECK-RELOAD1d-NOT: -Wundefined-func-template

View File

@ -205,7 +205,8 @@
// RUN: %clang -target x86_64-apple-ios -miphonesimulator-version-min=10.0 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-TNO-OSV3 %s
// CHECK-VERSION-TNO-OSV3: overriding '-mios-simulator-version-min=10.0' option with '--target=x86_64-apple-ios'
// CHECK-VERSION-TNO-OSV3: "x86_64-apple-ios10.0.0-simulator"
// CHECK-VERSION-TNO-OSV3-NOT: overriding '-mios-simulator-version-min
// CHECK-VERSION-TNO-OSV3-NOT: argument unused during compilation
// RUN: %clang -target arm64-apple-ios10.1.0 -miphoneos-version-min=10.1.0.1 -c %s -### 2>&1 | \
@ -235,6 +236,24 @@
// RUN: FileCheck --check-prefix=CHECK-VERSION-TIGNORE-OSV4 %s
// CHECK-VERSION-TIGNORE-OSV4: "thumbv7k-apple-watchos3.0.0"
// Target without OS version inlcudes the OS given by -m<os>-version-min arguments:
// RUN: %clang -target x86_64-apple-macos -mmacos-version-min=10.11 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-USE-OS-ARG1 %s
// CHECK-VERSION-USE-OS-ARG1: "x86_64-apple-macosx10.11.0"
// RUN: %clang -target arm64-apple-ios -mios-version-min=9.0 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-USE-OS-ARG2 %s
// CHECK-VERSION-USE-OS-ARG2: "arm64-apple-ios9.0.0"
// RUN: %clang -target arm64-apple-tvos -mtvos-version-min=10.0 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-USE-OS-ARG3 %s
// CHECK-VERSION-USE-OS-ARG3: "arm64-apple-tvos10.0.0"
// RUN: %clang -target armv7k-apple-watchos -mwatchos-version-min=4 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-USE-OS-ARG4 %s
// CHECK-VERSION-USE-OS-ARG4: "thumbv7k-apple-watchos4.0.0"
// Target with OS version is not overriden by environment variables:
// RUN: env MACOSX_DEPLOYMENT_TARGET=10.1 \

View File

@ -37,7 +37,9 @@ class C {
~C();
};
// RUN: c-index-test -test-annotate-tokens=%s:1:1:38:1 %s -fno-delayed-template-parsing | FileCheck %s
auto test5(X) -> X;
// RUN: c-index-test -test-annotate-tokens=%s:1:1:41:1 %s -std=c++14 -fno-delayed-template-parsing | FileCheck %s
// CHECK: Keyword: "struct" [1:1 - 1:7] StructDecl=bonk:1:8 (Definition)
// CHECK: Identifier: "bonk" [1:8 - 1:12] StructDecl=bonk:1:8 (Definition)
// CHECK: Punctuation: "{" [1:13 - 1:14] StructDecl=bonk:1:8 (Definition)
@ -184,6 +186,14 @@ class C {
// CHECK: Punctuation: "}" [29:22 - 29:23] CompoundStmt=
// CHECK: Punctuation: "~" [37:3 - 37:4] CXXDestructor=~C:37:3
// CHECK: Identifier: "C" [37:4 - 37:5] CXXDestructor=~C:37:3
// CHECK: Keyword: "auto" [40:1 - 40:5] FunctionDecl=test5:40:6
// CHECK: Identifier: "test5" [40:6 - 40:11] FunctionDecl=test5:40:6
// CHECK: Punctuation: "(" [40:11 - 40:12] FunctionDecl=test5:40:6
// CHECK: Identifier: "X" [40:12 - 40:13] TypeRef=struct X:7:8
// CHECK: Punctuation: ")" [40:13 - 40:14] FunctionDecl=test5:40:6
// CHECK: Punctuation: "->" [40:15 - 40:17] FunctionDecl=test5:40:6
// CHECK: Identifier: "X" [40:18 - 40:19] TypeRef=struct X:7:8
// CHECK: Punctuation: ";" [40:19 - 40:20]
// RUN: env LIBCLANG_DISABLE_CRASH_RECOVERY=1 c-index-test -test-annotate-tokens=%s:32:1:32:13 %s | FileCheck %s -check-prefix=CHECK2
// CHECK2: Keyword: "if" [32:3 - 32:5] IfStmt=

View File

@ -1,6 +1,10 @@
// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
// expected-no-diagnostics
#ifndef HEADER

View File

@ -1,6 +1,11 @@
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp-simd -x c -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// RUN: %clang_cc1 -fopenmp-simd -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp-simd -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
// expected-no-diagnostics
#ifndef HEADER
#define HEADER

View File

@ -2,6 +2,12 @@
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -x c++ -emit-llvm -std=c++98 %s -o - | FileCheck %s
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -x c++ -emit-llvm -std=c++11 %s -o - | FileCheck %s
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp-simd -fexceptions -fcxx-exceptions -x c++ -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp-simd -fexceptions -fcxx-exceptions -x c++ -emit-llvm -std=c++98 %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp-simd -fexceptions -fcxx-exceptions -x c++ -emit-llvm -std=c++11 %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp-simd -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
// expected-no-diagnostics
int a;

View File

@ -1,5 +1,7 @@
// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s
int foo() {
L1:
foo();

View File

@ -1,5 +1,7 @@
// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s
int foo() {
L1:
foo();

View File

@ -1,6 +1,11 @@
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp-simd -x c -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// RUN: %clang_cc1 -fopenmp-simd -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp-simd -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
// expected-no-diagnostics
// REQUIRES: x86-registered-target
#ifndef HEADER

View File

@ -1,6 +1,11 @@
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp-simd -x c -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// RUN: %clang_cc1 -fopenmp-simd -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp-simd -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
// expected-no-diagnostics
#ifndef HEADER
#define HEADER

View File

@ -1,6 +1,11 @@
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp-simd -x c -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// RUN: %clang_cc1 -fopenmp-simd -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp-simd -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
// expected-no-diagnostics
// REQUIRES: x86-registered-target
#ifndef HEADER

View File

@ -1,6 +1,10 @@
// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
// expected-no-diagnostics
#ifndef HEADER

View File

@ -1,6 +1,11 @@
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
// expected-no-diagnostics
#ifndef HEADER
#define HEADER

View File

@ -1,5 +1,7 @@
// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s
template <class T>
T tmain(T argc) {
#pragma omp barrier

View File

@ -1,6 +1,10 @@
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s
// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -ast-print %s | FileCheck %s
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
// expected-no-diagnostics
#ifndef HEADER

View File

@ -1,6 +1,11 @@
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -triple x86_64-apple-darwin13.4.0 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-apple-darwin13.4.0 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -triple x86_64-apple-darwin13.4.0 -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -triple x86_64-apple-darwin13.4.0 -emit-llvm -o - %s | FileCheck --check-prefix SIMD-ONLY0 %s
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-apple-darwin13.4.0 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -triple x86_64-apple-darwin13.4.0 -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
// expected-no-diagnostics
#ifndef HEADER
#define HEADER

View File

@ -1,5 +1,8 @@
// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-version=45 -triple x86_64-apple-darwin13.4.0 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -std=c++11 -fopenmp-simd -fopenmp-version=45 -triple x86_64-apple-darwin13.4.0 -emit-llvm -o - %s | FileCheck --check-prefix SIMD-ONLY0 %s
// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
//CHECK: call i32 @__kmpc_cancel
//CHECK: br {{.*}}label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
//CHECK: [[EXIT]]:

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