Vendor import of clang trunk r302418:

https://llvm.org/svn/llvm-project/cfe/trunk@302418
This commit is contained in:
Dimitry Andric 2017-05-08 17:13:11 +00:00
parent f0c0337bbf
commit 0a5fb09b59
112 changed files with 2864 additions and 504 deletions
docs
include/clang
lib
test

@ -780,14 +780,14 @@ Use ``__has_feature(cxx_variadic_templates)`` or
``__has_extension(cxx_variadic_templates)`` to determine if support for
variadic templates is enabled.
C++1y
C++14
-----
The features listed below are part of the committee draft for the C++1y
standard. As a result, all these features are enabled with the ``-std=c++1y``
or ``-std=gnu++1y`` option when compiling C++ code.
The features listed below are part of the C++14 standard. As a result, all
these features are enabled with the ``-std=C++14`` or ``-std=gnu++14`` option
when compiling C++ code.
C++1y binary literals
C++14 binary literals
^^^^^^^^^^^^^^^^^^^^^
Use ``__has_feature(cxx_binary_literals)`` or
@ -795,37 +795,37 @@ Use ``__has_feature(cxx_binary_literals)`` or
binary literals (for instance, ``0b10010``) are recognized. Clang supports this
feature as an extension in all language modes.
C++1y contextual conversions
C++14 contextual conversions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Use ``__has_feature(cxx_contextual_conversions)`` or
``__has_extension(cxx_contextual_conversions)`` to determine if the C++1y rules
``__has_extension(cxx_contextual_conversions)`` to determine if the C++14 rules
are used when performing an implicit conversion for an array bound in a
*new-expression*, the operand of a *delete-expression*, an integral constant
expression, or a condition in a ``switch`` statement.
C++1y decltype(auto)
C++14 decltype(auto)
^^^^^^^^^^^^^^^^^^^^
Use ``__has_feature(cxx_decltype_auto)`` or
``__has_extension(cxx_decltype_auto)`` to determine if support
for the ``decltype(auto)`` placeholder type is enabled.
C++1y default initializers for aggregates
C++14 default initializers for aggregates
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Use ``__has_feature(cxx_aggregate_nsdmi)`` or
``__has_extension(cxx_aggregate_nsdmi)`` to determine if support
for default initializers in aggregate members is enabled.
C++1y digit separators
C++14 digit separators
^^^^^^^^^^^^^^^^^^^^^^
Use ``__cpp_digit_separators`` to determine if support for digit separators
using single quotes (for instance, ``10'000``) is enabled. At this time, there
is no corresponding ``__has_feature`` name
C++1y generalized lambda capture
C++14 generalized lambda capture
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Use ``__has_feature(cxx_init_captures)`` or
@ -833,7 +833,7 @@ Use ``__has_feature(cxx_init_captures)`` or
lambda captures with explicit initializers is enabled
(for instance, ``[n(0)] { return ++n; }``).
C++1y generic lambdas
C++14 generic lambdas
^^^^^^^^^^^^^^^^^^^^^
Use ``__has_feature(cxx_generic_lambdas)`` or
@ -841,7 +841,7 @@ Use ``__has_feature(cxx_generic_lambdas)`` or
(polymorphic) lambdas is enabled
(for instance, ``[] (auto x) { return x + 1; }``).
C++1y relaxed constexpr
C++14 relaxed constexpr
^^^^^^^^^^^^^^^^^^^^^^^
Use ``__has_feature(cxx_relaxed_constexpr)`` or
@ -849,7 +849,7 @@ Use ``__has_feature(cxx_relaxed_constexpr)`` or
declarations, local variable modification, and control flow constructs
are permitted in ``constexpr`` functions.
C++1y return type deduction
C++14 return type deduction
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Use ``__has_feature(cxx_return_type_deduction)`` or
@ -857,7 +857,7 @@ Use ``__has_feature(cxx_return_type_deduction)`` or
for return type deduction for functions (using ``auto`` as a return type)
is enabled.
C++1y runtime-sized arrays
C++14 runtime-sized arrays
^^^^^^^^^^^^^^^^^^^^^^^^^^
Use ``__has_feature(cxx_runtime_array)`` or
@ -866,7 +866,7 @@ for arrays of runtime bound (a restricted form of variable-length arrays)
is enabled.
Clang's implementation of this feature is incomplete.
C++1y variable templates
C++14 variable templates
^^^^^^^^^^^^^^^^^^^^^^^^
Use ``__has_feature(cxx_variable_templates)`` or

@ -924,6 +924,19 @@ in
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('cxxStdInitializerListExpr0')"><a name="cxxStdInitializerListExpr0Anchor">cxxStdInitializerListExpr</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXStdInitializerListExpr.html">CXXStdInitializerListExpr</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="cxxStdInitializerListExpr0"><pre>Matches C++ initializer list expressions.
Given
std::vector&lt;int&gt; a({ 1, 2, 3 });
std::vector&lt;int&gt; b = { 4, 5 };
int c[] = { 6, 7 };
std::pair&lt;int, int&gt; d = { 8, 9 };
cxxStdInitializerListExpr()
matches "{ 1, 2, 3 }" and "{ 4, 5 }"
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('cxxTemporaryObjectExpr0')"><a name="cxxTemporaryObjectExpr0Anchor">cxxTemporaryObjectExpr</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="cxxTemporaryObjectExpr0"><pre>Matches functional cast expressions having N != 1 arguments
@ -1160,7 +1173,7 @@ Example matches [&amp;](){return 5;}
<tr><td colspan="4" class="doc" id="materializeTemporaryExpr0"><pre>Matches nodes where temporaries are materialized.
Example: Given
struct T {void func()};
struct T {void func();};
T f();
void g(T);
materializeTemporaryExpr() matches 'f()' in these statements
@ -5233,7 +5246,7 @@ Example matches y in x(y)
<tr><td colspan="4" class="doc" id="hasReceiverType0"><pre>Matches on the receiver of an ObjectiveC Message expression.
Example
matcher = objCMessageExpr(hasRecieverType(asString("UIWebView *")));
matcher = objCMessageExpr(hasReceiverType(asString("UIWebView *")));
matches the [webView ...] message invocation.
NSString *webViewJavaScript = ...
UIWebView *webView = ...

@ -144,8 +144,9 @@ Use these flags together with ``trace-pc-guard`` or ``trace-pc``,
like this: ``-fsanitize-coverage=func,trace-pc-guard``.
When ``edge`` or ``bb`` is used, some of the edges/blocks may still be left
uninstrumented if such instrumentation is considered redundant.
**TODO**: add a user-visible option to disable the optimization.
uninstrumented (pruned) if such instrumentation is considered redundant.
Use ``no-prune`` (e.g. ``-fsanitize-coverage=bb,no-prune,trace-pc-guard``)
to disable pruning. This could be useful for better coverage visualization.
Edge coverage

@ -764,8 +764,6 @@ implementation.
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
#endif
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#define CAPABILITY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(capability(x))

@ -25,7 +25,7 @@ namespace clang {
class Decl;
class IdentifierInfo;
class NestedNameSpecifer;
class NestedNameSpecifier;
class Stmt;
class TemplateParameterList;

@ -1223,6 +1223,20 @@ AST_MATCHER_P(InitListExpr, hasSyntacticForm,
InnerMatcher.matches(*SyntForm, Finder, Builder));
}
/// \brief Matches C++ initializer list expressions.
///
/// Given
/// \code
/// std::vector<int> a({ 1, 2, 3 });
/// std::vector<int> b = { 4, 5 };
/// int c[] = { 6, 7 };
/// std::pair<int, int> d = { 8, 9 };
/// \endcode
/// cxxStdInitializerListExpr()
/// matches "{ 1, 2, 3 }" and "{ 4, 5 }"
const internal::VariadicDynCastAllOfMatcher<Stmt,
CXXStdInitializerListExpr> cxxStdInitializerListExpr;
/// \brief Matches implicit initializers of init list expressions.
///
/// Given

@ -864,6 +864,13 @@ def OpenCLUnrollHint : InheritableAttr {
let Documentation = [OpenCLUnrollHintDocs];
}
def OpenCLIntelReqdSubGroupSize: InheritableAttr {
let Spellings = [GNU<"intel_reqd_sub_group_size">];
let Args = [UnsignedArgument<"SubGroupSize">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [OpenCLIntelReqdSubGroupSizeDocs];
}
// This attribute is both a type attribute, and a declaration attribute (for
// parameter variables).
def OpenCLAccess : Attr {

@ -2216,6 +2216,21 @@ s6.11.5 for details.
}];
}
def OpenCLIntelReqdSubGroupSizeDocs : Documentation {
let Category = DocCatStmt;
let Heading = "__attribute__((intel_reqd_sub_group_size))";
let Content = [{
The optional attribute intel_reqd_sub_group_size can be used to indicate that
the kernel must be compiled and executed with the specified subgroup size. When
this attribute is present, get_max_sub_group_size() is guaranteed to return the
specified integer value. This is important for the correctness of many subgroup
algorithms, and in some cases may be used by the compiler to generate more optimal
code. See `cl_intel_required_subgroup_size
<https://www.khronos.org/registry/OpenCL/extensions/intel/cl_intel_required_subgroup_size.txt>`
for details.
}];
}
def OpenCLAccessDocs : Documentation {
let Category = DocCatStmt;
let Heading = "__read_only, __write_only, __read_write (read_only, write_only, read_write)";

@ -25,11 +25,93 @@
// In libgcc
BUILTIN(__clear_cache, "vv*v*", "i")
// 16-bit multiplications
BUILTIN(__builtin_arm_smulbb, "iii", "nc")
BUILTIN(__builtin_arm_smulbt, "iii", "nc")
BUILTIN(__builtin_arm_smultb, "iii", "nc")
BUILTIN(__builtin_arm_smultt, "iii", "nc")
BUILTIN(__builtin_arm_smulwb, "iii", "nc")
BUILTIN(__builtin_arm_smulwt, "iii", "nc")
// Saturating arithmetic
BUILTIN(__builtin_arm_qadd, "iii", "nc")
BUILTIN(__builtin_arm_qsub, "iii", "nc")
BUILTIN(__builtin_arm_ssat, "iiUi", "nc")
BUILTIN(__builtin_arm_usat, "UiUiUi", "nc")
BUILTIN(__builtin_arm_usat, "UiiUi", "nc")
BUILTIN(__builtin_arm_smlabb, "iiii", "nc")
BUILTIN(__builtin_arm_smlabt, "iiii", "nc")
BUILTIN(__builtin_arm_smlatb, "iiii", "nc")
BUILTIN(__builtin_arm_smlatt, "iiii", "nc")
BUILTIN(__builtin_arm_smlawb, "iiii", "nc")
BUILTIN(__builtin_arm_smlawt, "iiii", "nc")
BUILTIN(__builtin_arm_ssat16, "iii", "nc")
BUILTIN(__builtin_arm_usat16, "iii", "nc")
BUILTIN(__builtin_arm_sxtab16, "iii", "nc")
BUILTIN(__builtin_arm_sxtb16, "ii", "nc")
BUILTIN(__builtin_arm_uxtab16, "iii", "nc")
BUILTIN(__builtin_arm_uxtb16, "ii", "nc")
BUILTIN(__builtin_arm_sel, "iii", "nc")
BUILTIN(__builtin_arm_qadd8, "iii", "nc")
BUILTIN(__builtin_arm_qsub8, "iii", "nc")
BUILTIN(__builtin_arm_sadd8, "iii", "nc")
BUILTIN(__builtin_arm_shadd8, "iii", "nc")
BUILTIN(__builtin_arm_shsub8, "iii", "nc")
BUILTIN(__builtin_arm_ssub8, "iii", "nc")
BUILTIN(__builtin_arm_uadd8, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uhadd8, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uhsub8, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uqadd8, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uqsub8, "UiUiUi", "nc")
BUILTIN(__builtin_arm_usub8, "UiUiUi", "nc")
// Sum of 8-bit absolute differences
BUILTIN(__builtin_arm_usad8, "UiUiUi", "nc")
BUILTIN(__builtin_arm_usada8, "UiUiUiUi", "nc")
// Parallel 16-bit addition and subtraction
BUILTIN(__builtin_arm_qadd16, "iii", "nc")
BUILTIN(__builtin_arm_qasx, "iii", "nc")
BUILTIN(__builtin_arm_qsax, "iii", "nc")
BUILTIN(__builtin_arm_qsub16, "iii", "nc")
BUILTIN(__builtin_arm_sadd16, "iii", "nc")
BUILTIN(__builtin_arm_sasx, "iii", "nc")
BUILTIN(__builtin_arm_shadd16, "iii", "nc")
BUILTIN(__builtin_arm_shasx, "iii", "nc")
BUILTIN(__builtin_arm_shsax, "iii", "nc")
BUILTIN(__builtin_arm_shsub16, "iii", "nc")
BUILTIN(__builtin_arm_ssax, "iii", "nc")
BUILTIN(__builtin_arm_ssub16, "iii", "nc")
BUILTIN(__builtin_arm_uadd16, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uasx, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uhadd16, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uhasx, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uhsax, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uhsub16, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uqadd16, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uqasx, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uqsax, "UiUiUi", "nc")
BUILTIN(__builtin_arm_uqsub16, "UiUiUi", "nc")
BUILTIN(__builtin_arm_usax, "UiUiUi", "nc")
BUILTIN(__builtin_arm_usub16, "UiUiUi", "nc")
// Parallel 16-bit multiplication
BUILTIN(__builtin_arm_smlad, "iiii", "nc")
BUILTIN(__builtin_arm_smladx, "iiii", "nc")
BUILTIN(__builtin_arm_smlald, "LLiiiLLi", "nc")
BUILTIN(__builtin_arm_smlaldx, "LLiiiLLi", "nc")
BUILTIN(__builtin_arm_smlsd, "iiii", "nc")
BUILTIN(__builtin_arm_smlsdx, "iiii", "nc")
BUILTIN(__builtin_arm_smlsld, "LLiiiLLi", "nc")
BUILTIN(__builtin_arm_smlsldx, "LLiiiLLi", "nc")
BUILTIN(__builtin_arm_smuad, "iii", "nc")
BUILTIN(__builtin_arm_smuadx, "iii", "nc")
BUILTIN(__builtin_arm_smusd, "iii", "nc")
BUILTIN(__builtin_arm_smusdx, "iii", "nc")
// Bit manipulation
BUILTIN(__builtin_arm_rbit, "UiUi", "nc")

@ -668,6 +668,12 @@ TARGET_BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "", "bmi2")
// TBM
TARGET_BUILTIN(__builtin_ia32_bextri_u32, "UiUiIUi", "", "tbm")
// LWP
TARGET_BUILTIN(__builtin_ia32_llwpcb, "vv*", "", "lwp")
TARGET_BUILTIN(__builtin_ia32_slwpcb, "v*", "", "lwp")
TARGET_BUILTIN(__builtin_ia32_lwpins32, "UcUiUiUi", "", "lwp")
TARGET_BUILTIN(__builtin_ia32_lwpval32, "vUiUiUi", "", "lwp")
// SHA
TARGET_BUILTIN(__builtin_ia32_sha1rnds4, "V4iV4iV4iIc", "", "sha")
TARGET_BUILTIN(__builtin_ia32_sha1nexte, "V4iV4iV4i", "", "sha")

@ -69,6 +69,8 @@ TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "", "tbm")
TARGET_BUILTIN(__builtin_ia32_lwpins64, "UcULLiUiUi", "", "lwp")
TARGET_BUILTIN(__builtin_ia32_lwpval64, "vULLiUiUi", "", "lwp")
TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_gpr_mask, "V8LLiLLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pbroadcastq128_gpr_mask, "V2LLiULLiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pbroadcastq256_gpr_mask, "V4LLiULLiV4LLiUc","","avx512vl")

@ -475,8 +475,6 @@ def warn_pragma_pop_macro_no_push : Warning<
def warn_pragma_message : Warning<"%0">,
InGroup<PoundPragmaMessage>, DefaultWarnNoWerror;
def err_pragma_message : Error<"%0">;
def err_pragma_module_import_expected_module_name : Error<
"expected %select{identifier in|'.' or end of directive after}0 module name">;
def warn_pragma_ignored : Warning<"unknown pragma ignored">,
InGroup<UnknownPragmas>, DefaultIgnore;
def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
@ -511,6 +509,22 @@ def warn_pragma_debug_unexpected_command : Warning<
"unexpected debug command '%0'">, InGroup<IgnoredPragmas>;
def warn_pragma_debug_missing_argument : Warning<
"missing argument to debug command '%0'">, InGroup<IgnoredPragmas>;
// #pragma module
def err_pp_expected_module_name : Error<
"expected %select{identifier after '.' in |}0module name">;
def err_pp_module_begin_wrong_module : Error<
"must specify '-fmodule-name=%0' to enter %select{|submodule of }1"
"this module%select{ (current module is %3)|}2">;
def err_pp_module_begin_no_module_map : Error<
"no module map available for module %0">;
def err_pp_module_begin_no_submodule : Error<
"submodule %0.%1 not declared in module map">;
def err_pp_module_begin_without_module_end : Error<
"no matching '#pragma clang module end' for this "
"'#pragma clang module begin'">;
def err_pp_module_end_without_module_begin : Error<
"no matching '#pragma clang module begin' for this "
"'#pragma clang module end'">;
def err_defined_macro_name : Error<"'defined' cannot be used as a macro name">;
def err_paste_at_start : Error<

@ -730,6 +730,9 @@ def err_super_in_lambda_unsupported : Error<
def warn_pragma_unused_undeclared_var : Warning<
"undeclared variable %0 used as an argument for '#pragma unused'">,
InGroup<IgnoredPragmas>;
def warn_atl_uuid_deprecated : Warning<
"specifying 'uuid' as an ATL attribute is deprecated; use __declspec instead">,
InGroup<DeprecatedDeclarations>;
def warn_pragma_unused_expected_var_arg : Warning<
"only variables can be arguments to '#pragma unused'">,
InGroup<IgnoredPragmas>;
@ -2088,7 +2091,7 @@ def err_enum_invalid_underlying : Error<
"non-integral type %0 is an invalid underlying type">;
def err_enumerator_too_large : Error<
"enumerator value is not representable in the underlying type %0">;
def ext_enumerator_too_large : ExtWarn<
def ext_enumerator_too_large : Extension<
"enumerator value is not representable in the underlying type %0">,
InGroup<MicrosoftEnumValue>;
def err_enumerator_wrapped : Error<
@ -2868,7 +2871,8 @@ def warn_partial_availability : Warning<"%0 is only available conditionally">,
def note_partial_availability_silence : Note<
"explicitly redeclare %0 to silence this warning">;
def note_unguarded_available_silence : Note<
"enclose %0 in an @available check to silence this warning">;
"enclose %0 in %select{an @available|a __builtin_available}1 check to silence"
" this warning">;
def warn_partial_message : Warning<"%0 is partial: %1">,
InGroup<UnguardedAvailability>, DefaultIgnore;
def warn_partial_fwdclass_message : Warning<
@ -4759,7 +4763,7 @@ def ext_forward_ref_enum : Extension<
"ISO C forbids forward references to 'enum' types">;
def err_forward_ref_enum : Error<
"ISO C++ forbids forward references to 'enum' types">;
def ext_ms_forward_ref_enum : Extension<
def ext_ms_forward_ref_enum : ExtWarn<
"forward references to 'enum' types are a Microsoft extension">,
InGroup<MicrosoftEnumForwardReference>;
def ext_forward_ref_enum_def : Extension<
@ -7920,7 +7924,11 @@ def warn_empty_switch_body : Warning<
def note_empty_body_on_separate_line : Note<
"put the semicolon on a separate line to silence this warning">;
def err_va_start_used_in_non_variadic_function : Error<
def err_va_start_captured_stmt : Error<
"'va_start' cannot be used in a captured statement">;
def err_va_start_outside_function : Error<
"'va_start' cannot be used outside a function">;
def err_va_start_fixed_function : Error<
"'va_start' used in function with fixed args">;
def err_va_start_used_in_wrong_abi_function : Error<
"'va_start' used in %select{System V|Win64}0 ABI function">;
@ -8297,6 +8305,8 @@ def err_sampler_argument_required : Error<
"sampler_t variable required - got %0">;
def err_wrong_sampler_addressspace: Error<
"sampler type cannot be used with the __local and __global address space qualifiers">;
def err_opencl_nonconst_global_sampler : Error<
"global sampler requires a const or constant address space qualifier">;
def err_opencl_cast_non_zero_to_event_t : Error<
"cannot cast non-zero value '%0' to 'event_t'">;
def err_opencl_global_invalid_addr_space : Error<
@ -8971,6 +8981,9 @@ def warn_nullability_lost : Warning<
"implicit conversion from nullable pointer %0 to non-nullable pointer "
"type %1">,
InGroup<NullableToNonNullConversion>, DefaultIgnore;
def warn_zero_as_null_pointer_constant : Warning<
"zero as null pointer constant">,
InGroup<DiagGroup<"zero-as-null-pointer-constant">>, DefaultIgnore;
def err_nullability_cs_multilevel : Error<
"nullability keyword %0 cannot be applied to multi-level pointer type %1">;

@ -297,6 +297,9 @@ def fsanitize_coverage_trace_pc
def fsanitize_coverage_trace_pc_guard
: Flag<["-"], "fsanitize-coverage-trace-pc-guard">,
HelpText<"Enable PC tracing with guard in sanitizer coverage">;
def fsanitize_coverage_no_prune
: Flag<["-"], "fsanitize-coverage-no-prune">,
HelpText<"Disable coverage pruning (i.e. instrument all blocks/edges)">;
def fprofile_instrument_EQ : Joined<["-"], "fprofile-instrument=">,
HelpText<"Enable PGO instrumentation. The accepted value is clang, llvm, "
"or none">;

@ -57,6 +57,7 @@ public:
UbuntuXenial,
UbuntuYakkety,
UbuntuZesty,
UbuntuArtful,
UnknownDistro
};
@ -110,9 +111,9 @@ public:
}
bool IsUbuntu() const {
return DistroVal >= UbuntuHardy && DistroVal <= UbuntuZesty;
return DistroVal >= UbuntuHardy && DistroVal <= UbuntuArtful;
}
/// @}
};

@ -70,13 +70,21 @@ public:
/// All elements begin with either '+' or '-'
const flags_list &flags() const { return Flags; }
flags_list &flags() { return Flags; }
/// Add a flag to the flags list
/// \p Flag must be a flag accepted by the driver with its leading '-' removed,
/// and replaced with either:
/// '-' which contraindicates using this multilib with that flag
/// or:
/// '+' which promotes using this multilib in the presence of that flag
/// otherwise '-print-multi-lib' will not emit them correctly.
Multilib &flag(StringRef F) {
assert(F.front() == '+' || F.front() == '-');
Flags.push_back(F);
return *this;
}
LLVM_DUMP_METHOD void dump() const;
/// \brief print summary of the Multilib
void print(raw_ostream &OS) const;
@ -150,6 +158,7 @@ public:
unsigned size() const { return Multilibs.size(); }
LLVM_DUMP_METHOD void dump() const;
void print(raw_ostream &OS) const;
MultilibSet &setIncludeDirsCallback(IncludeDirsFunc F) {

@ -1688,6 +1688,8 @@ def mllvm : Separate<["-"], "mllvm">, Flags<[CC1Option,CC1AsOption,CoreOption]>,
HelpText<"Additional arguments to forward to LLVM's option processing">;
def mmacosx_version_min_EQ : Joined<["-"], "mmacosx-version-min=">,
Group<m_Group>, HelpText<"Set Mac OS X deployment target">;
def mmacos_version_min_EQ : Joined<["-"], "mmacos-version-min=">,
Group<m_Group>, Alias<mmacosx_version_min_EQ>;
def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>, Flags<[CC1Option]>,
HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard">;
def mno_ms_bitfields : Flag<["-"], "mno-ms-bitfields">, Group<m_Group>,
@ -1750,6 +1752,7 @@ def mno_bmi : Flag<["-"], "mno-bmi">, Group<m_x86_Features_Group>;
def mno_bmi2 : Flag<["-"], "mno-bmi2">, Group<m_x86_Features_Group>;
def mno_popcnt : Flag<["-"], "mno-popcnt">, Group<m_x86_Features_Group>;
def mno_tbm : Flag<["-"], "mno-tbm">, Group<m_x86_Features_Group>;
def mno_lwp : Flag<["-"], "mno-lwp">, Group<m_x86_Features_Group>;
def mno_fma4 : Flag<["-"], "mno-fma4">, Group<m_x86_Features_Group>;
def mno_fma : Flag<["-"], "mno-fma">, Group<m_x86_Features_Group>;
def mno_xop : Flag<["-"], "mno-xop">, Group<m_x86_Features_Group>;
@ -1949,6 +1952,7 @@ def mbmi : Flag<["-"], "mbmi">, Group<m_x86_Features_Group>;
def mbmi2 : Flag<["-"], "mbmi2">, Group<m_x86_Features_Group>;
def mpopcnt : Flag<["-"], "mpopcnt">, Group<m_x86_Features_Group>;
def mtbm : Flag<["-"], "mtbm">, Group<m_x86_Features_Group>;
def mlwp : Flag<["-"], "mlwp">, Group<m_x86_Features_Group>;
def mfma4 : Flag<["-"], "mfma4">, Group<m_x86_Features_Group>;
def mfma : Flag<["-"], "mfma">, Group<m_x86_Features_Group>;
def mxop : Flag<["-"], "mxop">, Group<m_x86_Features_Group>;

@ -160,6 +160,7 @@ CODEGENOPT(SanitizeCoverageTracePC, 1, 0) ///< Enable PC tracing
///< in sanitizer coverage.
CODEGENOPT(SanitizeCoverageTracePCGuard, 1, 0) ///< Enable PC tracing with guard
///< in sanitizer coverage.
CODEGENOPT(SanitizeCoverageNoPrune, 1, 0) ///< Disable coverage pruning.
CODEGENOPT(SanitizeStats , 1, 0) ///< Collect statistics for sanitizers.
CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.
CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float.

@ -146,6 +146,8 @@ public:
return *CurrentASTUnit;
}
Module *getCurrentModule() const;
std::unique_ptr<ASTUnit> takeCurrentASTUnit() {
return std::move(CurrentASTUnit);
}

@ -538,9 +538,15 @@ public:
///
/// \param File The module map file.
/// \param IsSystem Whether this file is in a system header directory.
/// \param ID If the module map file is already mapped (perhaps as part of
/// processing a preprocessed module), the ID of the file.
/// \param Offset [inout] An offset within ID to start parsing. On exit,
/// filled by the end of the parsed contents (either EOF or the
/// location of an end-of-module-map pragma).
///
/// \returns true if an error occurred, false otherwise.
bool loadModuleMapFile(const FileEntry *File, bool IsSystem);
bool loadModuleMapFile(const FileEntry *File, bool IsSystem,
FileID ID = FileID(), unsigned *Offset = nullptr);
/// \brief Collect the set of all known, top-level modules.
///
@ -686,7 +692,9 @@ private:
LoadModuleMapResult loadModuleMapFileImpl(const FileEntry *File,
bool IsSystem,
const DirectoryEntry *Dir);
const DirectoryEntry *Dir,
FileID ID = FileID(),
unsigned *Offset = nullptr);
/// \brief Try to load the module map file in the given directory.
///

@ -478,6 +478,11 @@ public:
return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts);
}
/// Returns the leading whitespace for line that corresponds to the given
/// location \p Loc.
static StringRef getIndentationForLine(SourceLocation Loc,
const SourceManager &SM);
//===--------------------------------------------------------------------===//
// Internal implementation interfaces.
private:

@ -546,14 +546,20 @@ public:
/// \param HomeDir The directory in which relative paths within this module
/// map file will be resolved.
///
/// \param ID The FileID of the file to process, if we've already entered it.
///
/// \param Offset [inout] On input the offset at which to start parsing. On
/// output, the offset at which the module map terminated.
///
/// \param ExternModuleLoc The location of the "extern module" declaration
/// that caused us to load this module map file, if any.
///
/// \returns true if an error occurred, false otherwise.
bool parseModuleMapFile(const FileEntry *File, bool IsSystem,
const DirectoryEntry *HomeDir,
const DirectoryEntry *HomeDir, FileID ID = FileID(),
unsigned *Offset = nullptr,
SourceLocation ExternModuleLoc = SourceLocation());
/// \brief Dump the contents of the module map, for debugging purposes.
void dump();

@ -324,7 +324,7 @@ class Preprocessor {
/// \brief If the current lexer is for a submodule that is being built, this
/// is that submodule.
Module *CurSubmodule;
Module *CurLexerSubmodule;
/// \brief Keeps track of the stack of files currently
/// \#included, and macros currently being expanded from, not counting
@ -507,16 +507,19 @@ class Preprocessor {
/// \brief Information about a submodule that we're currently building.
struct BuildingSubmoduleInfo {
BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc,
BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, bool IsPragma,
SubmoduleState *OuterSubmoduleState,
unsigned OuterPendingModuleMacroNames)
: M(M), ImportLoc(ImportLoc), OuterSubmoduleState(OuterSubmoduleState),
: M(M), ImportLoc(ImportLoc), IsPragma(IsPragma),
OuterSubmoduleState(OuterSubmoduleState),
OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {}
/// The module that we are building.
Module *M;
/// The location at which the module was included.
SourceLocation ImportLoc;
/// Whether we entered this submodule via a pragma.
bool IsPragma;
/// The previous SubmoduleState.
SubmoduleState *OuterSubmoduleState;
/// The number of pending module macro names when we started building this.
@ -773,8 +776,9 @@ public:
/// expansions going on at the time.
PreprocessorLexer *getCurrentFileLexer() const;
/// \brief Return the submodule owning the file being lexed.
Module *getCurrentSubmodule() const { return CurSubmodule; }
/// \brief Return the submodule owning the file being lexed. This may not be
/// the current module if we have changed modules since entering the file.
Module *getCurrentLexerSubmodule() const { return CurLexerSubmodule; }
/// \brief Returns the FileID for the preprocessor predefines.
FileID getPredefinesFileID() const { return PredefinesFileID; }
@ -1726,13 +1730,16 @@ public:
bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
bool *ShadowFlag = nullptr);
private:
void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma);
Module *LeaveSubmodule(bool ForPragma);
private:
void PushIncludeMacroStack() {
assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer");
IncludeMacroStack.emplace_back(
CurLexerKind, CurSubmodule, std::move(CurLexer), std::move(CurPTHLexer),
CurPPLexer, std::move(CurTokenLexer), CurDirLookup);
IncludeMacroStack.emplace_back(CurLexerKind, CurLexerSubmodule,
std::move(CurLexer), std::move(CurPTHLexer),
CurPPLexer, std::move(CurTokenLexer),
CurDirLookup);
CurPPLexer = nullptr;
}
@ -1742,16 +1749,13 @@ private:
CurPPLexer = IncludeMacroStack.back().ThePPLexer;
CurTokenLexer = std::move(IncludeMacroStack.back().TheTokenLexer);
CurDirLookup = IncludeMacroStack.back().TheDirLookup;
CurSubmodule = IncludeMacroStack.back().TheSubmodule;
CurLexerSubmodule = IncludeMacroStack.back().TheSubmodule;
CurLexerKind = IncludeMacroStack.back().CurLexerKind;
IncludeMacroStack.pop_back();
}
void PropagateLineStartLeadingSpaceInfo(Token &Result);
void EnterSubmodule(Module *M, SourceLocation ImportLoc);
void LeaveSubmodule();
/// Determine whether we need to create module macros for #defines in the
/// current context.
bool needModuleMacros() const;
@ -1967,7 +1971,6 @@ public:
void HandlePragmaPoison();
void HandlePragmaSystemHeader(Token &SysHeaderTok);
void HandlePragmaDependency(Token &DependencyTok);
void HandlePragmaModuleImport(Token &Tok);
void HandlePragmaPushMacro(Token &Tok);
void HandlePragmaPopMacro(Token &Tok);
void HandlePragmaIncludeAlias(Token &Tok);

@ -3766,6 +3766,9 @@ public:
void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType,
SourceLocation Loc);
/// Warn when implicitly casting 0 to nullptr.
void diagnoseZeroToNullptrConversion(CastKind Kind, const Expr *E);
ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool &pool) {
return DelayedDiagnostics.push(pool);
}

@ -65,6 +65,13 @@ FixItHint createReplacement(const D &Destination, const S &Source,
getText(Source, Context));
}
// \brief Returns a FixItHint to replace \p Destination by \p Source.
template <typename D>
FixItHint createReplacement(const D &Destination, StringRef Source) {
return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
Source);
}
} // end namespace fixit
} // end namespace tooling
} // end namespace clang

@ -153,6 +153,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(cxxRecordDecl);
REGISTER_MATCHER(cxxReinterpretCastExpr);
REGISTER_MATCHER(cxxStaticCastExpr);
REGISTER_MATCHER(cxxStdInitializerListExpr);
REGISTER_MATCHER(cxxTemporaryObjectExpr);
REGISTER_MATCHER(cxxThisExpr);
REGISTER_MATCHER(cxxThrowExpr);

@ -146,10 +146,9 @@ void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
}
void DiagnosticsEngine::ReportDelayed() {
Report(DelayedDiagID) << DelayedDiagArg1 << DelayedDiagArg2;
unsigned ID = DelayedDiagID;
DelayedDiagID = 0;
DelayedDiagArg1.clear();
DelayedDiagArg2.clear();
Report(ID) << DelayedDiagArg1 << DelayedDiagArg2;
}
void DiagnosticsEngine::DiagStateMap::appendFirst(
@ -420,11 +419,10 @@ bool DiagnosticsEngine::EmitCurrentDiagnostic(bool Force) {
}
// Clear out the current diagnostic object.
unsigned DiagID = CurDiagID;
Clear();
// If there was a delayed diagnostic, emit it now.
if (!Force && DelayedDiagID && DelayedDiagID != DiagID)
if (!Force && DelayedDiagID)
ReportDelayed();
return Emitted;

@ -666,6 +666,10 @@ bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const {
}
}
// Make sure we set FatalErrorOccurred to ensure that the notes from the
// diagnostic that caused `fatal_too_many_errors` won't be emitted.
if (Diag.CurDiagID == diag::fatal_too_many_errors)
Diag.FatalErrorOccurred = true;
// Finally, report it.
EmitDiag(Diag, DiagLevel);
return true;

@ -2591,6 +2591,7 @@ class X86TargetInfo : public TargetInfo {
bool HasRDSEED = false;
bool HasADX = false;
bool HasTBM = false;
bool HasLWP = false;
bool HasFMA = false;
bool HasF16C = false;
bool HasAVX512CD = false;
@ -3363,6 +3364,7 @@ bool X86TargetInfo::initFeatureMap(
case CK_BDVER1:
// xop implies avx, sse4a and fma4.
setFeatureEnabledImpl(Features, "xop", true);
setFeatureEnabledImpl(Features, "lwp", true);
setFeatureEnabledImpl(Features, "lzcnt", true);
setFeatureEnabledImpl(Features, "aes", true);
setFeatureEnabledImpl(Features, "pclmul", true);
@ -3634,6 +3636,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasADX = true;
} else if (Feature == "+tbm") {
HasTBM = true;
} else if (Feature == "+lwp") {
HasLWP = true;
} else if (Feature == "+fma") {
HasFMA = true;
} else if (Feature == "+f16c") {
@ -3949,6 +3953,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasTBM)
Builder.defineMacro("__TBM__");
if (HasLWP)
Builder.defineMacro("__LWP__");
if (HasMWAITX)
Builder.defineMacro("__MWAITX__");
@ -4132,6 +4139,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("sse4.2", SSELevel >= SSE42)
.Case("sse4a", XOPLevel >= SSE4A)
.Case("tbm", HasTBM)
.Case("lwp", HasLWP)
.Case("x86", true)
.Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
.Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
@ -5443,6 +5451,7 @@ public:
.Case("softfloat", SoftFloat)
.Case("thumb", isThumb())
.Case("neon", (FPU & NeonFPU) && !SoftFloat)
.Case("vfp", FPU && !SoftFloat)
.Case("hwdiv", HWDiv & HWDivThumb)
.Case("hwdiv-arm", HWDiv & HWDivARM)
.Default(false);

@ -185,6 +185,7 @@ static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
Opts.Use8bitCounters = CGOpts.SanitizeCoverage8bitCounters;
Opts.TracePC = CGOpts.SanitizeCoverageTracePC;
Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard;
Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune;
PM.add(createSanitizerCoverageModulePass(Opts));
}
@ -974,10 +975,14 @@ static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M,
// via a WriteIndexesThinBackend.
FunctionImporter::ImportMapTy ImportList;
for (auto &GlobalList : *CombinedIndex) {
// Ignore entries for undefined references.
if (GlobalList.second.SummaryList.empty())
continue;
auto GUID = GlobalList.first;
assert(GlobalList.second.size() == 1 &&
assert(GlobalList.second.SummaryList.size() == 1 &&
"Expected individual combined index to have one summary per GUID");
auto &Summary = GlobalList.second[0];
auto &Summary = GlobalList.second.SummaryList[0];
// Skip the summaries for the importing module. These are included to
// e.g. record required linkage changes.
if (Summary->modulePath() == M->getModuleIdentifier())

@ -623,9 +623,13 @@ static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) {
// For const-qualified captures, emit clang.arc.use to ensure the captured
// object doesn't get released while we are still depending on its validity
// within the block.
if (VT.isConstQualified() && VT.getObjCLifetime() == Qualifiers::OCL_Strong)
if (VT.isConstQualified() &&
VT.getObjCLifetime() == Qualifiers::OCL_Strong &&
CGF.CGM.getCodeGenOpts().OptimizationLevel != 0) {
assert(CGF.CGM.getLangOpts().ObjCAutoRefCount &&
"expected ObjC ARC to be enabled");
destroyer = CodeGenFunction::emitARCIntrinsicUse;
else if (dtorKind == QualType::DK_objc_strong_lifetime) {
} else if (dtorKind == QualType::DK_objc_strong_lifetime) {
destroyer = CodeGenFunction::destroyARCStrongImprecise;
} else {
destroyer = CGF.getDestroyer(dtorKind);

@ -2751,7 +2751,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
// Push a clang.arc.use cleanup for each object in RetainableOperands. The
// cleanup will cause the use to appear after the final log call, keeping
// the object valid while its held in the log buffer. Note that if theres
// the object valid while it's held in the log buffer. Note that if there's
// a release cleanup on the object, it will already be active; since
// cleanups are emitted in reverse order, the use will occur before the
// object is released.

@ -658,34 +658,42 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD,
GenOpenCLArgMetadata(FD, Fn, CGM, Context, Builder, getContext());
if (const VecTypeHintAttr *A = FD->getAttr<VecTypeHintAttr>()) {
QualType hintQTy = A->getTypeHint();
const ExtVectorType *hintEltQTy = hintQTy->getAs<ExtVectorType>();
bool isSignedInteger =
hintQTy->isSignedIntegerType() ||
(hintEltQTy && hintEltQTy->getElementType()->isSignedIntegerType());
llvm::Metadata *attrMDArgs[] = {
QualType HintQTy = A->getTypeHint();
const ExtVectorType *HintEltQTy = HintQTy->getAs<ExtVectorType>();
bool IsSignedInteger =
HintQTy->isSignedIntegerType() ||
(HintEltQTy && HintEltQTy->getElementType()->isSignedIntegerType());
llvm::Metadata *AttrMDArgs[] = {
llvm::ConstantAsMetadata::get(llvm::UndefValue::get(
CGM.getTypes().ConvertType(A->getTypeHint()))),
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
llvm::IntegerType::get(Context, 32),
llvm::APInt(32, (uint64_t)(isSignedInteger ? 1 : 0))))};
Fn->setMetadata("vec_type_hint", llvm::MDNode::get(Context, attrMDArgs));
llvm::APInt(32, (uint64_t)(IsSignedInteger ? 1 : 0))))};
Fn->setMetadata("vec_type_hint", llvm::MDNode::get(Context, AttrMDArgs));
}
if (const WorkGroupSizeHintAttr *A = FD->getAttr<WorkGroupSizeHintAttr>()) {
llvm::Metadata *attrMDArgs[] = {
llvm::Metadata *AttrMDArgs[] = {
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getXDim())),
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getYDim())),
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getZDim()))};
Fn->setMetadata("work_group_size_hint", llvm::MDNode::get(Context, attrMDArgs));
Fn->setMetadata("work_group_size_hint", llvm::MDNode::get(Context, AttrMDArgs));
}
if (const ReqdWorkGroupSizeAttr *A = FD->getAttr<ReqdWorkGroupSizeAttr>()) {
llvm::Metadata *attrMDArgs[] = {
llvm::Metadata *AttrMDArgs[] = {
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getXDim())),
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getYDim())),
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getZDim()))};
Fn->setMetadata("reqd_work_group_size", llvm::MDNode::get(Context, attrMDArgs));
Fn->setMetadata("reqd_work_group_size", llvm::MDNode::get(Context, AttrMDArgs));
}
if (const OpenCLIntelReqdSubGroupSizeAttr *A =
FD->getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
llvm::Metadata *AttrMDArgs[] = {
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getSubGroupSize()))};
Fn->setMetadata("intel_reqd_sub_group_size",
llvm::MDNode::get(Context, AttrMDArgs));
}
}

@ -1413,16 +1413,8 @@ private:
/// True if we need emit the life-time markers.
const bool ShouldEmitLifetimeMarkers;
/// Add a kernel metadata node to the named metadata node 'opencl.kernels'.
/// In the kernel metadata node, reference the kernel function and metadata
/// nodes for its optional attribute qualifiers (OpenCL 1.1 6.7.2):
/// - A node for the vec_type_hint(<type>) qualifier contains string
/// "vec_type_hint", an undefined value of the <type> data type,
/// and a Boolean that is true if the <type> is integer and signed.
/// - A node for the work_group_size_hint(X,Y,Z) qualifier contains string
/// "work_group_size_hint", and three 32-bit integers X, Y and Z.
/// - A node for the reqd_work_group_size(X,Y,Z) qualifier contains string
/// "reqd_work_group_size", and three 32-bit integers X, Y and Z.
/// Add OpenCL kernel arg metadata and the kernel attribute meatadata to
/// the function metadata.
void EmitOpenCLKernelMetadata(const FunctionDecl *FD,
llvm::Function *Fn);

@ -4890,10 +4890,16 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty) const {
// Empty records are always ignored on Darwin, but actually passed in C++ mode
// elsewhere for GNU compatibility.
if (isEmptyRecord(getContext(), Ty, true)) {
uint64_t Size = getContext().getTypeSize(Ty);
bool IsEmpty = isEmptyRecord(getContext(), Ty, true);
if (IsEmpty || Size == 0) {
if (!getContext().getLangOpts().CPlusPlus || isDarwinPCS())
return ABIArgInfo::getIgnore();
// GNU C mode. The only argument that gets ignored is an empty one with size
// 0.
if (IsEmpty && Size == 0)
return ABIArgInfo::getIgnore();
return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
}
@ -4906,7 +4912,6 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty) const {
}
// Aggregates <= 16 bytes are passed directly in registers or on the stack.
uint64_t Size = getContext().getTypeSize(Ty);
if (Size <= 128) {
// On RenderScript, coerce Aggregates <= 16 bytes to an integer array of
// same size and alignment.
@ -4946,7 +4951,8 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy) const {
: ABIArgInfo::getDirect());
}
if (isEmptyRecord(getContext(), RetTy, true))
uint64_t Size = getContext().getTypeSize(RetTy);
if (isEmptyRecord(getContext(), RetTy, true) || Size == 0)
return ABIArgInfo::getIgnore();
const Type *Base = nullptr;
@ -4956,7 +4962,6 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy) const {
return ABIArgInfo::getDirect();
// Aggregates <= 16 bytes are returned directly in registers or on the stack.
uint64_t Size = getContext().getTypeSize(RetTy);
if (Size <= 128) {
// On RenderScript, coerce Aggregates <= 16 bytes to an integer array of
// same size and alignment.

@ -47,6 +47,7 @@ static Distro::DistroType DetectDistro(vfs::FileSystem &VFS) {
.Case("xenial", Distro::UbuntuXenial)
.Case("yakkety", Distro::UbuntuYakkety)
.Case("zesty", Distro::UbuntuZesty)
.Case("artful", Distro::UbuntuArtful)
.Default(Distro::UnknownDistro);
if (Version != Distro::UnknownDistro)
return Version;

@ -80,6 +80,10 @@ Multilib &Multilib::includeSuffix(StringRef S) {
return *this;
}
LLVM_DUMP_METHOD void Multilib::dump() const {
print(llvm::errs());
}
void Multilib::print(raw_ostream &OS) const {
assert(GCCSuffix.empty() || (StringRef(GCCSuffix).front() == '/'));
if (GCCSuffix.empty())
@ -270,6 +274,10 @@ bool MultilibSet::select(const Multilib::flags_list &Flags, Multilib &M) const {
return false;
}
LLVM_DUMP_METHOD void MultilibSet::dump() const {
print(llvm::errs());
}
void MultilibSet::print(raw_ostream &OS) const {
for (const Multilib &M : *this)
OS << M << "\n";

@ -55,6 +55,7 @@ enum CoverageFeature {
Coverage8bitCounters = 1 << 8,
CoverageTracePC = 1 << 9,
CoverageTracePCGuard = 1 << 10,
CoverageNoPrune = 1 << 11,
};
/// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
@ -629,7 +630,8 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
std::make_pair(CoverageTracePCGuard, "-fsanitize-coverage-trace-pc-guard")};
std::make_pair(CoverageTracePCGuard, "-fsanitize-coverage-trace-pc-guard"),
std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune")};
for (auto F : CoverageFlags) {
if (CoverageFeatures & F.first)
CmdArgs.push_back(Args.MakeArgString(F.second));
@ -786,6 +788,7 @@ int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) {
.Case("8bit-counters", Coverage8bitCounters)
.Case("trace-pc", CoverageTracePC)
.Case("trace-pc-guard", CoverageTracePCGuard)
.Case("no-prune", CoverageNoPrune)
.Default(0);
if (F == 0)
D.Diag(clang::diag::err_drv_unsupported_option_argument)

@ -204,7 +204,7 @@ CrossWindowsToolChain::CrossWindowsToolChain(const Driver &D,
const llvm::Triple &T,
const llvm::opt::ArgList &Args)
: Generic_GCC(D, T, Args) {
if (GetCXXStdlibType(Args) == ToolChain::CST_Libstdcxx) {
if (D.CCCIsCXX() && GetCXXStdlibType(Args) == ToolChain::CST_Libstdcxx) {
const std::string &SysRoot = D.SysRoot;
// libstdc++ resides in /usr/lib, but depends on libgcc which is placed in

@ -893,6 +893,8 @@ static bool isSoftFloatABI(const ArgList &Args) {
A->getValue() == StringRef("soft"));
}
/// \p Flag must be a flag accepted by the driver with its leading '-' removed,
// otherwise '-print-multi-lib' will not emit them correctly.
static void addMultilibFlag(bool Enabled, const char *const Flag,
std::vector<std::string> &Flags) {
if (Enabled)
@ -1437,17 +1439,17 @@ static void findAndroidArmMultilibs(const Driver &D,
// Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb.
FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
Multilib ArmV7Multilib = makeMultilib("/armv7-a")
.flag("+armv7")
.flag("-thumb");
.flag("+march=armv7-a")
.flag("-mthumb");
Multilib ThumbMultilib = makeMultilib("/thumb")
.flag("-armv7")
.flag("+thumb");
.flag("-march=armv7-a")
.flag("+mthumb");
Multilib ArmV7ThumbMultilib = makeMultilib("/armv7-a/thumb")
.flag("+armv7")
.flag("+thumb");
.flag("+march=armv7-a")
.flag("+mthumb");
Multilib DefaultMultilib = makeMultilib("")
.flag("-armv7")
.flag("-thumb");
.flag("-march=armv7-a")
.flag("-mthumb");
MultilibSet AndroidArmMultilibs =
MultilibSet()
.Either(ThumbMultilib, ArmV7Multilib,
@ -1465,8 +1467,8 @@ static void findAndroidArmMultilibs(const Driver &D,
bool IsArmV7Mode = (IsArmArch || IsThumbArch) &&
(llvm::ARM::parseArchVersion(Arch) == 7 ||
(IsArmArch && Arch == "" && IsV7SubArch));
addMultilibFlag(IsArmV7Mode, "armv7", Flags);
addMultilibFlag(IsThumbMode, "thumb", Flags);
addMultilibFlag(IsArmV7Mode, "march=armv7-a", Flags);
addMultilibFlag(IsThumbMode, "mthumb", Flags);
if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilib))
Result.Multilibs = AndroidArmMultilibs;

@ -53,6 +53,8 @@ namespace format {
TYPE(InlineASMColon) \
TYPE(JavaAnnotation) \
TYPE(JsComputedPropertyName) \
TYPE(JsExponentiation) \
TYPE(JsExponentiationEqual) \
TYPE(JsFatArrow) \
TYPE(JsNonNullAssertion) \
TYPE(JsTypeColon) \

@ -74,6 +74,10 @@ void FormatTokenLexer::tryMergePreviousTokens() {
static const tok::TokenKind JSShiftEqual[] = {tok::greater, tok::greater,
tok::greaterequal};
static const tok::TokenKind JSRightArrow[] = {tok::equal, tok::greater};
static const tok::TokenKind JSExponentiation[] = {tok::star, tok::star};
static const tok::TokenKind JSExponentiationEqual[] = {tok::star,
tok::starequal};
// FIXME: Investigate what token type gives the correct operator priority.
if (tryMergeTokens(JSIdentity, TT_BinaryOperator))
return;
@ -83,6 +87,12 @@ void FormatTokenLexer::tryMergePreviousTokens() {
return;
if (tryMergeTokens(JSRightArrow, TT_JsFatArrow))
return;
if (tryMergeTokens(JSExponentiation, TT_JsExponentiation))
return;
if (tryMergeTokens(JSExponentiationEqual, TT_JsExponentiationEqual)) {
Tokens.back()->Tok.setKind(tok::starequal);
return;
}
}
if (Style.Language == FormatStyle::LK_Java) {

@ -766,6 +766,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.SanitizeCoverageTracePC = Args.hasArg(OPT_fsanitize_coverage_trace_pc);
Opts.SanitizeCoverageTracePCGuard =
Args.hasArg(OPT_fsanitize_coverage_trace_pc_guard);
Opts.SanitizeCoverageNoPrune = Args.hasArg(OPT_fsanitize_coverage_no_prune);
Opts.SanitizeMemoryTrackOrigins =
getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags);
Opts.SanitizeMemoryUseAfterDtor =

@ -136,6 +136,12 @@ void FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput,
CurrentASTUnit = std::move(AST);
}
Module *FrontendAction::getCurrentModule() const {
CompilerInstance &CI = getCompilerInstance();
return CI.getPreprocessor().getHeaderSearchInfo().lookupModule(
CI.getLangOpts().CurrentModule, /*AllowSearch*/false);
}
std::unique_ptr<ASTConsumer>
FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
StringRef InFile) {
@ -188,16 +194,25 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
}
// For preprocessed files, if the first line is the linemarker and specifies
// the original source file name, use that name as the input file name.
static bool ReadOriginalFileName(CompilerInstance &CI, std::string &InputFile)
{
bool Invalid = false;
/// For preprocessed files, if the first line is the linemarker and specifies
/// the original source file name, use that name as the input file name.
/// Returns the location of the first token after the line marker directive.
///
/// \param CI The compiler instance.
/// \param InputFile Populated with the filename from the line marker.
/// \param AddLineNote If \c true, add a line note corresponding to this line
/// directive. Only use this if the directive will not actually be
/// visited by the preprocessor.
static SourceLocation ReadOriginalFileName(CompilerInstance &CI,
std::string &InputFile,
bool AddLineNote = false) {
auto &SourceMgr = CI.getSourceManager();
auto MainFileID = SourceMgr.getMainFileID();
bool Invalid = false;
const auto *MainFileBuf = SourceMgr.getBuffer(MainFileID, &Invalid);
if (Invalid)
return false;
return SourceLocation();
std::unique_ptr<Lexer> RawLexer(
new Lexer(MainFileID, MainFileBuf, SourceMgr, CI.getLangOpts()));
@ -209,19 +224,37 @@ static bool ReadOriginalFileName(CompilerInstance &CI, std::string &InputFile)
// we use FILENAME as the input file name.
Token T;
if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash)
return false;
return SourceLocation();
if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() ||
T.getKind() != tok::numeric_constant)
return false;
return SourceLocation();
unsigned LineNo;
SourceLocation LineNoLoc = T.getLocation();
if (AddLineNote) {
llvm::SmallString<16> Buffer;
if (Lexer::getSpelling(LineNoLoc, Buffer, SourceMgr, CI.getLangOpts())
.getAsInteger(10, LineNo))
return SourceLocation();
}
RawLexer->LexFromRawLexer(T);
if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)
return false;
return SourceLocation();
StringLiteralParser Literal(T, CI.getPreprocessor());
if (Literal.hadError)
return false;
return SourceLocation();
RawLexer->LexFromRawLexer(T);
if (T.isNot(tok::eof) && !T.isAtStartOfLine())
return SourceLocation();
InputFile = Literal.GetString().str();
return true;
if (AddLineNote)
CI.getSourceManager().AddLineNote(
LineNoLoc, LineNo, SourceMgr.getLineTableFilenameID(InputFile));
return T.getLocation();
}
static SmallVectorImpl<char> &
@ -339,42 +372,44 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
return std::error_code();
}
/// Parse a module map and compute the corresponding real input buffer that
/// should be used to build the module described by that module map and the
/// current module name.
static std::unique_ptr<llvm::MemoryBuffer>
getInputBufferForModuleMap(CompilerInstance &CI, StringRef Filename,
bool IsSystem) {
// Find the module map file.
const FileEntry *ModuleMap =
CI.getFileManager().getFile(Filename, /*openFile*/true);
if (!ModuleMap) {
CI.getDiagnostics().Report(diag::err_module_map_not_found)
<< Filename;
return nullptr;
static bool
loadModuleMapForModuleBuild(CompilerInstance &CI, StringRef Filename,
bool IsSystem, bool IsPreprocessed,
unsigned &Offset) {
auto &SrcMgr = CI.getSourceManager();
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
// Map the current input to a file.
FileID ModuleMapID = SrcMgr.getMainFileID();
const FileEntry *ModuleMap = SrcMgr.getFileEntryForID(ModuleMapID);
// If the module map is preprocessed, handle the initial line marker;
// line directives are not part of the module map syntax in general.
Offset = 0;
if (IsPreprocessed) {
std::string PresumedModuleMapFile;
SourceLocation EndOfLineMarker =
ReadOriginalFileName(CI, PresumedModuleMapFile, /*AddLineNote*/true);
if (EndOfLineMarker.isValid())
Offset = CI.getSourceManager().getDecomposedLoc(EndOfLineMarker).second;
// FIXME: Use PresumedModuleMapFile as the MODULE_MAP_FILE in the PCM.
}
// Find the module map file from which it was generated, if different.
const FileEntry *OriginalModuleMap = ModuleMap;
StringRef OriginalModuleMapName = CI.getFrontendOpts().OriginalModuleMap;
if (!OriginalModuleMapName.empty()) {
OriginalModuleMap = CI.getFileManager().getFile(OriginalModuleMapName,
/*openFile*/ true);
if (!OriginalModuleMap) {
CI.getDiagnostics().Report(diag::err_module_map_not_found)
<< OriginalModuleMapName;
return nullptr;
}
}
// Parse the module map file.
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
if (HS.loadModuleMapFile(ModuleMap, IsSystem))
return nullptr;
// Load the module map file.
if (HS.loadModuleMapFile(ModuleMap, IsSystem, ModuleMapID, &Offset))
return true;
if (SrcMgr.getBuffer(ModuleMapID)->getBufferSize() == Offset)
Offset = 0;
return false;
}
static Module *prepareToBuildModule(CompilerInstance &CI,
StringRef ModuleMapFilename) {
if (CI.getLangOpts().CurrentModule.empty()) {
CI.getDiagnostics().Report(diag::err_missing_module_name);
// FIXME: Eventually, we could consider asking whether there was just
// a single module described in the module map, and use that as a
// default. Then it would be fairly trivial to just "compile" a module
@ -382,21 +417,14 @@ getInputBufferForModuleMap(CompilerInstance &CI, StringRef Filename,
return nullptr;
}
// If we're being run from the command-line, the module build stack will not
// have been filled in yet, so complete it now in order to allow us to detect
// module cycles.
SourceManager &SourceMgr = CI.getSourceManager();
if (SourceMgr.getModuleBuildStack().empty())
SourceMgr.pushModuleBuildStack(CI.getLangOpts().CurrentModule,
FullSourceLoc(SourceLocation(), SourceMgr));
// Dig out the module definition.
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
Module *M = HS.lookupModule(CI.getLangOpts().CurrentModule,
/*AllowSearch=*/false);
if (!M) {
CI.getDiagnostics().Report(diag::err_missing_module)
<< CI.getLangOpts().CurrentModule << Filename;
<< CI.getLangOpts().CurrentModule << ModuleMapFilename;
return nullptr;
}
@ -417,11 +445,45 @@ getInputBufferForModuleMap(CompilerInstance &CI, StringRef Filename,
return nullptr;
}
if (OriginalModuleMap != ModuleMap) {
M->IsInferred = true;
HS.getModuleMap().setInferredModuleAllowedBy(M, OriginalModuleMap);
// Inform the preprocessor that includes from within the input buffer should
// be resolved relative to the build directory of the module map file.
CI.getPreprocessor().setMainFileDir(M->Directory);
// If the module was inferred from a different module map (via an expanded
// umbrella module definition), track that fact.
// FIXME: It would be preferable to fill this in as part of processing
// the module map, rather than adding it after the fact.
StringRef OriginalModuleMapName = CI.getFrontendOpts().OriginalModuleMap;
if (!OriginalModuleMapName.empty()) {
auto *OriginalModuleMap =
CI.getFileManager().getFile(OriginalModuleMapName,
/*openFile*/ true);
if (!OriginalModuleMap) {
CI.getDiagnostics().Report(diag::err_module_map_not_found)
<< OriginalModuleMapName;
return nullptr;
}
if (OriginalModuleMap != CI.getSourceManager().getFileEntryForID(
CI.getSourceManager().getMainFileID())) {
M->IsInferred = true;
CI.getPreprocessor().getHeaderSearchInfo().getModuleMap()
.setInferredModuleAllowedBy(M, OriginalModuleMap);
}
}
// If we're being run from the command-line, the module build stack will not
// have been filled in yet, so complete it now in order to allow us to detect
// module cycles.
SourceManager &SourceMgr = CI.getSourceManager();
if (SourceMgr.getModuleBuildStack().empty())
SourceMgr.pushModuleBuildStack(CI.getLangOpts().CurrentModule,
FullSourceLoc(SourceLocation(), SourceMgr));
return M;
}
/// Compute the input buffer that should be used to build the specified module.
static std::unique_ptr<llvm::MemoryBuffer>
getInputBufferForModule(CompilerInstance &CI, Module *M) {
FileManager &FileMgr = CI.getFileManager();
// Collect the set of #includes we need to build the module.
@ -441,10 +503,6 @@ getInputBufferForModuleMap(CompilerInstance &CI, StringRef Filename,
return nullptr;
}
// Inform the preprocessor that includes from within the input buffer should
// be resolved relative to the build directory of the module map file.
CI.getPreprocessor().setMainFileDir(M->Directory);
return llvm::MemoryBuffer::getMemBufferCopy(
HeaderContents, Module::getModuleInputBufferName());
}
@ -457,7 +515,6 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
setCompilerInstance(&CI);
StringRef InputFile = Input.getFile();
FrontendInputFile FileToProcess = Input;
bool HasBegunSourceFile = false;
if (!BeginInvocation(CI))
goto failure;
@ -597,36 +654,45 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
&CI.getPreprocessor());
HasBegunSourceFile = true;
// Initialize the main file entry.
if (!CI.InitializeSourceManager(Input))
goto failure;
// For module map files, we first parse the module map and synthesize a
// "<module-includes>" buffer before more conventional processing.
if (Input.getKind().getFormat() == InputKind::ModuleMap) {
CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap);
auto Buffer = getInputBufferForModuleMap(CI, InputFile, Input.isSystem());
if (!Buffer)
unsigned OffsetToContents;
if (loadModuleMapForModuleBuild(CI, Input.getFile(), Input.isSystem(),
Input.isPreprocessed(), OffsetToContents))
goto failure;
Module *CurrentModule =
CI.getPreprocessor().getHeaderSearchInfo().lookupModule(
CI.getLangOpts().CurrentModule,
/*AllowSearch=*/false);
assert(CurrentModule && "no module info for current module");
auto *CurrentModule = prepareToBuildModule(CI, Input.getFile());
if (!CurrentModule)
goto failure;
// The input that we end up processing is the generated buffer, not the
// module map file itself.
FileToProcess = FrontendInputFile(
Buffer.release(), Input.getKind().withFormat(InputKind::Source),
CurrentModule->IsSystem);
if (OffsetToContents)
// If the module contents are in the same file, skip to them.
CI.getPreprocessor().setSkipMainFilePreamble(OffsetToContents, true);
else {
// Otherwise, convert the module description to a suitable input buffer.
auto Buffer = getInputBufferForModule(CI, CurrentModule);
if (!Buffer)
goto failure;
// Reinitialize the main file entry to refer to the new input.
if (!CI.InitializeSourceManager(FrontendInputFile(
Buffer.release(), Input.getKind().withFormat(InputKind::Source),
CurrentModule->IsSystem)))
goto failure;
}
}
// Initialize the action.
if (!BeginSourceFileAction(CI, InputFile))
goto failure;
// Initialize the main file entry.
if (!CI.InitializeSourceManager(FileToProcess))
goto failure;
// Create the AST context and consumer unless this is a preprocessor only
// action.
if (!usesPreprocessorOnly()) {
@ -636,13 +702,12 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
// For preprocessed files, check if the first line specifies the original
// source file name with a linemarker.
std::string OrigFile;
std::string PresumedInputFile = InputFile;
if (Input.isPreprocessed())
if (ReadOriginalFileName(CI, OrigFile))
InputFile = OrigFile;
ReadOriginalFileName(CI, PresumedInputFile);
std::unique_ptr<ASTConsumer> Consumer =
CreateWrappedASTConsumer(CI, InputFile);
CreateWrappedASTConsumer(CI, PresumedInputFile);
if (!Consumer)
goto failure;

@ -542,6 +542,18 @@ void PrintPreprocessedAction::ExecuteAction() {
CI.createDefaultOutputFile(BinaryMode, getCurrentFile());
if (!OS) return;
// If we're preprocessing a module map, start by dumping the contents of the
// module itself before switching to the input buffer.
auto &Input = getCurrentInput();
if (Input.getKind().getFormat() == InputKind::ModuleMap) {
if (Input.isFile())
(*OS) << "# 1 \"" << Input.getFile() << "\"\n";
// FIXME: Include additional information here so that we don't need the
// original source files to exist on disk.
getCurrentModule()->print(*OS);
(*OS) << "#pragma clang module contents\n";
}
DoPrintPreprocessedInput(CI.getPreprocessor(), OS.get(),
CI.getPreprocessorOutputOpts());
}

@ -174,6 +174,9 @@ public:
void MacroUndefined(const Token &MacroNameTok,
const MacroDefinition &MD,
const MacroDirective *Undef) override;
void BeginModule(const Module *M);
void EndModule(const Module *M);
};
} // end anonymous namespace
@ -372,6 +375,20 @@ void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc,
}
}
/// Handle entering the scope of a module during a module compilation.
void PrintPPOutputPPCallbacks::BeginModule(const Module *M) {
startNewLineIfNeeded();
OS << "#pragma clang module begin " << M->getFullModuleName();
setEmittedDirectiveOnThisLine();
}
/// Handle leaving the scope of a module during a module compilation.
void PrintPPOutputPPCallbacks::EndModule(const Module *M) {
startNewLineIfNeeded();
OS << "#pragma clang module end /*" << M->getFullModuleName() << "*/";
setEmittedDirectiveOnThisLine();
}
/// Ident - Handle #ident directives when read by the preprocessor.
///
void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, StringRef S) {
@ -685,13 +702,27 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
// -traditional-cpp the lexer keeps /all/ whitespace, including comments.
SourceLocation StartLoc = Tok.getLocation();
Callbacks->MoveToLine(StartLoc.getLocWithOffset(Tok.getLength()));
} else if (Tok.is(tok::annot_module_include) ||
Tok.is(tok::annot_module_begin) ||
Tok.is(tok::annot_module_end)) {
} else if (Tok.is(tok::annot_module_include)) {
// PrintPPOutputPPCallbacks::InclusionDirective handles producing
// appropriate output here. Ignore this token entirely.
PP.Lex(Tok);
continue;
} else if (Tok.is(tok::annot_module_begin)) {
// FIXME: We retrieve this token after the FileChanged callback, and
// retrieve the module_end token before the FileChanged callback, so
// we render this within the file and render the module end outside the
// file, but this is backwards from the token locations: the module_begin
// token is at the include location (outside the file) and the module_end
// token is at the EOF location (within the file).
Callbacks->BeginModule(
reinterpret_cast<Module *>(Tok.getAnnotationValue()));
PP.Lex(Tok);
continue;
} else if (Tok.is(tok::annot_module_end)) {
Callbacks->EndModule(
reinterpret_cast<Module *>(Tok.getAnnotationValue()));
PP.Lex(Tok);
continue;
} else if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
OS << II->getName();
} else if (Tok.isLiteral() && !Tok.needsCleaning() &&

@ -196,6 +196,18 @@ void RewriteIncludesAction::ExecuteAction() {
CI.createDefaultOutputFile(true, getCurrentFile());
if (!OS) return;
// If we're preprocessing a module map, start by dumping the contents of the
// module itself before switching to the input buffer.
auto &Input = getCurrentInput();
if (Input.getKind().getFormat() == InputKind::ModuleMap) {
if (Input.isFile())
(*OS) << "# 1 \"" << Input.getFile() << "\"\n";
// FIXME: Include additional information here so that we don't need the
// original source files to exist on disk.
getCurrentModule()->print(*OS);
(*OS) << "#pragma clang module contents\n";
}
RewriteIncludesInInput(CI.getPreprocessor(), OS.get(),
CI.getPreprocessorOutputOpts());
}

@ -46,6 +46,8 @@ class InclusionRewriter : public PPCallbacks {
std::map<unsigned, IncludedFile> FileIncludes;
/// Tracks where inclusions that import modules are found.
std::map<unsigned, const Module *> ModuleIncludes;
/// Tracks where inclusions that enter modules (in a module build) are found.
std::map<unsigned, const Module *> ModuleEntryIncludes;
/// Used transitively for building up the FileIncludes mapping over the
/// various \c PPCallbacks callbacks.
SourceLocation LastInclusionLocation;
@ -57,6 +59,11 @@ public:
PredefinesBuffer = Buf;
}
void detectMainFileEOL();
void handleModuleBegin(Token &Tok) {
assert(Tok.getKind() == tok::annot_module_begin);
ModuleEntryIncludes.insert({Tok.getLocation().getRawEncoding(),
(Module *)Tok.getAnnotationValue()});
}
private:
void FileChanged(SourceLocation Loc, FileChangeReason Reason,
SrcMgr::CharacteristicKind FileType,
@ -84,6 +91,7 @@ private:
bool &FileExists);
const IncludedFile *FindIncludeAtLocation(SourceLocation Loc) const;
const Module *FindModuleAtLocation(SourceLocation Loc) const;
const Module *FindEnteredModule(SourceLocation Loc) const;
StringRef NextIdentifierName(Lexer &RawLex, Token &RawToken);
};
@ -211,6 +219,16 @@ InclusionRewriter::FindModuleAtLocation(SourceLocation Loc) const {
return nullptr;
}
/// Simple lookup for a SourceLocation (specifically one denoting the hash in
/// an inclusion directive) in the map of module entry information.
const Module *
InclusionRewriter::FindEnteredModule(SourceLocation Loc) const {
const auto I = ModuleEntryIncludes.find(Loc.getRawEncoding());
if (I != ModuleEntryIncludes.end())
return I->second;
return nullptr;
}
/// Detect the likely line ending style of \p FromFile by examining the first
/// newline found within it.
static StringRef DetectEOL(const MemoryBuffer &FromFile) {
@ -452,8 +470,18 @@ void InclusionRewriter::Process(FileID FileId,
if (const Module *Mod = FindModuleAtLocation(Loc))
WriteImplicitModuleImport(Mod);
else if (const IncludedFile *Inc = FindIncludeAtLocation(Loc)) {
const Module *Mod = FindEnteredModule(Loc);
if (Mod)
OS << "#pragma clang module begin " << Mod->getFullModuleName()
<< "\n";
// Include and recursively process the file.
Process(Inc->Id, Inc->FileType);
if (Mod)
OS << "#pragma clang module end /*" << Mod->getFullModuleName()
<< "*/\n";
// Add line marker to indicate we're returning from an included
// file.
LineInfoExtra = " 2";
@ -590,6 +618,8 @@ void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
PP.SetMacroExpansionOnlyInDirectives();
do {
PP.Lex(Tok);
if (Tok.is(tok::annot_module_begin))
Rewrite->handleModuleBegin(Tok);
} while (Tok.isNot(tok::eof));
Rewrite->setPredefinesBuffer(SM.getBuffer(PP.getPredefinesFileID()));
Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User);

@ -45,6 +45,7 @@ set(files
inttypes.h
iso646.h
limits.h
lwpintrin.h
lzcntintrin.h
mm3dnow.h
mmintrin.h

@ -224,6 +224,36 @@ __rbitl(unsigned long __t) {
#endif
}
/*
* 9.3 16-bit multiplications
*/
#if __ARM_FEATURE_DSP
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
__smulbb(int32_t __a, int32_t __b) {
return __builtin_arm_smulbb(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
__smulbt(int32_t __a, int32_t __b) {
return __builtin_arm_smulbt(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
__smultb(int32_t __a, int32_t __b) {
return __builtin_arm_smultb(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
__smultt(int32_t __a, int32_t __b) {
return __builtin_arm_smultt(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
__smulwb(int32_t __a, int32_t __b) {
return __builtin_arm_smulwb(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
__smulwt(int32_t __a, int32_t __b) {
return __builtin_arm_smulwt(__a, __b);
}
#endif
/*
* 9.4 Saturating intrinsics
*
@ -231,13 +261,13 @@ __rbitl(unsigned long __t) {
* intrinsics are implemented and the flag is enabled.
*/
/* 9.4.1 Width-specified saturation intrinsics */
#if __ARM_32BIT_STATE
#if __ARM_FEATURE_SAT
#define __ssat(x, y) __builtin_arm_ssat(x, y)
#define __usat(x, y) __builtin_arm_usat(x, y)
#endif
/* 9.4.2 Saturating addition and subtraction intrinsics */
#if __ARM_32BIT_STATE
#if __ARM_FEATURE_DSP
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__qadd(int32_t __t, int32_t __v) {
return __builtin_arm_qadd(__t, __v);
@ -254,6 +284,290 @@ __qdbl(int32_t __t) {
}
#endif
/* 9.4.3 Accumultating multiplications */
#if __ARM_FEATURE_DSP
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smlabb(int32_t __a, int32_t __b, int32_t __c) {
return __builtin_arm_smlabb(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smlabt(int32_t __a, int32_t __b, int32_t __c) {
return __builtin_arm_smlabt(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smlatb(int32_t __a, int32_t __b, int32_t __c) {
return __builtin_arm_smlatb(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smlatt(int32_t __a, int32_t __b, int32_t __c) {
return __builtin_arm_smlatt(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smlawb(int32_t __a, int32_t __b, int32_t __c) {
return __builtin_arm_smlawb(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smlawt(int32_t __a, int32_t __b, int32_t __c) {
return __builtin_arm_smlawt(__a, __b, __c);
}
#endif
/* 9.5.4 Parallel 16-bit saturation */
#if __ARM_FEATURE_SIMD32
#define __ssat16(x, y) __builtin_arm_ssat16(x, y)
#define __usat16(x, y) __builtin_arm_usat16(x, y)
#endif
/* 9.5.5 Packing and unpacking */
#if __ARM_FEATURE_SIMD32
typedef int32_t int8x4_t;
typedef int32_t int16x2_t;
typedef uint32_t uint8x4_t;
typedef uint32_t uint16x2_t;
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__sxtab16(int16x2_t __a, int8x4_t __b) {
return __builtin_arm_sxtab16(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__sxtb16(int8x4_t __a) {
return __builtin_arm_sxtb16(__a);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__uxtab16(int16x2_t __a, int8x4_t __b) {
return __builtin_arm_uxtab16(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__uxtb16(int8x4_t __a) {
return __builtin_arm_uxtb16(__a);
}
#endif
/* 9.5.6 Parallel selection */
#if __ARM_FEATURE_SIMD32
static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
__sel(uint8x4_t __a, uint8x4_t __b) {
return __builtin_arm_sel(__a, __b);
}
#endif
/* 9.5.7 Parallel 8-bit addition and subtraction */
#if __ARM_FEATURE_SIMD32
static __inline__ int8x4_t __attribute__((__always_inline__, __nodebug__))
__qadd8(int8x4_t __a, int8x4_t __b) {
return __builtin_arm_qadd8(__a, __b);
}
static __inline__ int8x4_t __attribute__((__always_inline__, __nodebug__))
__qsub8(int8x4_t __a, int8x4_t __b) {
return __builtin_arm_qsub8(__a, __b);
}
static __inline__ int8x4_t __attribute__((__always_inline__, __nodebug__))
__sadd8(int8x4_t __a, int8x4_t __b) {
return __builtin_arm_sadd8(__a, __b);
}
static __inline__ int8x4_t __attribute__((__always_inline__, __nodebug__))
__shadd8(int8x4_t __a, int8x4_t __b) {
return __builtin_arm_shadd8(__a, __b);
}
static __inline__ int8x4_t __attribute__((__always_inline__, __nodebug__))
__shsub8(int8x4_t __a, int8x4_t __b) {
return __builtin_arm_shsub8(__a, __b);
}
static __inline__ int8x4_t __attribute__((__always_inline__, __nodebug__))
__ssub8(int8x4_t __a, int8x4_t __b) {
return __builtin_arm_ssub8(__a, __b);
}
static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
__uadd8(uint8x4_t __a, uint8x4_t __b) {
return __builtin_arm_uadd8(__a, __b);
}
static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
__uhadd8(uint8x4_t __a, uint8x4_t __b) {
return __builtin_arm_uhadd8(__a, __b);
}
static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
__uhsub8(uint8x4_t __a, uint8x4_t __b) {
return __builtin_arm_uhsub8(__a, __b);
}
static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
__uqadd8(uint8x4_t __a, uint8x4_t __b) {
return __builtin_arm_uqadd8(__a, __b);
}
static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
__uqsub8(uint8x4_t __a, uint8x4_t __b) {
return __builtin_arm_uqsub8(__a, __b);
}
static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
__usub8(uint8x4_t __a, uint8x4_t __b) {
return __builtin_arm_usub8(__a, __b);
}
#endif
/* 9.5.8 Sum of 8-bit absolute differences */
#if __ARM_FEATURE_SIMD32
static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
__usad8(uint8x4_t __a, uint8x4_t __b) {
return __builtin_arm_usad8(__a, __b);
}
static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
__usada8(uint8x4_t __a, uint8x4_t __b, uint32_t __c) {
return __builtin_arm_usada8(__a, __b, __c);
}
#endif
/* 9.5.9 Parallel 16-bit addition and subtraction */
#if __ARM_FEATURE_SIMD32
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__qadd16(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_qadd16(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__qasx(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_qasx(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__qsax(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_qsax(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__qsub16(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_qsub16(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__sadd16(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_sadd16(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__sasx(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_sasx(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__shadd16(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_shadd16(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__shasx(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_shasx(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__shsax(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_shsax(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__shsub16(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_shsub16(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__ssax(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_ssax(__a, __b);
}
static __inline__ int16x2_t __attribute__((__always_inline__, __nodebug__))
__ssub16(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_ssub16(__a, __b);
}
static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
__uadd16(uint16x2_t __a, uint16x2_t __b) {
return __builtin_arm_uadd16(__a, __b);
}
static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
__uasx(uint16x2_t __a, uint16x2_t __b) {
return __builtin_arm_uasx(__a, __b);
}
static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
__uhadd16(uint16x2_t __a, uint16x2_t __b) {
return __builtin_arm_uhadd16(__a, __b);
}
static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
__uhasx(uint16x2_t __a, uint16x2_t __b) {
return __builtin_arm_uhasx(__a, __b);
}
static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
__uhsax(uint16x2_t __a, uint16x2_t __b) {
return __builtin_arm_uhsax(__a, __b);
}
static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
__uhsub16(uint16x2_t __a, uint16x2_t __b) {
return __builtin_arm_uhsub16(__a, __b);
}
static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
__uqadd16(uint16x2_t __a, uint16x2_t __b) {
return __builtin_arm_uqadd16(__a, __b);
}
static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
__uqasx(uint16x2_t __a, uint16x2_t __b) {
return __builtin_arm_uqasx(__a, __b);
}
static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
__uqsax(uint16x2_t __a, uint16x2_t __b) {
return __builtin_arm_uqsax(__a, __b);
}
static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
__uqsub16(uint16x2_t __a, uint16x2_t __b) {
return __builtin_arm_uqsub16(__a, __b);
}
static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
__usax(uint16x2_t __a, uint16x2_t __b) {
return __builtin_arm_usax(__a, __b);
}
static __inline__ uint16x2_t __attribute__((__always_inline__, __nodebug__))
__usub16(uint16x2_t __a, uint16x2_t __b) {
return __builtin_arm_usub16(__a, __b);
}
#endif
/* 9.5.10 Parallel 16-bit multiplications */
#if __ARM_FEATURE_SIMD32
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smlad(int16x2_t __a, int16x2_t __b, int32_t __c) {
return __builtin_arm_smlad(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smladx(int16x2_t __a, int16x2_t __b, int32_t __c) {
return __builtin_arm_smladx(__a, __b, __c);
}
static __inline__ int64_t __attribute__((__always_inline__, __nodebug__))
__smlald(int16x2_t __a, int16x2_t __b, int64_t __c) {
return __builtin_arm_smlald(__a, __b, __c);
}
static __inline__ int64_t __attribute__((__always_inline__, __nodebug__))
__smlaldx(int16x2_t __a, int16x2_t __b, int64_t __c) {
return __builtin_arm_smlaldx(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smlsd(int16x2_t __a, int16x2_t __b, int32_t __c) {
return __builtin_arm_smlsd(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smlsdx(int16x2_t __a, int16x2_t __b, int32_t __c) {
return __builtin_arm_smlsdx(__a, __b, __c);
}
static __inline__ int64_t __attribute__((__always_inline__, __nodebug__))
__smlsld(int16x2_t __a, int16x2_t __b, int64_t __c) {
return __builtin_arm_smlsld(__a, __b, __c);
}
static __inline__ int64_t __attribute__((__always_inline__, __nodebug__))
__smlsldx(int16x2_t __a, int16x2_t __b, int64_t __c) {
return __builtin_arm_smlsldx(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smuad(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_smuad(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smuadx(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_smuadx(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smusd(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_smusd(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
__smusdx(int16x2_t __a, int16x2_t __b) {
return __builtin_arm_smusdx(__a, __b);
}
#endif
/* 9.7 CRC32 intrinsics */
#if __ARM_FEATURE_CRC32
static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))

150
lib/Headers/lwpintrin.h Normal file

@ -0,0 +1,150 @@
/*===---- lwpintrin.h - LWP intrinsics -------------------------------------===
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*===-----------------------------------------------------------------------===
*/
#ifndef __X86INTRIN_H
#error "Never use <lwpintrin.h> directly; include <x86intrin.h> instead."
#endif
#ifndef __LWPINTRIN_H
#define __LWPINTRIN_H
/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("lwp")))
/// \brief Parses the LWPCB at the specified address and enables
/// profiling if valid.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> LLWPCB </c> instruction.
///
/// \param __addr
/// Address to the new Lightweight Profiling Control Block (LWPCB). If the
/// LWPCB is valid, writes the address into the LWP_CBADDR MSR and enables
/// Lightweight Profiling.
static __inline__ void __DEFAULT_FN_ATTRS
__llwpcb (void *__addr)
{
__builtin_ia32_llwpcb(__addr);
}
/// \brief Flushes the LWP state to memory and returns the address of the LWPCB.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> SLWPCB </c> instruction.
///
/// \return
/// Address to the current Lightweight Profiling Control Block (LWPCB).
/// If LWP is not currently enabled, returns NULL.
static __inline__ void* __DEFAULT_FN_ATTRS
__slwpcb ()
{
return __builtin_ia32_slwpcb();
}
/// \brief Inserts programmed event record into the LWP event ring buffer
/// and advances the ring buffer pointer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> LWPINS </c> instruction.
///
/// \param DATA2
/// A 32-bit value is zero-extended and inserted into the 64-bit Data2 field.
/// \param DATA1
/// A 32-bit value is inserted into the 32-bit Data1 field.
/// \param FLAGS
/// A 32-bit immediate value is inserted into the 32-bit Flags field.
/// \returns If the ring buffer is full and LWP is running in Synchronized Mode,
/// the event record overwrites the last record in the buffer, the MissedEvents
/// counter in the LWPCB is incremented, the head pointer is not advanced, and
/// 1 is returned. Otherwise 0 is returned.
#define __lwpins32(DATA2, DATA1, FLAGS) \
(__builtin_ia32_lwpins32((unsigned int) (DATA2), (unsigned int) (DATA1), \
(unsigned int) (FLAGS)))
/// \brief Decrements the LWP programmed value sample event counter. If the result is
/// negative, inserts an event record into the LWP event ring buffer in memory
/// and advances the ring buffer pointer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> LWPVAL </c> instruction.
///
/// \param DATA2
/// A 32-bit value is zero-extended and inserted into the 64-bit Data2 field.
/// \param DATA1
/// A 32-bit value is inserted into the 32-bit Data1 field.
/// \param FLAGS
/// A 32-bit immediate value is inserted into the 32-bit Flags field.
#define __lwpval32(DATA2, DATA1, FLAGS) \
(__builtin_ia32_lwpval32((unsigned int) (DATA2), (unsigned int) (DATA1), \
(unsigned int) (FLAGS)))
#ifdef __x86_64__
/// \brief Inserts programmed event record into the LWP event ring buffer
/// and advances the ring buffer pointer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> LWPINS </c> instruction.
///
/// \param DATA2
/// A 64-bit value is inserted into the 64-bit Data2 field.
/// \param DATA1
/// A 32-bit value is inserted into the 32-bit Data1 field.
/// \param FLAGS
/// A 32-bit immediate value is inserted into the 32-bit Flags field.
/// \returns If the ring buffer is full and LWP is running in Synchronized Mode,
/// the event record overwrites the last record in the buffer, the MissedEvents
/// counter in the LWPCB is incremented, the head pointer is not advanced, and
/// 1 is returned. Otherwise 0 is returned.
#define __lwpins64(DATA2, DATA1, FLAGS) \
(__builtin_ia32_lwpins64((unsigned long long) (DATA2), (unsigned int) (DATA1), \
(unsigned int) (FLAGS)))
/// \brief Decrements the LWP programmed value sample event counter. If the result is
/// negative, inserts an event record into the LWP event ring buffer in memory
/// and advances the ring buffer pointer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> LWPVAL </c> instruction.
///
/// \param DATA2
/// A 64-bit value is and inserted into the 64-bit Data2 field.
/// \param DATA1
/// A 32-bit value is inserted into the 32-bit Data1 field.
/// \param FLAGS
/// A 32-bit immediate value is inserted into the 32-bit Flags field.
#define __lwpval64(DATA2, DATA1, FLAGS) \
(__builtin_ia32_lwpval64((unsigned long long) (DATA2), (unsigned int) (DATA1), \
(unsigned int) (FLAGS)))
#endif
#undef __DEFAULT_FN_ATTRS
#endif /* __LWPINTRIN_H */

@ -72,6 +72,10 @@
#include <tbmintrin.h>
#endif
#if !defined(_MSC_VER) || __has_feature(modules) || defined(__LWP__)
#include <lwpintrin.h>
#endif
#if !defined(_MSC_VER) || __has_feature(modules) || defined(__F16C__)
#include <f16cintrin.h>
#endif

@ -184,9 +184,7 @@ public:
continue;
}
Relations.emplace_back(
SymbolRoleSet(SymbolRole::RelationOverrideOf) |
SymbolRoleSet(SymbolRole::RelationSpecializationOf),
ND);
SymbolRoleSet(SymbolRole::RelationSpecializationOf), ND);
}
}
}

@ -1325,7 +1325,8 @@ static const FileEntry *getPrivateModuleMap(const FileEntry *File,
return FileMgr.getFile(PrivateFilename);
}
bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) {
bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem,
FileID ID, unsigned *Offset) {
// Find the directory for the module. For frameworks, that may require going
// up from the 'Modules' directory.
const DirectoryEntry *Dir = nullptr;
@ -1344,7 +1345,7 @@ bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) {
}
}
switch (loadModuleMapFileImpl(File, IsSystem, Dir)) {
switch (loadModuleMapFileImpl(File, IsSystem, Dir, ID, Offset)) {
case LMM_AlreadyLoaded:
case LMM_NewlyLoaded:
return false;
@ -1357,7 +1358,8 @@ bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) {
HeaderSearch::LoadModuleMapResult
HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem,
const DirectoryEntry *Dir) {
const DirectoryEntry *Dir, FileID ID,
unsigned *Offset) {
assert(File && "expected FileEntry");
// Check whether we've already loaded this module map, and mark it as being
@ -1366,7 +1368,7 @@ HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem,
if (!AddResult.second)
return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
if (ModMap.parseModuleMapFile(File, IsSystem, Dir)) {
if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID, Offset)) {
LoadedModuleMaps[File] = false;
return LMM_InvalidModuleMap;
}

@ -452,6 +452,29 @@ bool Lexer::getRawToken(SourceLocation Loc, Token &Result,
return false;
}
/// Returns the pointer that points to the beginning of line that contains
/// the given offset, or null if the offset if invalid.
static const char *findBeginningOfLine(StringRef Buffer, unsigned Offset) {
const char *BufStart = Buffer.data();
if (Offset >= Buffer.size())
return nullptr;
const char *StrData = BufStart + Offset;
if (StrData[0] == '\n' || StrData[0] == '\r')
return StrData;
const char *LexStart = StrData;
while (LexStart != BufStart) {
if (LexStart[0] == '\n' || LexStart[0] == '\r') {
++LexStart;
break;
}
--LexStart;
}
return LexStart;
}
static SourceLocation getBeginningOfFileToken(SourceLocation Loc,
const SourceManager &SM,
const LangOptions &LangOpts) {
@ -467,27 +490,15 @@ static SourceLocation getBeginningOfFileToken(SourceLocation Loc,
// Back up from the current location until we hit the beginning of a line
// (or the buffer). We'll relex from that point.
const char *BufStart = Buffer.data();
if (LocInfo.second >= Buffer.size())
const char *StrData = Buffer.data() + LocInfo.second;
const char *LexStart = findBeginningOfLine(Buffer, LocInfo.second);
if (!LexStart || LexStart == StrData)
return Loc;
const char *StrData = BufStart+LocInfo.second;
if (StrData[0] == '\n' || StrData[0] == '\r')
return Loc;
const char *LexStart = StrData;
while (LexStart != BufStart) {
if (LexStart[0] == '\n' || LexStart[0] == '\r') {
++LexStart;
break;
}
--LexStart;
}
// Create a lexer starting at the beginning of this token.
SourceLocation LexerStartLoc = Loc.getLocWithOffset(-LocInfo.second);
Lexer TheLexer(LexerStartLoc, LangOpts, BufStart, LexStart, Buffer.end());
Lexer TheLexer(LexerStartLoc, LangOpts, Buffer.data(), LexStart,
Buffer.end());
TheLexer.SetCommentRetentionState(true);
// Lex tokens until we find the token that contains the source location.
@ -1038,6 +1049,27 @@ bool Lexer::isIdentifierBodyChar(char c, const LangOptions &LangOpts) {
return isIdentifierBody(c, LangOpts.DollarIdents);
}
StringRef Lexer::getIndentationForLine(SourceLocation Loc,
const SourceManager &SM) {
if (Loc.isInvalid() || Loc.isMacroID())
return "";
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
if (LocInfo.first.isInvalid())
return "";
bool Invalid = false;
StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid);
if (Invalid)
return "";
const char *Line = findBeginningOfLine(Buffer, LocInfo.second);
if (!Line)
return "";
StringRef Rest = Buffer.substr(Line - Buffer.data());
size_t NumWhitespaceChars = Rest.find_first_not_of(" \t");
return NumWhitespaceChars == StringRef::npos
? ""
: Rest.take_front(NumWhitespaceChars);
}
//===----------------------------------------------------------------------===//
// Diagnostics forwarding code.
//===----------------------------------------------------------------------===//

@ -1132,14 +1132,17 @@ namespace clang {
}
bool parseModuleMapFile();
bool terminatedByDirective() { return false; }
SourceLocation getLocation() { return Tok.getLocation(); }
};
}
SourceLocation ModuleMapParser::consumeToken() {
retry:
SourceLocation Result = Tok.getLocation();
retry:
Tok.clear();
Token LToken;
L.LexFromRawLexer(LToken);
Tok.Location = LToken.getLocation().getRawEncoding();
@ -1232,9 +1235,28 @@ retry:
case tok::comment:
goto retry;
case tok::hash:
// A module map can be terminated prematurely by
// #pragma clang module contents
// When building the module, we'll treat the rest of the file as the
// contents of the module.
{
auto NextIsIdent = [&](StringRef Str) -> bool {
L.LexFromRawLexer(LToken);
return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&
LToken.getRawIdentifier() == Str;
};
if (NextIsIdent("pragma") && NextIsIdent("clang") &&
NextIsIdent("module") && NextIsIdent("contents")) {
Tok.Kind = MMToken::EndOfFile;
break;
}
}
LLVM_FALLTHROUGH;
default:
Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
HadError = true;
goto retry;
}
@ -1682,7 +1704,8 @@ void ModuleMapParser::parseExternModuleDecl() {
File, /*IsSystem=*/false,
Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
? Directory
: File->getDir(), ExternLoc);
: File->getDir(),
FileID(), nullptr, ExternLoc);
}
/// Whether to add the requirement \p Feature to the module \p M.
@ -2522,28 +2545,45 @@ bool ModuleMapParser::parseModuleMapFile() {
}
bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
const DirectoryEntry *Dir,
const DirectoryEntry *Dir, FileID ID,
unsigned *Offset,
SourceLocation ExternModuleLoc) {
assert(Target && "Missing target information");
llvm::DenseMap<const FileEntry *, bool>::iterator Known
= ParsedModuleMap.find(File);
if (Known != ParsedModuleMap.end())
return Known->second;
// If the module map file wasn't already entered, do so now.
if (ID.isInvalid()) {
auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
}
assert(Target && "Missing target information");
auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
if (!Buffer)
return ParsedModuleMap[File] = true;
assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
"invalid buffer offset");
// Parse this module map file.
Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
Buffer->getBufferStart(),
Buffer->getBufferStart() + (Offset ? *Offset : 0),
Buffer->getBufferEnd());
SourceLocation Start = L.getSourceLocation();
ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
BuiltinIncludeDir, IsSystem);
bool Result = Parser.parseModuleMapFile();
ParsedModuleMap[File] = Result;
if (Offset) {
auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation());
assert(Loc.first == ID && "stopped in a different file?");
*Offset = Loc.second;
}
// Notify callbacks that we parsed it.
for (const auto &Cb : Callbacks)
Cb->moduleMapFileRead(Start, *File, IsSystem);

@ -2049,12 +2049,12 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
M->getTopLevelModuleName() == getLangOpts().CurrentModule)
return;
assert(!CurSubmodule && "should not have marked this as a module yet");
CurSubmodule = M;
assert(!CurLexerSubmodule && "should not have marked this as a module yet");
CurLexerSubmodule = M;
// Let the macro handling code know that any future macros are within
// the new submodule.
EnterSubmodule(M, HashLoc);
EnterSubmodule(M, HashLoc, /*ForPragma*/false);
// Let the parser know that any future declarations are within the new
// submodule.
@ -2082,7 +2082,7 @@ void Preprocessor::HandleIncludeNextDirective(SourceLocation HashLoc,
} else if (isInPrimaryFile()) {
Lookup = nullptr;
Diag(IncludeNextTok, diag::pp_include_next_in_primary);
} else if (CurSubmodule) {
} else if (CurLexerSubmodule) {
// Start looking up in the directory *after* the one in which the current
// file would be found, if any.
assert(CurPPLexer && "#include_next directive in macro?");

@ -117,7 +117,7 @@ void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer,
CurLexer.reset(TheLexer);
CurPPLexer = TheLexer;
CurDirLookup = CurDir;
CurSubmodule = nullptr;
CurLexerSubmodule = nullptr;
if (CurLexerKind != CLK_LexAfterModuleImport)
CurLexerKind = CLK_Lexer;
@ -142,7 +142,7 @@ void Preprocessor::EnterSourceFileWithPTH(PTHLexer *PL,
CurDirLookup = CurDir;
CurPTHLexer.reset(PL);
CurPPLexer = CurPTHLexer.get();
CurSubmodule = nullptr;
CurLexerSubmodule = nullptr;
if (CurLexerKind != CLK_LexAfterModuleImport)
CurLexerKind = CLK_PTHLexer;
@ -337,6 +337,26 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
assert(!CurTokenLexer &&
"Ending a file when currently in a macro!");
// If we have an unclosed module region from a pragma at the end of a
// module, complain and close it now.
// FIXME: This is not correct if we are building a module from PTH.
const bool LeavingSubmodule = CurLexer && CurLexerSubmodule;
if ((LeavingSubmodule || IncludeMacroStack.empty()) &&
!BuildingSubmoduleStack.empty() &&
BuildingSubmoduleStack.back().IsPragma) {
Diag(BuildingSubmoduleStack.back().ImportLoc,
diag::err_pp_module_begin_without_module_end);
Module *M = LeaveSubmodule(/*ForPragma*/true);
Result.startToken();
const char *EndPos = getCurLexerEndPos();
CurLexer->BufferPtr = EndPos;
CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end);
Result.setAnnotationEndLoc(Result.getLocation());
Result.setAnnotationValue(M);
return true;
}
// See if this file had a controlling macro.
if (CurPPLexer) { // Not ending a macro, ignore it.
if (const IdentifierInfo *ControllingMacro =
@ -442,18 +462,17 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
if (Callbacks && !isEndOfMacro && CurPPLexer)
ExitedFID = CurPPLexer->getFileID();
bool LeavingSubmodule = CurSubmodule && CurLexer;
if (LeavingSubmodule) {
// We're done with this submodule.
Module *M = LeaveSubmodule(/*ForPragma*/false);
// Notify the parser that we've left the module.
const char *EndPos = getCurLexerEndPos();
Result.startToken();
CurLexer->BufferPtr = EndPos;
CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end);
Result.setAnnotationEndLoc(Result.getLocation());
Result.setAnnotationValue(CurSubmodule);
// We're done with this submodule.
LeaveSubmodule();
Result.setAnnotationValue(M);
}
// We're done with the #included file.
@ -628,11 +647,13 @@ void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) {
assert(!FoundLexer && "Lexer should return EOD before EOF in PP mode");
}
void Preprocessor::EnterSubmodule(Module *M, SourceLocation ImportLoc) {
void Preprocessor::EnterSubmodule(Module *M, SourceLocation ImportLoc,
bool ForPragma) {
if (!getLangOpts().ModulesLocalVisibility) {
// Just track that we entered this submodule.
BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(
M, ImportLoc, CurSubmoduleState, PendingModuleMacroNames.size()));
BuildingSubmoduleStack.push_back(
BuildingSubmoduleInfo(M, ImportLoc, ForPragma, CurSubmoduleState,
PendingModuleMacroNames.size()));
return;
}
@ -673,8 +694,9 @@ void Preprocessor::EnterSubmodule(Module *M, SourceLocation ImportLoc) {
}
// Track that we entered this module.
BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(
M, ImportLoc, CurSubmoduleState, PendingModuleMacroNames.size()));
BuildingSubmoduleStack.push_back(
BuildingSubmoduleInfo(M, ImportLoc, ForPragma, CurSubmoduleState,
PendingModuleMacroNames.size()));
// Switch to this submodule as the current submodule.
CurSubmoduleState = &State;
@ -697,7 +719,13 @@ bool Preprocessor::needModuleMacros() const {
return getLangOpts().isCompilingModule();
}
void Preprocessor::LeaveSubmodule() {
Module *Preprocessor::LeaveSubmodule(bool ForPragma) {
if (BuildingSubmoduleStack.empty() ||
BuildingSubmoduleStack.back().IsPragma != ForPragma) {
assert(ForPragma && "non-pragma module enter/leave mismatch");
return nullptr;
}
auto &Info = BuildingSubmoduleStack.back();
Module *LeavingMod = Info.M;
@ -711,7 +739,7 @@ void Preprocessor::LeaveSubmodule() {
// of pending names for the surrounding submodule.
BuildingSubmoduleStack.pop_back();
makeModuleVisible(LeavingMod, ImportLoc);
return;
return LeavingMod;
}
// Create ModuleMacros for any macros defined in this submodule.
@ -800,4 +828,5 @@ void Preprocessor::LeaveSubmodule() {
// A nested #include makes the included submodule visible.
makeModuleVisible(LeavingMod, ImportLoc);
return LeavingMod;
}

@ -1453,7 +1453,7 @@ static bool EvaluateHasIncludeNext(Token &Tok,
} else if (PP.isInPrimaryFile()) {
Lookup = nullptr;
PP.Diag(Tok, diag::pp_include_next_in_primary);
} else if (PP.getCurrentSubmodule()) {
} else if (PP.getCurrentLexerSubmodule()) {
// Start looking up in the directory *after* the one in which the current
// file would be found, if any.
assert(PP.getCurrentLexer() && "#include_next directive in macro?");

@ -534,47 +534,6 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
}
}
void Preprocessor::HandlePragmaModuleImport(Token &ImportTok) {
SourceLocation ImportLoc = ImportTok.getLocation();
Token Tok;
llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8> ModuleName;
while (true) {
LexUnexpandedToken(Tok);
if (Tok.isNot(tok::identifier)) {
Diag(Tok.getLocation(),
diag::err_pragma_module_import_expected_module_name) << 0;
return;
}
ModuleName.emplace_back(Tok.getIdentifierInfo(), Tok.getLocation());
LexUnexpandedToken(Tok);
assert(Tok.isNot(tok::eof));
if (Tok.is(tok::eod))
break;
if (Tok.isNot(tok::period)) {
Diag(Tok.getLocation(),
diag::err_pragma_module_import_expected_module_name) << 1;
return;
}
}
// If we have a non-empty module path, load the named module.
Module *Imported =
TheModuleLoader.loadModule(ImportLoc, ModuleName, Module::Hidden,
/*IsIncludeDirective=*/false);
if (!Imported)
return;
makeModuleVisible(Imported, ImportLoc);
EnterAnnotationToken(SourceRange(ImportLoc, Tok.getLocation()),
tok::annot_module_include, Imported);
if (Callbacks)
Callbacks->moduleImport(ImportLoc, ModuleName, Imported);
}
/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
/// Return the IdentifierInfo* associated with the macro to push or pop.
IdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {
@ -1342,6 +1301,26 @@ public:
}
};
static bool LexModuleName(
Preprocessor &PP, Token &Tok,
llvm::SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>>
&ModuleName) {
while (true) {
PP.LexUnexpandedToken(Tok);
if (Tok.isAnnotation() || !Tok.getIdentifierInfo()) {
PP.Diag(Tok.getLocation(), diag::err_pp_expected_module_name)
<< ModuleName.empty();
return true;
}
ModuleName.emplace_back(Tok.getIdentifierInfo(), Tok.getLocation());
PP.LexUnexpandedToken(Tok);
if (Tok.isNot(tok::period))
return false;
}
}
/// Handle the clang \#pragma module import extension. The syntax is:
/// \code
/// #pragma clang module import some.module.name
@ -1350,8 +1329,108 @@ struct PragmaModuleImportHandler : public PragmaHandler {
PragmaModuleImportHandler() : PragmaHandler("import") {}
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &ImportTok) override {
PP.HandlePragmaModuleImport(ImportTok);
Token &Tok) override {
SourceLocation ImportLoc = Tok.getLocation();
// Read the module name.
llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8>
ModuleName;
if (LexModuleName(PP, Tok, ModuleName))
return;
if (Tok.isNot(tok::eod))
PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
// If we have a non-empty module path, load the named module.
Module *Imported =
PP.getModuleLoader().loadModule(ImportLoc, ModuleName, Module::Hidden,
/*IsIncludeDirective=*/false);
if (!Imported)
return;
PP.makeModuleVisible(Imported, ImportLoc);
PP.EnterAnnotationToken(SourceRange(ImportLoc, ModuleName.back().second),
tok::annot_module_include, Imported);
if (auto *CB = PP.getPPCallbacks())
CB->moduleImport(ImportLoc, ModuleName, Imported);
}
};
/// Handle the clang \#pragma module begin extension. The syntax is:
/// \code
/// #pragma clang module begin some.module.name
/// ...
/// #pragma clang module end
/// \endcode
struct PragmaModuleBeginHandler : public PragmaHandler {
PragmaModuleBeginHandler() : PragmaHandler("begin") {}
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &Tok) override {
SourceLocation BeginLoc = Tok.getLocation();
// Read the module name.
llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8>
ModuleName;
if (LexModuleName(PP, Tok, ModuleName))
return;
if (Tok.isNot(tok::eod))
PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
// We can only enter submodules of the current module.
StringRef Current = PP.getLangOpts().CurrentModule;
if (ModuleName.front().first->getName() != Current) {
PP.Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module)
<< ModuleName.front().first << (ModuleName.size() > 1)
<< Current.empty() << Current;
return;
}
// Find the module we're entering. We require that a module map for it
// be loaded or implicitly loadable.
// FIXME: We could create the submodule here. We'd need to know whether
// it's supposed to be explicit, but not much else.
Module *M = PP.getHeaderSearchInfo().getModuleMap().findModule(Current);
if (!M) {
PP.Diag(ModuleName.front().second,
diag::err_pp_module_begin_no_module_map) << Current;
return;
}
for (unsigned I = 1; I != ModuleName.size(); ++I) {
auto *NewM = M->findSubmodule(ModuleName[I].first->getName());
if (!NewM) {
PP.Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)
<< M->getFullModuleName() << ModuleName[I].first;
return;
}
M = NewM;
}
// Enter the scope of the submodule.
PP.EnterSubmodule(M, BeginLoc, /*ForPragma*/true);
PP.EnterAnnotationToken(SourceRange(BeginLoc, ModuleName.back().second),
tok::annot_module_begin, M);
}
};
/// Handle the clang \#pragma module end extension.
struct PragmaModuleEndHandler : public PragmaHandler {
PragmaModuleEndHandler() : PragmaHandler("end") {}
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &Tok) override {
SourceLocation Loc = Tok.getLocation();
PP.LexUnexpandedToken(Tok);
if (Tok.isNot(tok::eod))
PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
Module *M = PP.LeaveSubmodule(/*ForPragma*/true);
if (M)
PP.EnterAnnotationToken(SourceRange(Loc), tok::annot_module_end, M);
else
PP.Diag(Loc, diag::err_pp_module_end_without_module_begin);
}
};
@ -1582,6 +1661,8 @@ void Preprocessor::RegisterBuiltinPragmas() {
auto *ModuleHandler = new PragmaNamespace("module");
AddPragmaHandler("clang", ModuleHandler);
ModuleHandler->AddPragma(new PragmaModuleImportHandler());
ModuleHandler->AddPragma(new PragmaModuleBeginHandler());
ModuleHandler->AddPragma(new PragmaModuleEndHandler());
AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler());

@ -85,10 +85,10 @@ Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
LastTokenWasAt(false), ModuleImportExpectsIdentifier(false),
CodeCompletionReached(false), CodeCompletionII(nullptr),
MainFileDir(nullptr), SkipMainFilePreamble(0, true), CurPPLexer(nullptr),
CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr),
Callbacks(nullptr), CurSubmoduleState(&NullSubmoduleState),
MacroArgCache(nullptr), Record(nullptr), MIChainHead(nullptr),
DeserialMIChainHead(nullptr) {
CurDirLookup(nullptr), CurLexerKind(CLK_Lexer),
CurLexerSubmodule(nullptr), Callbacks(nullptr),
CurSubmoduleState(&NullSubmoduleState), MacroArgCache(nullptr),
Record(nullptr), MIChainHead(nullptr), DeserialMIChainHead(nullptr) {
OwnsHeaderSearch = OwnsHeaders;
CounterValue = 0; // __COUNTER__ starts at 0.

@ -183,6 +183,12 @@ void TokenLexer::ExpandFunctionArguments() {
// preprocessor already verified that the following token is a macro name
// when the #define was parsed.
const Token &CurTok = Tokens[i];
// We don't want a space for the next token after a paste
// operator. In valid code, the token will get smooshed onto the
// preceding one anyway. In assembler-with-cpp mode, invalid
// pastes are allowed through: in this case, we do not want the
// extra whitespace to be added. For example, we want ". ## foo"
// -> ".foo" not ". foo".
if (i != 0 && !Tokens[i-1].is(tok::hashhash) && CurTok.hasLeadingSpace())
NextTokGetsSpace = true;
@ -317,6 +323,7 @@ void TokenLexer::ExpandFunctionArguments() {
const Token *ArgToks = ActualArgs->getUnexpArgument(ArgNo);
unsigned NumToks = MacroArgs::getArgLength(ArgToks);
if (NumToks) { // Not an empty argument?
bool VaArgsPseudoPaste = false;
// If this is the GNU ", ## __VA_ARGS__" extension, and we just learned
// that __VA_ARGS__ expands to multiple tokens, avoid a pasting error when
// the expander trys to paste ',' with the first token of the __VA_ARGS__
@ -325,6 +332,7 @@ void TokenLexer::ExpandFunctionArguments() {
ResultToks[ResultToks.size()-2].is(tok::comma) &&
(unsigned)ArgNo == Macro->getNumArgs()-1 &&
Macro->isVariadic()) {
VaArgsPseudoPaste = true;
// Remove the paste operator, report use of the extension.
PP.Diag(ResultToks.pop_back_val().getLocation(), diag::ext_paste_comma);
}
@ -344,18 +352,16 @@ void TokenLexer::ExpandFunctionArguments() {
ResultToks.end()-NumToks, ResultToks.end());
}
// If this token (the macro argument) was supposed to get leading
// whitespace, transfer this information onto the first token of the
// expansion.
//
// Do not do this if the paste operator occurs before the macro argument,
// as in "A ## MACROARG". In valid code, the first token will get
// smooshed onto the preceding one anyway (forming AMACROARG). In
// assembler-with-cpp mode, invalid pastes are allowed through: in this
// case, we do not want the extra whitespace to be added. For example,
// we want ". ## foo" -> ".foo" not ". foo".
if (NextTokGetsSpace)
ResultToks[ResultToks.size()-NumToks].setFlag(Token::LeadingSpace);
// Transfer the leading whitespace information from the token
// (the macro argument) onto the first token of the
// expansion. Note that we don't do this for the GNU
// pseudo-paste extension ", ## __VA_ARGS__".
if (!VaArgsPseudoPaste) {
ResultToks[ResultToks.size() - NumToks].setFlagValue(Token::StartOfLine,
false);
ResultToks[ResultToks.size() - NumToks].setFlagValue(
Token::LeadingSpace, NextTokGetsSpace);
}
NextTokGetsSpace = false;
continue;

@ -4151,8 +4151,6 @@ void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {
}
if (!T.consumeClose()) {
// FIXME: Warn that this syntax is deprecated, with a Fix-It suggesting
// using __declspec(uuid()) instead.
Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()), nullptr,
SourceLocation(), ArgExprs.data(), ArgExprs.size(),
AttributeList::AS_Microsoft);

@ -383,6 +383,19 @@ void Sema::diagnoseNullableToNonnullConversion(QualType DstType,
Diag(Loc, diag::warn_nullability_lost) << SrcType << DstType;
}
void Sema::diagnoseZeroToNullptrConversion(CastKind Kind, const Expr* E) {
if (Kind != CK_NullToPointer && Kind != CK_NullToMemberPointer)
return;
if (E->getType()->isNullPtrType())
return;
// nullptr only exists from C++11 on, so don't warn on its absence earlier.
if (!getLangOpts().CPlusPlus11)
return;
Diag(E->getLocStart(), diag::warn_zero_as_null_pointer_constant)
<< FixItHint::CreateReplacement(E->getSourceRange(), "nullptr");
}
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
/// If there is already an implicit cast, merge into the existing one.
/// The result is of the given category.
@ -407,6 +420,7 @@ ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
#endif
diagnoseNullableToNonnullConversion(Ty, E->getType(), E->getLocStart());
diagnoseZeroToNullptrConversion(Kind, E);
QualType ExprTy = Context.getCanonicalType(E->getType());
QualType TypeTy = Context.getCanonicalType(Ty);

@ -3652,22 +3652,29 @@ static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn,
// and get its parameter list.
bool IsVariadic = false;
ArrayRef<ParmVarDecl *> Params;
if (BlockScopeInfo *CurBlock = S.getCurBlock()) {
IsVariadic = CurBlock->TheDecl->isVariadic();
Params = CurBlock->TheDecl->parameters();
} else if (FunctionDecl *FD = S.getCurFunctionDecl()) {
DeclContext *Caller = S.CurContext;
if (auto *Block = dyn_cast<BlockDecl>(Caller)) {
IsVariadic = Block->isVariadic();
Params = Block->parameters();
} else if (auto *FD = dyn_cast<FunctionDecl>(Caller)) {
IsVariadic = FD->isVariadic();
Params = FD->parameters();
} else if (ObjCMethodDecl *MD = S.getCurMethodDecl()) {
} else if (auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
IsVariadic = MD->isVariadic();
// FIXME: This isn't correct for methods (results in bogus warning).
Params = MD->parameters();
} else if (isa<CapturedDecl>(Caller)) {
// We don't support va_start in a CapturedDecl.
S.Diag(Fn->getLocStart(), diag::err_va_start_captured_stmt);
return true;
} else {
llvm_unreachable("unknown va_start context");
// This must be some other declcontext that parses exprs.
S.Diag(Fn->getLocStart(), diag::err_va_start_outside_function);
return true;
}
if (!IsVariadic) {
S.Diag(Fn->getLocStart(), diag::err_va_start_used_in_non_variadic_function);
S.Diag(Fn->getLocStart(), diag::err_va_start_fixed_function);
return true;
}

@ -6070,12 +6070,24 @@ NamedDecl *Sema::ActOnVariableDeclarator(
}
}
// OpenCL v1.2 s6.9.b p4:
// The sampler type cannot be used with the __local and __global address
// space qualifiers.
if (R->isSamplerT() && (R.getAddressSpace() == LangAS::opencl_local ||
R.getAddressSpace() == LangAS::opencl_global)) {
Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace);
if (R->isSamplerT()) {
// OpenCL v1.2 s6.9.b p4:
// The sampler type cannot be used with the __local and __global address
// space qualifiers.
if (R.getAddressSpace() == LangAS::opencl_local ||
R.getAddressSpace() == LangAS::opencl_global) {
Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace);
}
// OpenCL v1.2 s6.12.14.1:
// A global sampler must be declared with either the constant address
// space qualifier or with the const qualifier.
if (DC->isTranslationUnit() &&
!(R.getAddressSpace() == LangAS::opencl_constant ||
R.isConstQualified())) {
Diag(D.getIdentifierLoc(), diag::err_opencl_nonconst_global_sampler);
D.setInvalidType();
}
}
// OpenCL v1.2 s6.9.r:
@ -15902,7 +15914,7 @@ void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) {
VisibleModules.setVisible(Mod, DirectiveLoc);
}
void Sema::ActOnModuleEnd(SourceLocation EofLoc, Module *Mod) {
void Sema::ActOnModuleEnd(SourceLocation EomLoc, Module *Mod) {
if (getLangOpts().ModulesLocalVisibility) {
VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
// Leaving a module hides namespace names, so our visible namespace cache
@ -15914,12 +15926,19 @@ void Sema::ActOnModuleEnd(SourceLocation EofLoc, Module *Mod) {
"left the wrong module scope");
ModuleScopes.pop_back();
// We got to the end of processing a #include of a local module. Create an
// We got to the end of processing a local module. Create an
// ImportDecl as we would for an imported module.
FileID File = getSourceManager().getFileID(EofLoc);
assert(File != getSourceManager().getMainFileID() &&
"end of submodule in main source file");
SourceLocation DirectiveLoc = getSourceManager().getIncludeLoc(File);
FileID File = getSourceManager().getFileID(EomLoc);
SourceLocation DirectiveLoc;
if (EomLoc == getSourceManager().getLocForEndOfFile(File)) {
// We reached the end of a #included module header. Use the #include loc.
assert(File != getSourceManager().getMainFileID() &&
"end of submodule in main source file");
DirectiveLoc = getSourceManager().getIncludeLoc(File);
} else {
// We reached an EOM pragma. Use the pragma location.
DirectiveLoc = EomLoc;
}
BuildModuleInclude(DirectiveLoc, Mod);
}

@ -2891,6 +2891,28 @@ static void handleWorkGroupSize(Sema &S, Decl *D,
Attr.getAttributeSpellingListIndex()));
}
// Handles intel_reqd_sub_group_size.
static void handleSubGroupSize(Sema &S, Decl *D, const AttributeList &Attr) {
uint32_t SGSize;
const Expr *E = Attr.getArgAsExpr(0);
if (!checkUInt32Argument(S, Attr, E, SGSize))
return;
if (SGSize == 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero)
<< Attr.getName() << E->getSourceRange();
return;
}
OpenCLIntelReqdSubGroupSizeAttr *Existing =
D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>();
if (Existing && Existing->getSubGroupSize() != SGSize)
S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
D->addAttr(::new (S.Context) OpenCLIntelReqdSubGroupSizeAttr(
Attr.getRange(), S.Context, SGSize,
Attr.getAttributeSpellingListIndex()));
}
static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) {
if (!Attr.hasParsedType()) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
@ -5057,6 +5079,15 @@ static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
}
}
// FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's
// the only thing in the [] list, the [] too), and add an insertion of
// __declspec(uuid(...)). But sadly, neither the SourceLocs of the commas
// separating attributes nor of the [ and the ] are in the AST.
// Cf "SourceLocations of attribute list delimiters - [[ ... , ... ]] etc"
// on cfe-dev.
if (Attr.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.
S.Diag(Attr.getLoc(), diag::warn_atl_uuid_deprecated);
UuidAttr *UA = S.mergeUuidAttr(D, Attr.getRange(),
Attr.getAttributeSpellingListIndex(), StrRef);
if (UA)
@ -6157,6 +6188,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_ReqdWorkGroupSize:
handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, Attr);
break;
case AttributeList::AT_OpenCLIntelReqdSubGroupSize:
handleSubGroupSize(S, D, Attr);
break;
case AttributeList::AT_VecTypeHint:
handleVecTypeHint(S, D, Attr);
break;
@ -6521,6 +6555,9 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
<< A << ExpectedKernelFunction;
D->setInvalidDecl();
} else if (Attr *A = D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
D->setInvalidDecl();
}
}
}
@ -7104,6 +7141,69 @@ void Sema::EmitAvailabilityWarning(AvailabilityResult AR,
namespace {
/// Returns true if the given statement can be a body-like child of \p Parent.
bool isBodyLikeChildStmt(const Stmt *S, const Stmt *Parent) {
switch (Parent->getStmtClass()) {
case Stmt::IfStmtClass:
return cast<IfStmt>(Parent)->getThen() == S ||
cast<IfStmt>(Parent)->getElse() == S;
case Stmt::WhileStmtClass:
return cast<WhileStmt>(Parent)->getBody() == S;
case Stmt::DoStmtClass:
return cast<DoStmt>(Parent)->getBody() == S;
case Stmt::ForStmtClass:
return cast<ForStmt>(Parent)->getBody() == S;
case Stmt::CXXForRangeStmtClass:
return cast<CXXForRangeStmt>(Parent)->getBody() == S;
case Stmt::ObjCForCollectionStmtClass:
return cast<ObjCForCollectionStmt>(Parent)->getBody() == S;
case Stmt::CaseStmtClass:
case Stmt::DefaultStmtClass:
return cast<SwitchCase>(Parent)->getSubStmt() == S;
default:
return false;
}
}
class StmtUSEFinder : public RecursiveASTVisitor<StmtUSEFinder> {
const Stmt *Target;
public:
bool VisitStmt(Stmt *S) { return S != Target; }
/// Returns true if the given statement is present in the given declaration.
static bool isContained(const Stmt *Target, const Decl *D) {
StmtUSEFinder Visitor;
Visitor.Target = Target;
return !Visitor.TraverseDecl(const_cast<Decl *>(D));
}
};
/// Traverses the AST and finds the last statement that used a given
/// declaration.
class LastDeclUSEFinder : public RecursiveASTVisitor<LastDeclUSEFinder> {
const Decl *D;
public:
bool VisitDeclRefExpr(DeclRefExpr *DRE) {
if (DRE->getDecl() == D)
return false;
return true;
}
static const Stmt *findLastStmtThatUsesDecl(const Decl *D,
const CompoundStmt *Scope) {
LastDeclUSEFinder Visitor;
Visitor.D = D;
for (auto I = Scope->body_rbegin(), E = Scope->body_rend(); I != E; ++I) {
const Stmt *S = *I;
if (!Visitor.TraverseStmt(const_cast<Stmt *>(S)))
return S;
}
return nullptr;
}
};
/// \brief This class implements -Wunguarded-availability.
///
/// This is done with a traversal of the AST of a function that makes reference
@ -7119,6 +7219,7 @@ class DiagnoseUnguardedAvailability
/// Stack of potentially nested 'if (@available(...))'s.
SmallVector<VersionTuple, 8> AvailabilityStack;
SmallVector<const Stmt *, 16> StmtStack;
void DiagnoseDeclAvailability(NamedDecl *D, SourceRange Range);
@ -7129,6 +7230,15 @@ public:
SemaRef.Context.getTargetInfo().getPlatformMinVersion());
}
bool TraverseStmt(Stmt *S) {
if (!S)
return true;
StmtStack.push_back(S);
bool Result = Base::TraverseStmt(S);
StmtStack.pop_back();
return Result;
}
void IssueDiagnostics(Stmt *S) { TraverseStmt(S); }
bool TraverseIfStmt(IfStmt *If);
@ -7186,9 +7296,73 @@ void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
SemaRef.Diag(D->getLocation(), diag::note_availability_specified_here)
<< D << /* partial */ 3;
// FIXME: Replace this with a fixit diagnostic.
SemaRef.Diag(Range.getBegin(), diag::note_unguarded_available_silence)
<< Range << D;
auto FixitDiag =
SemaRef.Diag(Range.getBegin(), diag::note_unguarded_available_silence)
<< Range << D
<< (SemaRef.getLangOpts().ObjC1 ? /*@available*/ 0
: /*__builtin_available*/ 1);
// Find the statement which should be enclosed in the if @available check.
if (StmtStack.empty())
return;
const Stmt *StmtOfUse = StmtStack.back();
const CompoundStmt *Scope = nullptr;
for (const Stmt *S : llvm::reverse(StmtStack)) {
if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
Scope = CS;
break;
}
if (isBodyLikeChildStmt(StmtOfUse, S)) {
// The declaration won't be seen outside of the statement, so we don't
// have to wrap the uses of any declared variables in if (@available).
// Therefore we can avoid setting Scope here.
break;
}
StmtOfUse = S;
}
const Stmt *LastStmtOfUse = nullptr;
if (isa<DeclStmt>(StmtOfUse) && Scope) {
for (const Decl *D : cast<DeclStmt>(StmtOfUse)->decls()) {
if (StmtUSEFinder::isContained(StmtStack.back(), D)) {
LastStmtOfUse = LastDeclUSEFinder::findLastStmtThatUsesDecl(D, Scope);
break;
}
}
}
const SourceManager &SM = SemaRef.getSourceManager();
SourceLocation IfInsertionLoc =
SM.getExpansionLoc(StmtOfUse->getLocStart());
SourceLocation StmtEndLoc =
SM.getExpansionRange(
(LastStmtOfUse ? LastStmtOfUse : StmtOfUse)->getLocEnd())
.second;
if (SM.getFileID(IfInsertionLoc) != SM.getFileID(StmtEndLoc))
return;
StringRef Indentation = Lexer::getIndentationForLine(IfInsertionLoc, SM);
const char *ExtraIndentation = " ";
std::string FixItString;
llvm::raw_string_ostream FixItOS(FixItString);
FixItOS << "if (" << (SemaRef.getLangOpts().ObjC1 ? "@available"
: "__builtin_available")
<< "(" << SemaRef.getASTContext().getTargetInfo().getPlatformName()
<< " " << Introduced.getAsString() << ", *)) {\n"
<< Indentation << ExtraIndentation;
FixitDiag << FixItHint::CreateInsertion(IfInsertionLoc, FixItOS.str());
SourceLocation ElseInsertionLoc = Lexer::findLocationAfterToken(
StmtEndLoc, tok::semi, SM, SemaRef.getLangOpts(),
/*SkipTrailingWhitespaceAndNewLine=*/false);
if (ElseInsertionLoc.isInvalid())
ElseInsertionLoc =
Lexer::getLocForEndOfToken(StmtEndLoc, 0, SM, SemaRef.getLangOpts());
FixItOS.str().clear();
FixItOS << "\n"
<< Indentation << "} else {\n"
<< Indentation << ExtraIndentation
<< "// Fallback on earlier versions\n"
<< Indentation << "}";
FixitDiag << FixItHint::CreateInsertion(ElseInsertionLoc, FixItOS.str());
}
}

@ -4347,10 +4347,8 @@ static void checkObjCMethodX86VectorTypes(Sema &SemaRef,
AcceptedInVersion = VersionTuple(/*Major=*/10, /*Minor=*/11);
else
return;
VersionTuple MethodVersion = Method->getVersionIntroduced();
if (SemaRef.getASTContext().getTargetInfo().getPlatformMinVersion() >=
AcceptedInVersion &&
(MethodVersion.empty() || MethodVersion >= AcceptedInVersion))
AcceptedInVersion)
return;
SemaRef.Diag(Loc, diag::err_objc_method_unsupported_param_ret_type)
<< T << (Method->getReturnType()->isVectorType() ? /*return value*/ 1

@ -5399,9 +5399,11 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
// that the callee might not preserve them. This is easy to diagnose here,
// but can be very challenging to debug.
if (auto *Caller = getCurFunctionDecl())
if (Caller->hasAttr<ARMInterruptAttr>())
if (!FDecl || !FDecl->hasAttr<ARMInterruptAttr>())
if (Caller->hasAttr<ARMInterruptAttr>()) {
bool VFP = Context.getTargetInfo().hasFeature("vfp");
if (VFP && (!FDecl || !FDecl->hasAttr<ARMInterruptAttr>()))
Diag(Fn->getExprLoc(), diag::warn_arm_interrupt_calling_convention);
}
// Promote the function operand.
// We special-case function promotion here because we only allow promoting

@ -2828,7 +2828,7 @@ Sema::PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
// [...] If the first overload resolution fails or was not performed, or
// if the type of the first parameter of the selected constructor is not
// an rvalue reference to the objects type (possibly cv-qualified),
// an rvalue reference to the object's type (possibly cv-qualified),
// overload resolution is performed again, considering the object as an
// lvalue.
if (!RRefType ||

@ -146,12 +146,8 @@ class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin {
loadFromDirectory(StringRef Directory, std::string &ErrorMessage) override {
SmallString<1024> JSONDatabasePath(Directory);
llvm::sys::path::append(JSONDatabasePath, "compile_commands.json");
std::unique_ptr<CompilationDatabase> Database(
JSONCompilationDatabase::loadFromFile(
JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect));
if (!Database)
return nullptr;
return Database;
return JSONCompilationDatabase::loadFromFile(
JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect);
}
};

@ -0,0 +1,67 @@
// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s --check-prefix=CHECK-GNU-C
// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-GNU-CXX
// Empty structs are ignored for PCS purposes on Darwin and in C mode elsewhere.
// In C++ mode on ELF they consume a register slot though. Functions are
// slightly bigger than minimal to make confirmation against actual GCC
// behaviour easier.
#if __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
struct Empty {};
// CHECK: define i32 @empty_arg(i32 %a)
// CHECK-GNU-C: define i32 @empty_arg(i32 %a)
// CHECK-GNU-CXX: define i32 @empty_arg(i8 %e.coerce, i32 %a)
EXTERNC int empty_arg(struct Empty e, int a) {
return a;
}
// CHECK: define void @empty_ret()
// CHECK-GNU-C: define void @empty_ret()
// CHECK-GNU-CXX: define void @empty_ret()
EXTERNC struct Empty empty_ret() {
struct Empty e;
return e;
}
// However, what counts as "empty" is a baroque mess. This is super-empty, it's
// ignored even in C++ mode. It also has sizeof == 0, violating C++, but that's
// legacy for you:
struct SuperEmpty {
int arr[0];
};
// CHECK: define i32 @super_empty_arg(i32 %a)
// CHECK-GNU-C: define i32 @super_empty_arg(i32 %a)
// CHECK-GNU-CXX: define i32 @super_empty_arg(i32 %a)
EXTERNC int super_empty_arg(struct SuperEmpty e, int a) {
return a;
}
// This is not empty. It has 0 size but consumes a register slot for GCC.
struct SortOfEmpty {
struct SuperEmpty e;
};
// CHECK: define i32 @sort_of_empty_arg(i32 %a)
// CHECK-GNU-C: define i32 @sort_of_empty_arg(i32 %a)
// CHECK-GNU-CXX: define i32 @sort_of_empty_arg(i8 %e.coerce, i32 %a)
EXTERNC int sort_of_empty_arg(struct Empty e, int a) {
return a;
}
// CHECK: define void @sort_of_empty_ret()
// CHECK-GNU-C: define void @sort_of_empty_ret()
// CHECK-GNU-CXX: define void @sort_of_empty_ret()
EXTERNC struct SortOfEmpty sort_of_empty_ret() {
struct SortOfEmpty e;
return e;
}

@ -76,7 +76,7 @@ void test_dbg(void) {
// AArch32: call i32 @llvm.arm.strex
// AArch64: call i64 @llvm.aarch64.ldxr
// AArch64: call i32 @llvm.aarch64.stxr
uint32_t test_swp(uint32_t x, volatile void *p) {
void test_swp(uint32_t x, volatile void *p) {
__swp(x, p);
}
@ -118,6 +118,7 @@ void test_nop(void) {
}
/* 9 DATA-PROCESSING INTRINSICS */
/* 9.2 Miscellaneous data-processing intrinsics */
// ARM-LABEL: test_ror
// ARM: lshr
@ -266,8 +267,7 @@ uint64_t test_rbitll(uint64_t t) {
}
/* 9.4 Saturating intrinsics */
#ifdef __ARM_32BIT_STATE
#ifdef __ARM_FEATURE_SAT
/* 9.4.1 Width-specified saturation intrinsics */
// AArch32-LABEL: test_ssat
// AArch32: call i32 @llvm.arm.ssat(i32 %t, i32 1)
@ -277,11 +277,13 @@ int32_t test_ssat(int32_t t) {
// AArch32-LABEL: test_usat
// AArch32: call i32 @llvm.arm.usat(i32 %t, i32 2)
int32_t test_usat(int32_t t) {
uint32_t test_usat(int32_t t) {
return __usat(t, 2);
}
#endif
/* 9.4.2 Saturating addition and subtraction intrinsics */
#ifdef __ARM_FEATURE_DSP
// AArch32-LABEL: test_qadd
// AArch32: call i32 @llvm.arm.qadd(i32 %a, i32 %b)
int32_t test_qadd(int32_t a, int32_t b) {
@ -304,6 +306,389 @@ int32_t test_qdbl() {
}
#endif
/*
* 9.3 16-bit multiplications
*/
#if __ARM_FEATURE_DSP
// AArch32-LABEL: test_smulbb
// AArch32: call i32 @llvm.arm.smulbb
int32_t test_smulbb(int32_t a, int32_t b) {
return __smulbb(a, b);
}
// AArch32-LABEL: test_smulbt
// AArch32: call i32 @llvm.arm.smulbt
int32_t test_smulbt(int32_t a, int32_t b) {
return __smulbt(a, b);
}
// AArch32-LABEL: test_smultb
// AArch32: call i32 @llvm.arm.smultb
int32_t test_smultb(int32_t a, int32_t b) {
return __smultb(a, b);
}
// AArch32-LABEL: test_smultt
// AArch32: call i32 @llvm.arm.smultt
int32_t test_smultt(int32_t a, int32_t b) {
return __smultt(a, b);
}
// AArch32-LABEL: test_smulwb
// AArch32: call i32 @llvm.arm.smulwb
int32_t test_smulwb(int32_t a, int32_t b) {
return __smulwb(a, b);
}
// AArch32-LABEL: test_smulwt
// AArch32: call i32 @llvm.arm.smulwt
int32_t test_smulwt(int32_t a, int32_t b) {
return __smulwt(a, b);
}
#endif
/* 9.4.3 Accumultating multiplications */
#if __ARM_FEATURE_DSP
// AArch32-LABEL: test_smlabb
// AArch32: call i32 @llvm.arm.smlabb(i32 %a, i32 %b, i32 %c)
int32_t test_smlabb(int32_t a, int32_t b, int32_t c) {
return __smlabb(a, b, c);
}
// AArch32-LABEL: test_smlabt
// AArch32: call i32 @llvm.arm.smlabt(i32 %a, i32 %b, i32 %c)
int32_t test_smlabt(int32_t a, int32_t b, int32_t c) {
return __smlabt(a, b, c);
}
// AArch32-LABEL: test_smlatb
// AArch32: call i32 @llvm.arm.smlatb(i32 %a, i32 %b, i32 %c)
int32_t test_smlatb(int32_t a, int32_t b, int32_t c) {
return __smlatb(a, b, c);
}
// AArch32-LABEL: test_smlatt
// AArch32: call i32 @llvm.arm.smlatt(i32 %a, i32 %b, i32 %c)
int32_t test_smlatt(int32_t a, int32_t b, int32_t c) {
return __smlatt(a, b, c);
}
// AArch32-LABEL: test_smlawb
// AArch32: call i32 @llvm.arm.smlawb(i32 %a, i32 %b, i32 %c)
int32_t test_smlawb(int32_t a, int32_t b, int32_t c) {
return __smlawb(a, b, c);
}
// AArch32-LABEL: test_smlawt
// AArch32: call i32 @llvm.arm.smlawt(i32 %a, i32 %b, i32 %c)
int32_t test_smlawt(int32_t a, int32_t b, int32_t c) {
return __smlawt(a, b, c);
}
#endif
/* 9.5.4 Parallel 16-bit saturation */
#if __ARM_FEATURE_SIMD32
// AArch32-LABEL: test_ssat16
// AArch32: call i32 @llvm.arm.ssat16
int16x2_t test_ssat16(int16x2_t a) {
return __ssat16(a, 15);
}
// AArch32-LABEL: test_usat16
// AArch32: call i32 @llvm.arm.usat16
uint16x2_t test_usat16(int16x2_t a) {
return __usat16(a, 15);
}
#endif
/* 9.5.5 Packing and unpacking */
#if __ARM_FEATURE_SIMD32
// AArch32-LABEL: test_sxtab16
// AArch32: call i32 @llvm.arm.sxtab16
int16x2_t test_sxtab16(int16x2_t a, int8x4_t b) {
return __sxtab16(a, b);
}
// AArch32-LABEL: test_sxtb16
// AArch32: call i32 @llvm.arm.sxtb16
int16x2_t test_sxtb16(int8x4_t a) {
return __sxtb16(a);
}
// AArch32-LABEL: test_uxtab16
// AArch32: call i32 @llvm.arm.uxtab16
int16x2_t test_uxtab16(int16x2_t a, int8x4_t b) {
return __uxtab16(a, b);
}
// AArch32-LABEL: test_uxtb16
// AArch32: call i32 @llvm.arm.uxtb16
int16x2_t test_uxtb16(int8x4_t a) {
return __uxtb16(a);
}
#endif
/* 9.5.6 Parallel selection */
#if __ARM_FEATURE_SIMD32
// AArch32-LABEL: test_sel
// AArch32: call i32 @llvm.arm.sel
uint8x4_t test_sel(uint8x4_t a, uint8x4_t b) {
return __sel(a, b);
}
#endif
/* 9.5.7 Parallel 8-bit addition and subtraction */
#if __ARM_FEATURE_SIMD32
// AArch32-LABEL: test_qadd8
// AArch32: call i32 @llvm.arm.qadd8
int16x2_t test_qadd8(int8x4_t a, int8x4_t b) {
return __qadd8(a, b);
}
// AArch32-LABEL: test_qsub8
// AArch32: call i32 @llvm.arm.qsub8
int8x4_t test_qsub8(int8x4_t a, int8x4_t b) {
return __qsub8(a, b);
}
// AArch32-LABEL: test_sadd8
// AArch32: call i32 @llvm.arm.sadd8
int8x4_t test_sadd8(int8x4_t a, int8x4_t b) {
return __sadd8(a, b);
}
// AArch32-LABEL: test_shadd8
// AArch32: call i32 @llvm.arm.shadd8
int8x4_t test_shadd8(int8x4_t a, int8x4_t b) {
return __shadd8(a, b);
}
// AArch32-LABEL: test_shsub8
// AArch32: call i32 @llvm.arm.shsub8
int8x4_t test_shsub8(int8x4_t a, int8x4_t b) {
return __shsub8(a, b);
}
// AArch32-LABEL: test_ssub8
// AArch32: call i32 @llvm.arm.ssub8
int8x4_t test_ssub8(int8x4_t a, int8x4_t b) {
return __ssub8(a, b);
}
// AArch32-LABEL: test_uadd8
// AArch32: call i32 @llvm.arm.uadd8
uint8x4_t test_uadd8(uint8x4_t a, uint8x4_t b) {
return __uadd8(a, b);
}
// AArch32-LABEL: test_uhadd8
// AArch32: call i32 @llvm.arm.uhadd8
uint8x4_t test_uhadd8(uint8x4_t a, uint8x4_t b) {
return __uhadd8(a, b);
}
// AArch32-LABEL: test_uhsub8
// AArch32: call i32 @llvm.arm.uhsub8
uint8x4_t test_uhsub8(uint8x4_t a, uint8x4_t b) {
return __uhsub8(a, b);
}
// AArch32-LABEL: test_uqadd8
// AArch32: call i32 @llvm.arm.uqadd8
uint8x4_t test_uqadd8(uint8x4_t a, uint8x4_t b) {
return __uqadd8(a, b);
}
// AArch32-LABEL: test_uqsub8
// AArch32: call i32 @llvm.arm.uqsub8
uint8x4_t test_uqsub8(uint8x4_t a, uint8x4_t b) {
return __uqsub8(a, b);
}
// AArch32-LABEL: test_usub8
// AArch32: call i32 @llvm.arm.usub8
uint8x4_t test_usub8(uint8x4_t a, uint8x4_t b) {
return __usub8(a, b);
}
#endif
/* 9.5.8 Sum of 8-bit absolute differences */
#if __ARM_FEATURE_SIMD32
// AArch32-LABEL: test_usad8
// AArch32: call i32 @llvm.arm.usad8
uint32_t test_usad8(uint8x4_t a, uint8x4_t b) {
return __usad8(a, b);
}
// AArch32-LABEL: test_usada8
// AArch32: call i32 @llvm.arm.usada8
uint32_t test_usada8(uint8_t a, uint8_t b, uint8_t c) {
return __usada8(a, b, c);
}
#endif
/* 9.5.9 Parallel 16-bit addition and subtraction */
#if __ARM_FEATURE_SIMD32
// AArch32-LABEL: test_qadd16
// AArch32: call i32 @llvm.arm.qadd16
int16x2_t test_qadd16(int16x2_t a, int16x2_t b) {
return __qadd16(a, b);
}
// AArch32-LABEL: test_qasx
// AArch32: call i32 @llvm.arm.qasx
int16x2_t test_qasx(int16x2_t a, int16x2_t b) {
return __qasx(a, b);
}
// AArch32-LABEL: test_qsax
// AArch32: call i32 @llvm.arm.qsax
int16x2_t test_qsax(int16x2_t a, int16x2_t b) {
return __qsax(a, b);
}
// AArch32-LABEL: test_qsub16
// AArch32: call i32 @llvm.arm.qsub16
int16x2_t test_qsub16(int16x2_t a, int16x2_t b) {
return __qsub16(a, b);
}
// AArch32-LABEL: test_sadd16
// AArch32: call i32 @llvm.arm.sadd16
int16x2_t test_sadd16(int16x2_t a, int16x2_t b) {
return __sadd16(a, b);
}
// AArch32-LABEL: test_sasx
// AArch32: call i32 @llvm.arm.sasx
int16x2_t test_sasx(int16x2_t a, int16x2_t b) {
return __sasx(a, b);
}
// AArch32-LABEL: test_shadd16
// AArch32: call i32 @llvm.arm.shadd16
int16x2_t test_shadd16(int16x2_t a, int16x2_t b) {
return __shadd16(a, b);
}
// AArch32-LABEL: test_shasx
// AArch32: call i32 @llvm.arm.shasx
int16x2_t test_shasx(int16x2_t a, int16x2_t b) {
return __shasx(a, b);
}
// AArch32-LABEL: test_shsax
// AArch32: call i32 @llvm.arm.shsax
int16x2_t test_shsax(int16x2_t a, int16x2_t b) {
return __shsax(a, b);
}
// AArch32-LABEL: test_shsub16
// AArch32: call i32 @llvm.arm.shsub16
int16x2_t test_shsub16(int16x2_t a, int16x2_t b) {
return __shsub16(a, b);
}
// AArch32-LABEL: test_ssax
// AArch32: call i32 @llvm.arm.ssax
int16x2_t test_ssax(int16x2_t a, int16x2_t b) {
return __ssax(a, b);
}
// AArch32-LABEL: test_ssub16
// AArch32: call i32 @llvm.arm.ssub16
int16x2_t test_ssub16(int16x2_t a, int16x2_t b) {
return __ssub16(a, b);
}
// AArch32-LABEL: test_uadd16
// AArch32: call i32 @llvm.arm.uadd16
uint16x2_t test_uadd16(uint16x2_t a, uint16x2_t b) {
return __uadd16(a, b);
}
// AArch32-LABEL: test_uasx
// AArch32: call i32 @llvm.arm.uasx
uint16x2_t test_uasx(uint16x2_t a, uint16x2_t b) {
return __uasx(a, b);
}
// AArch32-LABEL: test_uhadd16
// AArch32: call i32 @llvm.arm.uhadd16
uint16x2_t test_uhadd16(uint16x2_t a, uint16x2_t b) {
return __uhadd16(a, b);
}
// AArch32-LABEL: test_uhasx
// AArch32: call i32 @llvm.arm.uhasx
uint16x2_t test_uhasx(uint16x2_t a, uint16x2_t b) {
return __uhasx(a, b);
}
// AArch32-LABEL: test_uhsax
// AArch32: call i32 @llvm.arm.uhsax
uint16x2_t test_uhsax(uint16x2_t a, uint16x2_t b) {
return __uhsax(a, b);
}
// AArch32-LABEL: test_uhsub16
// AArch32: call i32 @llvm.arm.uhsub16
uint16x2_t test_uhsub16(uint16x2_t a, uint16x2_t b) {
return __uhsub16(a, b);
}
// AArch32-LABEL: test_uqadd16
// AArch32: call i32 @llvm.arm.uqadd16
uint16x2_t test_uqadd16(uint16x2_t a, uint16x2_t b) {
return __uqadd16(a, b);
}
// AArch32-LABEL: test_uqasx
// AArch32: call i32 @llvm.arm.uqasx
uint16x2_t test_uqasx(uint16x2_t a, uint16x2_t b) {
return __uqasx(a, b);
}
// AArch32-LABEL: test_uqsax
// AArch32: call i32 @llvm.arm.uqsax
uint16x2_t test_uqsax(uint16x2_t a, uint16x2_t b) {
return __uqsax(a, b);
}
// AArch32-LABEL: test_uqsub16
// AArch32: call i32 @llvm.arm.uqsub16
uint16x2_t test_uqsub16(uint16x2_t a, uint16x2_t b) {
return __uqsub16(a, b);
}
// AArch32-LABEL: test_usax
// AArch32: call i32 @llvm.arm.usax
uint16x2_t test_usax(uint16x2_t a, uint16x2_t b) {
return __usax(a, b);
}
// AArch32-LABEL: test_usub16
// AArch32: call i32 @llvm.arm.usub16
uint16x2_t test_usub16(uint16x2_t a, uint16x2_t b) {
return __usub16(a, b);
}
#endif
/* 9.5.10 Parallel 16-bit multiplications */
#if __ARM_FEATURE_SIMD32
// AArch32-LABEL: test_smlad
// AArch32: call i32 @llvm.arm.smlad
int32_t test_smlad(int16x2_t a, int16x2_t b, int32_t c) {
return __smlad(a, b, c);
}
// AArch32-LABEL: test_smladx
// AArch32: call i32 @llvm.arm.smladx
int32_t test_smladx(int16x2_t a, int16x2_t b, int32_t c) {
return __smladx(a, b, c);
}
// AArch32-LABEL: test_smlald
// AArch32: call i64 @llvm.arm.smlald
int64_t test_smlald(int16x2_t a, int16x2_t b, int64_t c) {
return __smlald(a, b, c);
}
// AArch32-LABEL: test_smlaldx
// AArch32: call i64 @llvm.arm.smlaldx
int64_t test_smlaldx(int16x2_t a, int16x2_t b, int64_t c) {
return __smlaldx(a, b, c);
}
// AArch32-LABEL: test_smlsd
// AArch32: call i32 @llvm.arm.smlsd
int32_t test_smlsd(int16x2_t a, int16x2_t b, int32_t c) {
return __smlsd(a, b, c);
}
// AArch32-LABEL: test_smlsdx
// AArch32: call i32 @llvm.arm.smlsdx
int32_t test_smlsdx(int16x2_t a, int16x2_t b, int32_t c) {
return __smlsdx(a, b, c);
}
// AArch32-LABEL: test_smlsld
// AArch32: call i64 @llvm.arm.smlsld
int64_t test_smlsld(int16x2_t a, int16x2_t b, int64_t c) {
return __smlsld(a, b, c);
}
// AArch32-LABEL: test_smlsldx
// AArch32: call i64 @llvm.arm.smlsldx
int64_t test_smlsldx(int16x2_t a, int16x2_t b, int64_t c) {
return __smlsldx(a, b, c);
}
// AArch32-LABEL: test_smuad
// AArch32: call i32 @llvm.arm.smuad
int32_t test_smuad(int16x2_t a, int16x2_t b) {
return __smuad(a, b);
}
// AArch32-LABEL: test_smuadx
// AArch32: call i32 @llvm.arm.smuadx
int32_t test_smuadx(int16x2_t a, int16x2_t b) {
return __smuadx(a, b);
}
// AArch32-LABEL: test_smusd
// AArch32: call i32 @llvm.arm.smusd
int32_t test_smusd(int16x2_t a, int16x2_t b) {
return __smusd(a, b);
}
// AArch32-LABEL: test_smusdx
// AArch32: call i32 @llvm.arm.smusdx
int32_t test_smusdx(int16x2_t a, int16x2_t b) {
return __smusdx(a, b);
}
#endif
/* 9.7 CRC32 intrinsics */
// ARM-LABEL: test_crc32b
// AArch32: call i32 @llvm.arm.crc32b

@ -0,0 +1,39 @@
// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +lwp -emit-llvm -o - -Wall -Werror | FileCheck %s
#include <x86intrin.h>
void test_llwpcb(void *ptr) {
// CHECK-LABEL: @test_llwpcb
// CHECK: call void @llvm.x86.llwpcb(i8* %{{.*}})
__llwpcb(ptr);
}
void* test_slwpcb() {
// CHECK-LABEL: @test_slwpcb
// CHECK: call i8* @llvm.x86.slwpcb()
return __slwpcb();
}
unsigned char test_lwpins32(unsigned val2, unsigned val1) {
// CHECK-LABEL: @test_lwpins32
// CHECK: call i8 @llvm.x86.lwpins32(i32
return __lwpins32(val2, val1, 0x01234);
}
unsigned char test_lwpins64(unsigned long long val2, unsigned val1) {
// CHECK-LABEL: @test_lwpins64
// CHECK: call i8 @llvm.x86.lwpins64(i64
return __lwpins64(val2, val1, 0x56789);
}
void test_lwpval32(unsigned val2, unsigned val1) {
// CHECK-LABEL: @test_lwpval32
// CHECK: call void @llvm.x86.lwpval32(i32
__lwpval32(val2, val1, 0x01234);
}
void test_lwpval64(unsigned long long val2, unsigned val1) {
// CHECK-LABEL: @test_lwpval64
// CHECK: call void @llvm.x86.lwpval64(i64
__lwpval64(val2, val1, 0xABCDEF);
}

@ -18,25 +18,25 @@ void invoke(void* that, unsigned methodIndex,
// CHECK: store i32 %2, i32* %7, align 4
// CHECK: store i8* %3, i8** %8, align 4
// CHECK: call void asm sideeffect inteldialect
// CHECK: mov edx,dword ptr $1
// CHECK: test edx,edx
// CHECK: jz {{[^_]*}}__MSASMLABEL_.${:uid}__noparams
// ^ Can't use {{.*}} here because the matching is greedy.
// CHECK: mov eax,edx
// CHECK: shl eax,$$3
// CHECK: sub esp,eax
// CHECK: mov ecx,esp
// CHECK: push dword ptr $0
// CHECK: call dword ptr $2
// CHECK: {{.*}}__MSASMLABEL_.${:uid}__noparams:
// CHECK: mov ecx,dword ptr $3
// CHECK: push ecx
// CHECK: mov edx,[ecx]
// CHECK: mov eax,dword ptr $4
// CHECK: call dword ptr[edx+eax*$$4]
// CHECK: mov esp,ebp
// CHECK: pop ebp
// CHECK: ret
// CHECK-SAME: mov edx,$1
// CHECK-SAME: test edx,edx
// CHECK-SAME: jz {{[^_]*}}__MSASMLABEL_.${:uid}__noparams
// ^ Can't use {{.*}} here because the matching is greedy.
// CHECK-SAME: mov eax,edx
// CHECK-SAME: shl eax,$$3
// CHECK-SAME: sub esp,eax
// CHECK-SAME: mov ecx,esp
// CHECK-SAME: push $0
// CHECK-SAME: call dword ptr $2
// CHECK-SAME: {{.*}}__MSASMLABEL_.${:uid}__noparams:
// CHECK-SAME: mov ecx,$3
// CHECK-SAME: push ecx
// CHECK-SAME: mov edx,[ecx]
// CHECK-SAME: mov eax,$4
// CHECK-SAME: call dword ptr[edx+eax*$$4]
// CHECK-SAME: mov esp,ebp
// CHECK-SAME: pop ebp
// CHECK-SAME: ret
// CHECK: "=*m,*m,*m,*m,*m,~{eax},~{ebp},~{ecx},~{edx},~{flags},~{esp},~{dirflag},~{fpsr},~{flags}"
// CHECK: (i8** %8, i32* %7, void (...)* bitcast (void ()* @invoke_copy_to_stack to void (...)*), i8** %5, i32* %6)
// CHECK: ret void

@ -5,14 +5,18 @@ void t1() {
int var = 10;
__asm mov rax, offset var ; rax = address of myvar
// CHECK: t1
// CHECK: call void asm sideeffect inteldialect "mov rax, $0", "r,~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: mov rax, $0
// CHECK-SAME: "r,~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
void t2() {
int var = 10;
__asm mov [eax], offset var
// CHECK: t2
// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: mov [eax], $0
// CHECK-SAME: "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
struct t3_type { int a, b; };
@ -28,7 +32,11 @@ int t3() {
}
return foo.b;
// CHECK: t3
// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr $0\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}})
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: lea ebx, $0
// CHECK-SAME: mov eax, [ebx].0
// CHECK-SAME: mov [ebx].4, ecx
// CHECK-SAME: "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}})
}
int t4() {
@ -44,5 +52,9 @@ int t4() {
}
return foo.b;
// CHECK: t4
// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr $0\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}})
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: lea ebx, $0
// CHECK-SAME: mov eax, [ebx].0
// CHECK-SAME: mov [ebx].4, ecx
// CHECK-SAME: "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}})
}

@ -1,5 +1,5 @@
// REQUIRES: x86-registered-target
// RUN: %clang_cc1 %s -triple x86_64-pc-windows-msvc -target-cpu knl -fasm-blocks -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s -triple x86_64-pc-windows-msvc -target-cpu skylake-avx512 -fasm-blocks -emit-llvm -o - | FileCheck %s
void t1() {
// CHECK: @t1
@ -19,3 +19,16 @@ void t2() {
vaddpd zmm8 {k1}, zmm27, zmm6
}
}
void ignore_fe_size() {
// CHECK-LABEL: define void @ignore_fe_size()
char c;
// CHECK: vaddps xmm1, xmm2, $1{1to4}
__asm vaddps xmm1, xmm2, [c]{1to4}
// CHECK: vaddps xmm1, xmm2, $2
__asm vaddps xmm1, xmm2, [c]
// CHECK: mov eax, $3
__asm mov eax, [c]
// CHECK: mov $0, rax
__asm mov [c], rax
}

@ -92,7 +92,11 @@ void t9() {
__asm { pop ebx }
}
// CHECK: t9
// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx\0A\09", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: push ebx
// CHECK-SAME: mov ebx, $$0x07
// CHECK-SAME: pop ebx
// CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
}
unsigned t10(void) {
@ -107,7 +111,10 @@ unsigned t10(void) {
// CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4
// CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4
// CHECK: store i32 1, i32* [[I]], align 4
// CHECK: call i32 asm sideeffect inteldialect "mov eax, dword ptr $2\0A\09mov dword ptr $0, eax", "=*m,={eax},*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}})
// CHECK: call i32 asm sideeffect inteldialect
// CHECK-SAME: mov eax, $2
// CHECK-SAME: mov $0, eax
// CHECK-SAME: "=*m,={eax},*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}})
// CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32, i32* [[J]], align 4
// CHECK: ret i32 [[RET]]
}
@ -128,7 +135,12 @@ unsigned t12(void) {
}
return j + m;
// CHECK: t12
// CHECK: call i32 asm sideeffect inteldialect "mov eax, dword ptr $3\0A\09mov dword ptr $0, eax\0A\09mov eax, dword ptr $4\0A\09mov dword ptr $1, eax", "=*m,=*m,={eax},*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
// CHECK: call i32 asm sideeffect inteldialect
// CHECK-SAME: mov eax, $3
// CHECK-SAME: mov $0, eax
// CHECK-SAME: mov eax, $4
// CHECK-SAME: mov $1, eax
// CHECK-SAME: "=*m,=*m,={eax},*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
}
void t13() {
@ -136,8 +148,23 @@ void t13() {
short j = 2;
__asm movzx eax, i
__asm movzx eax, j
// CHECK: t13
// CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0\0A\09movzx eax, word ptr $1", "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}i, i16* %{{.*}}j)
// CHECK-LABEL: define void @t13()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: movzx eax, byte ptr $0
// CHECK-SAME: movzx eax, word ptr $1
// CHECK-SAME: "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}i, i16* %{{.*}}j)
}
void t13_brac() {
char i = 1;
short j = 2;
__asm movzx eax, [i]
__asm movzx eax, [j]
// CHECK-LABEL: define void @t13_brac()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: movzx eax, byte ptr $0
// CHECK-SAME: movzx eax, word ptr $1
// CHECK-SAME: "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}i, i16* %{{.*}}j)
}
void t14() {
@ -150,7 +177,7 @@ void t14() {
.endif
}
// CHECK: t14
// CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, dword ptr $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
int gvar = 10;
@ -158,7 +185,7 @@ void t15() {
// CHECK: t15
int lvar = 10;
__asm mov eax, lvar ; eax = 10
// CHECK: mov eax, dword ptr $0
// CHECK: mov eax, $0
__asm mov eax, offset lvar ; eax = address of lvar
// CHECK: mov eax, $1
__asm mov eax, offset gvar ; eax = address of gvar
@ -236,7 +263,11 @@ void t21() {
__asm pop ebx
}
// CHECK: t21
// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$07H\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: push ebx
// CHECK-SAME: mov ebx, $$07H
// CHECK-SAME: pop ebx
// CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
}
extern void t22_helper(int x);
@ -252,9 +283,15 @@ void t22() {
__asm pop ebx
}
// CHECK: t22
// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, esp", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: push ebx
// CHECK-SAME: mov ebx, esp
// CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void @t22_helper
// CHECK: call void asm sideeffect inteldialect "mov esp, ebx\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: mov esp, ebx
// CHECK-SAME: pop ebx
// CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
}
void t23() {
@ -342,9 +379,9 @@ int *t30()
{
int *res;
__asm lea edi, results
// CHECK: lea edi, dword ptr $2
// CHECK: lea edi, $2
__asm mov res, edi
// CHECK: mov dword ptr $0, edi
// CHECK: mov $0, edi
return res;
// CHECK: "=*m,={eax},*m,~{edi},~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}}, [2 x i32]* @{{.*}})
}
@ -362,7 +399,7 @@ void t32() {
// CHECK: t32
int i;
__asm mov eax, i
// CHECK: mov eax, dword ptr $0
// CHECK: mov eax, $0
__asm mov eax, dword ptr i
// CHECK: mov eax, dword ptr $1
__asm mov ax, word ptr i
@ -376,7 +413,7 @@ void t33() {
// CHECK: t33
int i;
__asm mov eax, [i]
// CHECK: mov eax, dword ptr $0
// CHECK: mov eax, $0
__asm mov eax, dword ptr [i]
// CHECK: mov eax, dword ptr $1
__asm mov ax, word ptr [i]
@ -409,31 +446,31 @@ void t36() {
int arr[4];
// Work around PR20368: These should be single line blocks
__asm { mov eax, 4[arr] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4[arr + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 8[arr + 4 + 32*2 - 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$72$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$72$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 12[4 + arr] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$16$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$16$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4[4 + arr + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4[64 + arr + (2*32)] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$132$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$132$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4[64 + arr - 2*32] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, [arr + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, [arr + 4 + 32*2 - 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$64$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$64$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, [4 + arr] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, [4 + arr + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, [64 + arr + (2*32)] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$128$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$128$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, [64 + arr - 2*32] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
}
void t37() {
@ -464,21 +501,21 @@ void t38() {
int arr[4];
// Work around PR20368: These should be single line blocks
__asm { mov eax, 4+4[arr] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, (4+4)[arr + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 8*2[arr + 4 + 32*2 - 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$80$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$80$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 12+20[4 + arr] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$36$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$36$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4*16+4[4 + arr + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$76$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$76$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4*4[64 + arr + (2*32)] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$144$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$144$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 4*(4-2)[64 + arr - 2*32] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
__asm { mov eax, 32*(4-2)[arr - 2*32] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$0$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$0$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
}
void cpuid() {
@ -554,7 +591,7 @@ void t42() {
// CHECK-LABEL: define void @t42
int flags;
__asm mov flags, eax
// CHECK: mov dword ptr $0, eax
// CHECK: mov $0, eax
// CHECK: "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %flags)
}
@ -563,31 +600,31 @@ void t43() {
C strct;
// Work around PR20368: These should be single line blocks
__asm { mov eax, 4[strct.c1] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, 4[strct.c3 + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, 8[strct.c2.a + 4 + 32*2 - 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$72$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$72$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, 12[4 + strct.c2.b] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$16$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$16$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, 4[4 + strct.c4.b2.b + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, 4[64 + strct.c1 + (2*32)] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$132$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$132$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, 4[64 + strct.c2.a - 2*32] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, [strct.c4.b1 + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, [strct.c4.b2.a + 4 + 32*2 - 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$64$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$64$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, [4 + strct.c1] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, [4 + strct.c2.b + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, [64 + strct.c3 + (2*32)] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$128$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $$128$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
__asm { mov eax, [64 + strct.c4.b2.b - 2*32] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
void call_clobber() {
@ -662,7 +699,7 @@ void mxcsr() {
__asm fxrstor buf
}
// CHECK-LABEL: define void @mxcsr
// CHECK: call void asm sideeffect inteldialect "fxrstor byte ptr $0", "=*m,~{dirflag},~{fpsr},~{flags}"
// CHECK: call void asm sideeffect inteldialect "fxrstor $0", "=*m,~{dirflag},~{fpsr},~{flags}"
typedef union _LARGE_INTEGER {
struct {
@ -680,7 +717,7 @@ int test_indirect_field(LARGE_INTEGER LargeInteger) {
__asm mov eax, LargeInteger.LowPart
}
// CHECK-LABEL: define i32 @test_indirect_field(
// CHECK: call i32 asm sideeffect inteldialect "mov eax, dword ptr $1",
// CHECK: call i32 asm sideeffect inteldialect "mov eax, $1",
// MS ASM containing labels must not be duplicated (PR23715).
// CHECK: attributes [[ATTR1]] = {

@ -14,15 +14,21 @@ struct Foo {
};
void t1() {
// CHECK-LABEL: define void @_Z2t1v()
Foo::ptr = (int *)0xDEADBEEF;
Foo::Bar::ptr = (int *)0xDEADBEEF;
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: mov eax, $0
// CHECK-SAME: mov eax, $1
// CHECK-SAME: mov eax, $2
// CHECK-SAME: mov eax, dword ptr $3
// CHECK-SAME: mov eax, dword ptr $4
// CHECK-SAME: "*m,*m,*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE)
__asm mov eax, Foo ::ptr
__asm mov eax, Foo :: Bar :: ptr
__asm mov eax, [Foo:: ptr]
__asm mov eax, dword ptr [Foo :: ptr]
__asm mov eax, dword ptr [Foo :: ptr]
// CHECK: @_Z2t1v
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0\0A\09mov eax, dword ptr $1\0A\09mov eax, dword ptr $2\0A\09mov eax, dword ptr $3\0A\09mov eax, dword ptr $4", "*m,*m,*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE)
}
int gvar = 10;
@ -30,8 +36,11 @@ void t2() {
int lvar = 10;
__asm mov eax, offset Foo::ptr
__asm mov eax, offset Foo::Bar::ptr
// CHECK: t2
// CHECK: call void asm sideeffect inteldialect "mov eax, $0\0A\09mov eax, $1", "r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE)
// CHECK-LABEL: define void @_Z2t2v()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: mov eax, $0
// CHECK-SAME: mov eax, $1
// CHECK-SAME: "r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE)
}
// CHECK-LABEL: define void @_Z2t3v()
@ -50,7 +59,20 @@ void t3() {
__asm mov eax, SIZE Foo::Bar::ptr
__asm mov eax, SIZE Foo::arr
__asm mov eax, SIZE Foo::Bar::arr
// CHECK: call void asm sideeffect inteldialect "mov eax, $$1\0A\09mov eax, $$1\0A\09mov eax, $$4\0A\09mov eax, $$2\0A\09mov eax, $$4\0A\09mov eax, $$4\0A\09mov eax, $$4\0A\09mov eax, $$1\0A\09mov eax, $$4\0A\09mov eax, $$4\0A\09mov eax, $$16\0A\09mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: mov eax, $$1
// CHECK-SAME: mov eax, $$1
// CHECK-SAME: mov eax, $$4
// CHECK-SAME: mov eax, $$2
// CHECK-SAME: mov eax, $$4
// CHECK-SAME: mov eax, $$4
// CHECK-SAME: mov eax, $$4
// CHECK-SAME: mov eax, $$1
// CHECK-SAME: mov eax, $$4
// CHECK-SAME: mov eax, $$4
// CHECK-SAME: mov eax, $$16
// CHECK-SAME: mov eax, $$2
// CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
@ -67,7 +89,10 @@ void T4::test() {
// CHECK: [[X:%.*]] = getelementptr inbounds [[T4]], [[T4]]* [[THIS]], i32 0, i32 0
__asm mov eax, x;
__asm mov y, eax;
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $1\0A\09mov dword ptr $0, eax", "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @_ZN2T41yE, i32* {{.*}})
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: mov eax, $1
// CHECK-SAME: mov $0, eax
// CHECK-SAME: "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @_ZN2T41yE, i32* {{.*}})
}
template <class T> struct T5 {
@ -82,7 +107,11 @@ void test5() {
__asm push y
__asm call T5<int>::create<float>
__asm mov x, eax
// CHECK: call void asm sideeffect inteldialect "push dword ptr $0\0A\09call dword ptr $2\0A\09mov dword ptr $1, eax", "=*m,=*m,*m,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* %y, i32* %x, i32 (float)* @_ZN2T5IiE6createIfEEiT_)
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: push $0
// CHECK-SAME: call dword ptr $2
// CHECK-SAME: mov $1, eax
// CHECK-SAME: "=*m,=*m,*m,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* %y, i32* %x, i32 (float)* @_ZN2T5IiE6createIfEEiT_)
}
// Just verify this doesn't emit an error.
@ -100,7 +129,9 @@ void t7_struct() {
};
__asm mov eax, [eax].A.b
// CHECK-LABEL: define void @_Z9t7_structv
// CHECK: call void asm sideeffect inteldialect "mov eax, [eax].4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: mov eax, [eax].4
// CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t7_typedef() {
@ -110,7 +141,9 @@ void t7_typedef() {
} A;
__asm mov eax, [eax].A.b
// CHECK-LABEL: define void @_Z10t7_typedefv
// CHECK: call void asm sideeffect inteldialect "mov eax, [eax].4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: mov eax, [eax].4
// CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t7_using() {
@ -120,20 +153,28 @@ void t7_using() {
};
__asm mov eax, [eax].A.b
// CHECK-LABEL: define void @_Z8t7_usingv
// CHECK: call void asm sideeffect inteldialect "mov eax, [eax].4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: mov eax, [eax].4
// CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t8() {
__asm some_label:
// CHECK-LABEL: define void @_Z2t8v()
// CHECK: call void asm sideeffect inteldialect "L__MSASMLABEL_.${:uid}__some_label:", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: L__MSASMLABEL_.${:uid}__some_label:
// CHECK-SAME: "~{dirflag},~{fpsr},~{flags}"()
struct A {
static void g() {
__asm jmp some_label ; This should jump forwards
__asm some_label:
__asm nop
// CHECK-LABEL: define internal void @_ZZ2t8vEN1A1gEv()
// CHECK: call void asm sideeffect inteldialect "jmp L__MSASMLABEL_.${:uid}__some_label\0A\09L__MSASMLABEL_.${:uid}__some_label:\0A\09nop", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: jmp L__MSASMLABEL_.${:uid}__some_label
// CHECK-SAME: L__MSASMLABEL_.${:uid}__some_label:
// CHECK-SAME: nop
// CHECK-SAME: "~{dirflag},~{fpsr},~{flags}"()
}
};
A::g();

@ -35,8 +35,12 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
declare void @f2()
declare i8* @f3()
define void @f1() {
call void @f2()
; Make sure that the backend can handle undefined references.
; Do an indirect call so that the undefined ref shows up in the combined index.
call void bitcast (i8*()* @f3 to void()*)()
ret void
}

@ -17,14 +17,14 @@ A a_global;
extern "C" int test_param_field(A p) {
// CHECK: define i32 @test_param_field(%struct.A* byval align 4 %p)
// CHECK: getelementptr inbounds %struct.A, %struct.A* %p, i32 0, i32 0
// CHECK: call i32 asm sideeffect inteldialect "mov eax, dword ptr $1"
// CHECK: call i32 asm sideeffect inteldialect "mov eax, $1"
// CHECK: ret i32
__asm mov eax, p.a1
}
extern "C" int test_namespace_global() {
// CHECK: define i32 @test_namespace_global()
// CHECK: call i32 asm sideeffect inteldialect "mov eax, dword ptr $1", "{{.*}}"(i32* getelementptr inbounds (%struct.A, %struct.A* @_ZN4asdf8a_globalE, i32 0, i32 2, i32 1))
// CHECK: call i32 asm sideeffect inteldialect "mov eax, $1", "{{.*}}"(i32* getelementptr inbounds (%struct.A, %struct.A* @_ZN4asdf8a_globalE, i32 0, i32 2, i32 1))
// CHECK: ret i32
__asm mov eax, asdf::a_global.a3.b2
}

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -emit-llvm %s -o %t-64.s
// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin -fblocks -fobjc-arc -fobjc-runtime-has-weak -emit-llvm %s -o - | FileCheck -check-prefix CHECK-LP64 %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -emit-llvm %s -o - | FileCheck -check-prefix CHECK-LP64-OPT %s
// rdar://9503326
// rdar://9606600
@ -29,6 +29,11 @@ void test0(NSArray *array) {
// CHECK-LP64-NEXT: [[BUFFER:%.*]] = alloca [16 x i8*], align 8
// CHECK-LP64-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
// CHECK-LP64-OPT-LABEL: define void @test0
// CHECK-LP64-OPT: [[STATE:%.*]] = alloca [[STATE_T:%.*]], align 8
// CHECK-LP64-OPT-NEXT: [[BUFFER:%.*]] = alloca [16 x i8*], align 8
// CHECK-LP64-OPT-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], align 8
// Initialize 'array'.
// CHECK-LP64-NEXT: store [[ARRAY_T]]* null, [[ARRAY_T]]** [[ARRAY]]
// CHECK-LP64-NEXT: [[ZERO:%.*]] = bitcast [[ARRAY_T]]** [[ARRAY]] to i8**
@ -66,8 +71,12 @@ void test0(NSArray *array) {
// CHECK-LP64-NEXT: store i8* [[T1]], i8** [[T0]]
// CHECK-LP64-NEXT: [[BLOCK1:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]]
// CHECK-LP64-NEXT: call void @use_block(void ()* [[BLOCK1]])
// CHECK-LP64-NEXT: [[CAPTURE:%.*]] = load i8*, i8** [[D0]]
// CHECK-LP64: call void (...) @clang.arc.use(i8* [[CAPTURE]])
// CHECK-LP64-NEXT: call void @objc_storeStrong(i8** [[D0]], i8* null)
// CHECK-LP64-NOT: call void (...) @clang.arc.use(i8* [[CAPTURE]])
// CHECK-LP64-OPT: [[D0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i64 0, i32 5
// CHECK-LP64-OPT: [[CAPTURE:%.*]] = load i8*, i8** [[D0]]
// CHECK-LP64-OPT: call void (...) @clang.arc.use(i8* [[CAPTURE]])
// CHECK-LP64: [[T0:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
// CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[ARRAY_T]]* [[SAVED_ARRAY]] to i8*
@ -200,15 +209,24 @@ NSArray *array4;
// CHECK-LP64: [[T0:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, [[TY]]* }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, [[TY]]* }>* [[BLOCK]], i32 0, i32 5
// CHECK-LP64: [[BC:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, [[TY]]* }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, [[TY]]* }>* [[BLOCK]], i32 0, i32 5
// CHECK-LP64: [[T1:%.*]] = load [[TY]]*, [[TY]]** [[SELF_ADDR]]
// CHECK-LP64: store [[TY]]* [[T1]], [[TY]]** [[BC]]
// CHECK-LP64: store [[TY]]* [[T1]], [[TY]]** [[BC]], align 8
// CHECK-LP64: [[T5:%.*]] = load [[TY]]*, [[TY]]** [[T0]]
// CHECK-LP64: call void (...) @clang.arc.use([[TY]]* [[T5]])
// CHECK-LP64-OPT-LABEL: define internal void @"\01-[I1 foo2]"(
// CHECK-LP64-OPT: [[TY:%.*]]* %self
// CHECK-LP64-OPT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
// CHECK-LP64-OPT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i64 0, i32 5
// CHECK-LP64: [[T5:%.*]] = bitcast [[TY]]** [[T0]] to i8**
// CHECK-LP64: call void @objc_storeStrong(i8** [[T5]], i8* null)
// CHECK-LP64-NOT: call void (...) @clang.arc.use([[TY]]* [[T5]])
// CHECK-LP64: switch i32 {{%.*}}, label %[[UNREACHABLE:.*]] [
// CHECK-LP64-NEXT: i32 0, label %[[CLEANUP_CONT:.*]]
// CHECK-LP64-NEXT: i32 2, label %[[FORCOLL_END:.*]]
// CHECK-LP64-NEXT: ]
// CHECK-LP64-OPT: [[T5:%.*]] = load [[TY]]*, [[TY]]** [[T0]]
// CHECK-LP64-OPT: call void (...) @clang.arc.use([[TY]]* [[T5]])
// CHECK-LP64: {{^|:}}[[CLEANUP_CONT]]
// CHECK-LP64-NEXT: br label %[[FORCOLL_END]]

@ -8,7 +8,11 @@ kernel __attribute__((vec_type_hint(int))) __attribute__((reqd_work_group_size(
kernel __attribute__((vec_type_hint(uint4))) __attribute__((work_group_size_hint(8,16,32))) void kernel2(int a) {}
// CHECK: define void @kernel2(i32 {{[^%]*}}%a) {{[^{]+}} !vec_type_hint ![[MD3:[0-9]+]] !work_group_size_hint ![[MD4:[0-9]+]]
kernel __attribute__((intel_reqd_sub_group_size(8))) void kernel3(int a) {}
// CHECK: define void @kernel3(i32 {{[^%]*}}%a) {{[^{]+}} !intel_reqd_sub_group_size ![[MD5:[0-9]+]]
// CHECK: [[MD1]] = !{i32 undef, i32 1}
// CHECK: [[MD2]] = !{i32 1, i32 2, i32 4}
// CHECK: [[MD3]] = !{<4 x i32> undef, i32 0}
// CHECK: [[MD4]] = !{i32 8, i32 16, i32 32}
// CHECK: [[MD5]] = !{i32 8}

@ -172,6 +172,20 @@
// CHECK-ARMV7THUMB-NOT: "-L{{.*}}/lib/gcc/arm-linux-androideabi/4.9/../{{[^ ]*}}/lib/armv7-a"
// CHECK-ARMV7THUMB-NOT: "-L{{.*}}/lib/gcc/arm-linux-androideabi/4.9/../{{[^ ]*}}/lib"
// CHECK-ARMV7THUMB: "-L{{.*}}/sysroot/usr/lib"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: -target arm-linux-androideabi -stdlib=libstdc++ \
// RUN: -march=armv7-a -mthumb \
// RUN: -B%S/Inputs/basic_android_ndk_tree \
// RUN: --sysroot=%S/Inputs/basic_android_ndk_tree/sysroot \
// RUN: -print-multi-lib \
// RUN: | FileCheck --check-prefix=CHECK-ARM-MULTILIBS %s
// CHECK-ARM-MULTILIBS: thumb;@mthumb
// CHECK-ARM-MULTILIBS-NEXT: armv7-a;@march=armv7-a
// CHECK-ARM-MULTILIBS-NEXT: armv7-a/thumb;@march=armv7-a@mthumb
// CHECK-ARM-MULTILIBS-NEXT: .;
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: -target armv7a-none-linux-androideabi -stdlib=libstdc++ \

@ -29,9 +29,13 @@
// RUN: FileCheck --check-prefix=CHECK-VERSION-OSX10 %s
// RUN: %clang -target x86_64-apple-macosx -mmacosx-version-min=10.10 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-OSX10 %s
// RUN: %clang -target x86_64-apple-macosx -mmacos-version-min=10.10 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-OSX10 %s
// CHECK-VERSION-OSX10: "x86_64-apple-macosx10.10.0"
// RUN: %clang -target x86_64-apple-macosx -mmacosx-version-min= -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-MISSING %s
// RUN: %clang -target x86_64-apple-macosx -mmacos-version-min= -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-MISSING %s
// CHECK-VERSION-MISSING: invalid version number
// RUN: %clang -target armv7k-apple-darwin -mwatchos-version-min=2.0 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-WATCHOS20 %s

@ -80,6 +80,10 @@
// CHECK-EXTEND-LEGACY: -fsanitize-coverage-type=1
// CHECK-EXTEND-LEGACY: -fsanitize-coverage-trace-cmp
// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=no-prune,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_NOPRUNE
// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=no-prune,func,trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_NOPRUNE
// CHECK_NOPRUNE: -fsanitize-coverage-no-prune
// RUN: %clang_cl --target=i386-pc-win32 -fsanitize=address -fsanitize-coverage=func,trace-pc-guard -c -### -- %s 2>&1 | FileCheck %s -check-prefix=CLANG-CL-COVERAGE
// CLANG-CL-COVERAGE-NOT: error:
// CLANG-CL-COVERAGE-NOT: warning:

@ -1,12 +1,17 @@
// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -stdlib=libstdc++ -rtlib=platform -o /dev/null %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-BASIC
// RUN: %clang -### --driver-mode=g++ -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -stdlib=libstdc++ -rtlib=platform -o /dev/null %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-BASIC-LIBSTDCXX
// CHECK-BASIC: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "-L{{.*}}/Inputs/Windows/ARM/8.1/usr/lib" "-L{{.*}}/Inputs/Windows/ARM/8.1/usr/lib/gcc" "{{.*}}.o" "-lmsvcrt" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
// CHECK-BASIC-LIBSTDCXX: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "-L{{.*}}/Inputs/Windows/ARM/8.1/usr/lib" "-L{{.*}}/Inputs/Windows/ARM/8.1/usr/lib/gcc" "{{.*}}.o" "-lstdc++" "-lmingw32" "-lmingwex" "-lgcc" "-lmoldname" "-lmingw32" "-lmsvcrt" "-lgcc_s" "-lgcc"
// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -stdlib=libstdc++ -rtlib=compiler-rt -o /dev/null %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-BASIC-LIBCXX
// CHECK-BASIC-LIBCXX: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{[^"]*}}.o" "-lmsvcrt"
// RUN: %clang -### -target armv7-windows-itanium --sysroot %s/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -rtlib=compiler-rt -stdlib=libstdc++ -o /dev/null %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-RTLIB
// CHECK-RTLIB: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "-L{{.*}}/Inputs/Windows/ARM/8.1/usr/lib" "-L{{.*}}/Inputs/Windows/ARM/8.1/usr/lib/gcc" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
// CHECK-RTLIB: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -rtlib=compiler-rt -stdlib=libc++ -o /dev/null %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-C-LIBCXX

@ -0,0 +1,10 @@
// RUN: %clang_cc1 -fsyntax-only -Wunguarded-availability -fdiagnostics-parseable-fixits -triple x86_64-apple-darwin9 %s 2>&1 | FileCheck %s
__attribute__((availability(macos, introduced=10.12)))
int function(void);
void use() {
function();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (__builtin_available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n } else {\n // Fallback on earlier versions\n }"
}

@ -0,0 +1,111 @@
// RUN: %clang_cc1 -fsyntax-only -Wunguarded-availability -fdiagnostics-parseable-fixits -triple x86_64-apple-darwin9 %s 2>&1 | FileCheck %s
__attribute__((availability(macos, introduced=10.12)))
int function(void);
void anotherFunction(int function);
int use() {
function();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n } else {\n // Fallback on earlier versions\n }"
int y = function(), x = 0;
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:29-[[@LINE-2]]:29}:"\n } else {\n // Fallback on earlier versions\n }"
x += function();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:19-[[@LINE-2]]:19}:"\n } else {\n // Fallback on earlier versions\n }"
if (1) {
x = function();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:20-[[@LINE-2]]:20}:"\n } else {\n // Fallback on earlier versions\n }"
}
anotherFunction(function());
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:31-[[@LINE-2]]:31}:"\n } else {\n // Fallback on earlier versions\n }"
if (function()) {
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE+1]]:4-[[@LINE+1]]:4}:"\n } else {\n // Fallback on earlier versions\n }"
}
while (function())
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE+1]]:6-[[@LINE+1]]:6}:"\n } else {\n // Fallback on earlier versions\n }"
;
do
function();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n } else {\n // Fallback on earlier versions\n }"
while (1);
for (int i = 0; i < 10; ++i)
function();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n } else {\n // Fallback on earlier versions\n }"
switch (x) {
case 0:
function();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n } else {\n // Fallback on earlier versions\n }"
case 2:
anotherFunction(1);
function();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n } else {\n // Fallback on earlier versions\n }"
break;
default:
function();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n } else {\n // Fallback on earlier versions\n }"
break;
}
return function();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:21-[[@LINE-2]]:21}:"\n } else {\n // Fallback on earlier versions\n }"
}
#define MYFUNCTION function
#define MACRO_ARGUMENT(X) X
#define MACRO_ARGUMENT_SEMI(X) X;
#define MACRO_ARGUMENT_2(X) if (1) X;
#define INNER_MACRO if (1) MACRO_ARGUMENT(function()); else ;
void useInMacros() {
MYFUNCTION();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n } else {\n // Fallback on earlier versions\n }"
MACRO_ARGUMENT_SEMI(function())
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:34-[[@LINE-2]]:34}:"\n } else {\n // Fallback on earlier versions\n }"
MACRO_ARGUMENT(function());
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:30-[[@LINE-2]]:30}:"\n } else {\n // Fallback on earlier versions\n }"
MACRO_ARGUMENT_2(function());
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:32-[[@LINE-2]]:32}:"\n } else {\n // Fallback on earlier versions\n }"
INNER_MACRO
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n } else {\n // Fallback on earlier versions\n }"
}
void wrapDeclStmtUses() {
int x = 0, y = function();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE+13]]:22-[[@LINE+13]]:22}:"\n } else {\n // Fallback on earlier versions\n }"
{
int z = function();
if (z) {
}
// CHECK: fix-it:{{.*}}:{[[@LINE-4]]:5-[[@LINE-4]]:5}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:6-[[@LINE-2]]:6}:"\n } else {\n // Fallback on earlier versions\n }"
}
if (y)
int z = function();
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:24-[[@LINE-2]]:24}:"\n } else {\n // Fallback on earlier versions\n }"
anotherFunction(y);
anotherFunction(x);
}

@ -139,13 +139,13 @@ class PseudoOverridesInSpecializations {
template<>
class PseudoOverridesInSpecializations<double, int> {
void function() { }
// CHECK: [[@LINE-1]]:8 | instance-method/C++ | function | c:@S@PseudoOverridesInSpecializations>#d#I@F@function# | __ZN32PseudoOverridesInSpecializationsIdiE8functionEv | Def,RelChild,RelOver,RelSpecialization | rel: 2
// CHECK: [[@LINE-1]]:8 | instance-method/C++ | function | c:@S@PseudoOverridesInSpecializations>#d#I@F@function# | __ZN32PseudoOverridesInSpecializationsIdiE8functionEv | Def,RelChild,RelSpecialization | rel: 2
// CHECK-NEXT: RelChild
// CHECK-NEXT: RelOver,RelSpecialization | function | c:@ST>2#T#T@PseudoOverridesInSpecializations@F@function#
// CHECK-NEXT: RelSpecialization | function | c:@ST>2#T#T@PseudoOverridesInSpecializations@F@function#
void staticFunction() { }
// CHECK: [[@LINE-1]]:8 | instance-method/C++ | staticFunction | c:@S@PseudoOverridesInSpecializations>#d#I@F@staticFunction# | __ZN32PseudoOverridesInSpecializationsIdiE14staticFunctionEv | Def,RelChild | rel: 1
// CHECK-NOT: RelOver
// CHECK-NOT: RelSpecialization
int notOverridingField = 0;
@ -153,57 +153,56 @@ class PseudoOverridesInSpecializations<double, int> {
int checLabelBreak = 0;
int field = 0;
// CHECK: [[@LINE-1]]:7 | field/C++ | field | c:@S@PseudoOverridesInSpecializations>#d#I@FI@field | <no-cgname> | Def,RelChild,RelOver,RelSpecialization | rel: 2
// CHECK: [[@LINE-1]]:7 | field/C++ | field | c:@S@PseudoOverridesInSpecializations>#d#I@FI@field | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
// CHECK-NEXT: RelChild
// CHECK-NEXT: RelOver,RelSpecialization | field | c:@ST>2#T#T@PseudoOverridesInSpecializations@FI@field
// CHECK-NEXT: RelSpecialization | field | c:@ST>2#T#T@PseudoOverridesInSpecializations@FI@field
static double variable;
// CHECK: [[@LINE-1]]:17 | static-property/C++ | variable | c:@S@PseudoOverridesInSpecializations>#d#I@variable | __ZN32PseudoOverridesInSpecializationsIdiE8variableE | Decl,RelChild,RelOver,RelSpecialization | rel: 2
// CHECK: [[@LINE-1]]:17 | static-property/C++ | variable | c:@S@PseudoOverridesInSpecializations>#d#I@variable | __ZN32PseudoOverridesInSpecializationsIdiE8variableE | Decl,RelChild,RelSpecialization | rel: 2
// CHECK-NEXT: RelChild
// CHECK-NEXT: RelOver,RelSpecialization | variable | c:@ST>2#T#T@PseudoOverridesInSpecializations@variable
// CHECK-NEXT: RelSpecialization | variable | c:@ST>2#T#T@PseudoOverridesInSpecializations@variable
typedef double TypeDef;
// CHECK: [[@LINE-1]]:18 | type-alias/C | TypeDef | c:index-source.cpp@S@PseudoOverridesInSpecializations>#d#I@T@TypeDef | <no-cgname> | Def,RelChild,RelOver,RelSpecialization | rel: 2
// CHECK: [[@LINE-1]]:18 | type-alias/C | TypeDef | c:index-source.cpp@S@PseudoOverridesInSpecializations>#d#I@T@TypeDef | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
// CHECK-NEXT: RelChild
// CHECK-NEXT: RelOver,RelSpecialization | TypeDef | c:index-source.cpp@ST>2#T#T@PseudoOverridesInSpecializations@T@TypeDef
// CHECK-NEXT: RelSpecialization | TypeDef | c:index-source.cpp@ST>2#T#T@PseudoOverridesInSpecializations@T@TypeDef
using TypeAlias = int;
// CHECK: [[@LINE-1]]:9 | type-alias/C++ | TypeAlias | c:@S@PseudoOverridesInSpecializations>#d#I@TypeAlias | <no-cgname> | Def,RelChild,RelOver,RelSpecialization | rel: 2
// CHECK: [[@LINE-1]]:9 | type-alias/C++ | TypeAlias | c:@S@PseudoOverridesInSpecializations>#d#I@TypeAlias | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
// CHECK-NEXT: RelChild
// CHECK-NEXT: RelOver,RelSpecialization | TypeAlias | c:@ST>2#T#T@PseudoOverridesInSpecializations@TypeAlias
// CHECK-NEXT: RelSpecialization | TypeAlias | c:@ST>2#T#T@PseudoOverridesInSpecializations@TypeAlias
enum anEnum { };
// CHECK: [[@LINE-1]]:8 | enum/C | anEnum | c:@S@PseudoOverridesInSpecializations>#d#I@E@anEnum | <no-cgname> | Def,RelChild,RelOver,RelSpecialization | rel: 2
// CHECK: [[@LINE-1]]:8 | enum/C | anEnum | c:@S@PseudoOverridesInSpecializations>#d#I@E@anEnum | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
// CHECK-NEXT: RelChild
// CHECK-NEXT: RelOver,RelSpecialization | anEnum | c:@ST>2#T#T@PseudoOverridesInSpecializations@E@anEnum
// CHECK-NEXT: RelSpecialization | anEnum | c:@ST>2#T#T@PseudoOverridesInSpecializations@E@anEnum
class Struct { };
// CHECK: [[@LINE-1]]:9 | class/C++ | Struct | c:@S@PseudoOverridesInSpecializations>#d#I@S@Struct | <no-cgname> | Def,RelChild,RelOver,RelSpecialization | rel: 2
// CHECK: [[@LINE-1]]:9 | class/C++ | Struct | c:@S@PseudoOverridesInSpecializations>#d#I@S@Struct | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
// CHECK-NEXT: RelChild
// CHECK-NEXT: RelOver,RelSpecialization | Struct | c:@ST>2#T#T@PseudoOverridesInSpecializations@S@Struct
// CHECK-NEXT: RelSpecialization | Struct | c:@ST>2#T#T@PseudoOverridesInSpecializations@S@Struct
union Union { };
// CHECK: [[@LINE-1]]:9 | union/C | Union | c:@S@PseudoOverridesInSpecializations>#d#I@U@Union | <no-cgname> | Def,RelChild,RelOver,RelSpecialization | rel: 2
// CHECK: [[@LINE-1]]:9 | union/C | Union | c:@S@PseudoOverridesInSpecializations>#d#I@U@Union | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
// CHECK-NEXT: RelChild
// CHECK-NEXT: RelOver,RelSpecialization | Union | c:@ST>2#T#T@PseudoOverridesInSpecializations@U@Union
// CHECK-NEXT: RelSpecialization | Union | c:@ST>2#T#T@PseudoOverridesInSpecializations@U@Union
struct TypealiasOrRecord { };
// CHECK: [[@LINE-1]]:10 | struct/C | TypealiasOrRecord | c:@S@PseudoOverridesInSpecializations>#d#I@S@TypealiasOrRecord | <no-cgname> | Def,RelChild,RelOver,RelSpecialization | rel: 2
// CHECK: [[@LINE-1]]:10 | struct/C | TypealiasOrRecord | c:@S@PseudoOverridesInSpecializations>#d#I@S@TypealiasOrRecord | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
// CHECK-NEXT: RelChild
// CHECK-NEXT: RelOver,RelSpecialization | TypealiasOrRecord | c:@ST>2#T#T@PseudoOverridesInSpecializations@TypealiasOrRecord
// CHECK-NEXT: RelSpecialization | TypealiasOrRecord | c:@ST>2#T#T@PseudoOverridesInSpecializations@TypealiasOrRecord
template<typename U> struct InnerTemplate { };
// CHECK: [[@LINE-1]]:31 | struct(Gen)/C++ | InnerTemplate | c:@S@PseudoOverridesInSpecializations>#d#I@ST>1#T@InnerTemplate | <no-cgname> | Def,RelChild,RelOver,RelSpecialization | rel: 2
// CHECK: [[@LINE-1]]:31 | struct(Gen)/C++ | InnerTemplate | c:@S@PseudoOverridesInSpecializations>#d#I@ST>1#T@InnerTemplate | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
// CHECK-NEXT: RelChild
// CHECK-NEXT: RelOver,RelSpecialization | InnerTemplate | c:@ST>2#T#T@PseudoOverridesInSpecializations@ST>1#T@InnerTemplate
// CHECK-NEXT: RelSpecialization | InnerTemplate | c:@ST>2#T#T@PseudoOverridesInSpecializations@ST>1#T@InnerTemplate
template<typename U> struct InnerTemplate <U*> { };
// CHECK-NOT: RelOver
};
template<typename S>
class PseudoOverridesInSpecializations<float, S> {
typedef float TypealiasOrRecord;
// CHECK: [[@LINE-1]]:17 | type-alias/C | TypealiasOrRecord | c:index-source.cpp@SP>1#T@PseudoOverridesInSpecializations>#f#t0.0@T@TypealiasOrRecord | <no-cgname> | Def,RelChild,RelOver,RelSpecialization | rel: 2
// CHECK: [[@LINE-1]]:17 | type-alias/C | TypealiasOrRecord | c:index-source.cpp@SP>1#T@PseudoOverridesInSpecializations>#f#t0.0@T@TypealiasOrRecord | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
// CHECK-NEXT: RelChild
// CHECK-NEXT: RelOver,RelSpecialization | TypealiasOrRecord | c:@ST>2#T#T@PseudoOverridesInSpecializations@TypealiasOrRecord
// CHECK-NEXT: RelSpecialization | TypealiasOrRecord | c:@ST>2#T#T@PseudoOverridesInSpecializations@TypealiasOrRecord
};
template<typename T, typename U>
@ -215,10 +214,10 @@ class ConflictingPseudoOverridesInSpecialization {
template<typename T>
class ConflictingPseudoOverridesInSpecialization<int, T> {
void foo(T x);
// CHECK: [[@LINE-1]]:8 | instance-method/C++ | foo | c:@SP>1#T@ConflictingPseudoOverridesInSpecialization>#I#t0.0@F@foo#S0_# | <no-cgname> | Decl,RelChild,RelOver,RelSpecialization | rel: 3
// CHECK: [[@LINE-1]]:8 | instance-method/C++ | foo | c:@SP>1#T@ConflictingPseudoOverridesInSpecialization>#I#t0.0@F@foo#S0_# | <no-cgname> | Decl,RelChild,RelSpecialization | rel: 3
// CHECK-NEXT: RelChild
// CHECK-NEXT: RelOver,RelSpecialization | foo | c:@ST>2#T#T@ConflictingPseudoOverridesInSpecialization@F@foo#t0.0#
// CHECK-NEXT: RelOver,RelSpecialization | foo | c:@ST>2#T#T@ConflictingPseudoOverridesInSpecialization@F@foo#t0.1#
// CHECK-NEXT: RelSpecialization | foo | c:@ST>2#T#T@ConflictingPseudoOverridesInSpecialization@F@foo#t0.0#
// CHECK-NEXT: RelSpecialization | foo | c:@ST>2#T#T@ConflictingPseudoOverridesInSpecialization@F@foo#t0.1#
};
template<typename T, typename U, int x>

@ -0,0 +1,29 @@
// RUN: env CINDEXTEST_KEEP_GOING=1 c-index-test -code-completion-at=%s:25:1 %s
// Shouldn't crash!
// This is the minimized test that triggered an infinite recursion:
+(BOOL) onEntity {
}
-(const Object &) a_200 {
}
-(int) struct {
}
-(int) bar {
}
-(int) part {
}
+(some_type_t) piece {
}
+(void) z_Z_42 {
([self onEntity: [] { 42];
} class: ^ { }
];
[super];
BOOL struct;
}

@ -2,7 +2,7 @@
// The number of supported attributes should never go down!
// CHECK: #pragma clang attribute supports 59 attributes:
// CHECK: #pragma clang attribute supports 60 attributes:
// CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function)
// CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function)
// CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function)
@ -42,6 +42,7 @@
// CHECK-NEXT: ObjCRuntimeName (SubjectMatchRule_objc_interface, SubjectMatchRule_objc_protocol)
// CHECK-NEXT: ObjCRuntimeVisible (SubjectMatchRule_objc_interface)
// CHECK-NEXT: ObjCSubclassingRestricted (SubjectMatchRule_objc_interface)
// CHECK-NEXT: OpenCLIntelReqdSubGroupSize (SubjectMatchRule_function)
// CHECK-NEXT: OpenCLNoSVM (SubjectMatchRule_variable)
// CHECK-NEXT: OptimizeNone (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: Overloadable (SubjectMatchRule_function)

@ -0,0 +1,2 @@
#include "file.h"
extern int file2;

@ -1,2 +1,2 @@
module fwd { header "fwd.h" export * }
module file { header "file.h" export * }
module file { header "file.h" header "file2.h" export * }

@ -1,12 +1,101 @@
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: not %clang_cc1 -fmodules -fmodule-name=file -I%S/Inputs/preprocess -x c++-module-map %S/Inputs/preprocess/module.modulemap -E 2>&1 | FileCheck %s --check-prefix=MISSING-FWD
// MISSING-FWD: module 'fwd' is needed
// RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodules-cache-path=%t -I%S/Inputs/preprocess -x c++-module-map %S/Inputs/preprocess/module.modulemap -E | FileCheck %s
// RUN: %clang_cc1 -fmodules -fmodule-name=fwd -I%S/Inputs/preprocess -x c++-module-map %S/Inputs/preprocess/module.modulemap -emit-module -o %t/fwd.pcm
// Check that we can preprocess modules, and get the expected output.
// RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodule-file=%t/fwd.pcm -I%S/Inputs/preprocess -x c++-module-map %S/Inputs/preprocess/module.modulemap -E -o %t/no-rewrite.ii
// RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodule-file=%t/fwd.pcm -I%S/Inputs/preprocess -x c++-module-map %S/Inputs/preprocess/module.modulemap -E -frewrite-includes -o %t/rewrite.ii
//
// RUN: FileCheck %s --input-file %t/no-rewrite.ii --check-prefix=CHECK --check-prefix=NO-REWRITE
// RUN: FileCheck %s --input-file %t/rewrite.ii --check-prefix=CHECK --check-prefix=REWRITE
// Check that we can build a module from the preprocessed output.
// FIXME: For now, we need the headers to exist.
// RUN: touch %t/file.h %t/file2.h
// RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodule-file=%t/fwd.pcm -x c++-module-map-cpp-output %t/no-rewrite.ii -emit-module -o %t/no-rewrite.pcm
// RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodule-file=%t/fwd.pcm -x c++-module-map-cpp-output %t/rewrite.ii -emit-module -o %t/rewrite.pcm
// Check the module we built works.
// RUN: %clang_cc1 -fmodules -fmodule-file=%t/no-rewrite.pcm %s -verify
// RUN: %clang_cc1 -fmodules -fmodule-file=%t/rewrite.pcm %s -verify
// == module map
// CHECK: # 1 "{{.*}}module.modulemap"
// CHECK: module file {
// CHECK: header "file.h"
// CHECK: header "file2.h"
// CHECK: }
// == file.h
// CHECK: # 1 "<module-includes>"
// REWRITE: #if 0
// REWRITE: #include "file.h"
// REWRITE: #endif
//
// FIXME: It would be preferable to consistently put the module begin/end in
// the same file, but the relative ordering of PP callbacks and module
// begin/end tokens makes that difficult.
//
// REWRITE: #pragma clang module begin file
// CHECK: # 1 "{{.*}}file.h" 1
// NO-REWRITE: #pragma clang module begin file
// NO-REWRITE: # 1 "{{.*}}file.h"{{$}}
//
// CHECK: struct __FILE;
// CHECK: #pragma clang module import fwd /* clang -E: implicit import for #include "fwd.h" */
// CHECK: #pragma clang module import fwd /* clang {{-E|-frewrite-includes}}: implicit import
// CHECK: typedef struct __FILE FILE;
//
// REWRITE: #pragma clang module end
// CHECK: # 2 "<module-includes>" 2
// NO-REWRITE: #pragma clang module end
// == file2.h
// REWRITE: #if 0
// REWRITE: #include "file2.h"
// REWRITE: #endif
//
// REWRITE: #pragma clang module begin file
// CHECK: # 1 "{{.*}}file2.h" 1
// NO-REWRITE: #pragma clang module begin file
//
// ==== recursively re-enter file.h
// REWRITE: #if 0
// REWRITE: #include "file.h"
// REWRITE: #endif
//
// REWRITE: #pragma clang module begin file
// CHECK: # 1 "{{.*}}file.h" 1
// NO-REWRITE: #pragma clang module begin file
// NO-REWRITE: # 1 "{{.*}}file.h"{{$}}
//
// CHECK: struct __FILE;
// CHECK: #pragma clang module import fwd /* clang {{-E|-frewrite-includes}}: implicit import
// CHECK: typedef struct __FILE FILE;
//
// REWRITE: #pragma clang module end
// CHECK: # 2 "{{.*}}file2.h" 2
// NO-REWRITE: #pragma clang module end
// NO-REWRITE: # 2 "{{.*}}file2.h"{{$}}
// ==== return to file2.h
//
// CHECK: extern int file2;
//
// REWRITE: #pragma clang module end
// CHECK: # 3 "<module-includes>" 2
// NO-REWRITE: #pragma clang module end
// expected-no-diagnostics
// FIXME: This should be rejected: we have not imported the submodule defining it yet.
__FILE *a;
#pragma clang module import file
FILE *b;
int x = file2;

8
test/OpenMP/varargs.cpp Normal file

@ -0,0 +1,8 @@
// RUN: %clang_cc1 -verify -fopenmp %s
void f(int a, ...) {
#pragma omp parallel for
for (int i = 0; i < 100; ++i) {
__builtin_va_list ap;
__builtin_va_start(ap, a); // expected-error {{'va_start' cannot be used in a captured statement}}
}
};

@ -60,7 +60,7 @@ struct struct_without_uuid { };
struct __declspec(uuid("000000A0-0000-0000-C000-000000000049"))
struct_with_uuid2;
[uuid("000000A0-0000-0000-C000-000000000049")] struct struct_with_uuid3;
[uuid("000000A0-0000-0000-C000-000000000049")] struct struct_with_uuid3; // expected-warning{{specifying 'uuid' as an ATL attribute is deprecated; use __declspec instead}}
struct
struct_with_uuid2 {} ;

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify -fms-extensions %s
// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify -fms-extensions %s -Wno-deprecated-declarations
typedef struct _GUID {
unsigned long Data1;

@ -109,7 +109,7 @@
// CHECK-MCPU-THUNDERX2T99: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto"
// RUN: %clang -target x86_64-apple-macosx -arch arm64 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARCH-ARM64 %s
// CHECK-ARCH-ARM64: "-target-cpu" "cyclone" "-target-feature" "+neon" "-target-feature" "+crypto" "-target-feature" "+zcm" "-target-feature" "+zcz"
// CHECK-ARCH-ARM64: "-target-cpu" "cyclone" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+crypto" "-target-feature" "+zcm" "-target-feature" "+zcz"
// RUN: %clang -target aarch64 -march=armv8-a+fp+simd+crc+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-1 %s
// RUN: %clang -target aarch64 -march=armv8-a+nofp+nosimd+nocrc+nocrypto+fp+simd+crc+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-1 %s

@ -1,13 +1,20 @@
// RUN: %clang_cc1 %s -E | grep 'V);'
// RUN: %clang_cc1 %s -E | grep 'W, 1, 2);'
// RUN: %clang_cc1 %s -E | grep 'X, 1, 2);'
// RUN: %clang_cc1 %s -E | grep 'Y,);'
// RUN: %clang_cc1 %s -E | grep 'Z,);'
// RUN: %clang_cc1 %s -E | FileCheck --strict-whitespace --match-full-lines %s
// In the following tests, note that the output is sensitive to the
// whitespace *preceeding* the varargs argument, as well as to
// interior whitespace. AFAIK, this is the only case where whitespace
// preceeding an argument matters, and might be considered a bug in
// GCC. Nevertheless, since this feature is a GCC extension in the
// first place, we'll follow along.
#define debug(format, ...) format, ## __VA_ARGS__)
// CHECK:V);
debug(V);
debug(W, 1, 2);
// CHECK:W,1, 2);
debug(W,1, 2);
// CHECK:X, 1, 2);
debug(X, 1, 2 );
// CHECK:Y,);
debug(Y, );
// CHECK:Z,);
debug(Z,);

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