Vendor import of clang trunk r239412:
https://llvm.org/svn/llvm-project/cfe/trunk@239412
This commit is contained in:
parent
5e20cdd81c
commit
798321d8eb
@ -182,6 +182,9 @@ set(GCC_INSTALL_PREFIX "" CACHE PATH "Directory where gcc is installed." )
|
||||
set(DEFAULT_SYSROOT "" CACHE PATH
|
||||
"Default <path> to all compiler invocations for --sysroot=<path>." )
|
||||
|
||||
set(CLANG_DEFAULT_OPENMP_RUNTIME "libgomp" CACHE STRING
|
||||
"Default OpenMP runtime used by -fopenmp.")
|
||||
|
||||
set(CLANG_VENDOR "" CACHE STRING
|
||||
"Vendor-specific text for showing with version information.")
|
||||
|
||||
@ -362,6 +365,7 @@ macro(add_clang_library name)
|
||||
|
||||
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "libclang")
|
||||
install(TARGETS ${name}
|
||||
EXPORT ClangTargets
|
||||
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
|
||||
RUNTIME DESTINATION bin)
|
||||
@ -441,11 +445,6 @@ if(CLANG_ENABLE_STATIC_ANALYZER)
|
||||
add_definitions(-DCLANG_ENABLE_STATIC_ANALYZER)
|
||||
endif()
|
||||
|
||||
set(OPENMP_DEFAULT_LIB "" CACHE STRING "OpenMP library used by default for -fopenmp.")
|
||||
if(OPENMP_DEFAULT_LIB)
|
||||
add_definitions(-DOPENMP_DEFAULT_LIB=${OPENMP_DEFAULT_LIB})
|
||||
endif()
|
||||
|
||||
# Clang version information
|
||||
set(CLANG_EXECUTABLE_VERSION
|
||||
"${CLANG_VERSION_MAJOR}.${CLANG_VERSION_MINOR}" CACHE STRING
|
||||
@ -526,9 +525,10 @@ if (CLANG_BUILT_STANDALONE)
|
||||
|
||||
# Install a <prefix>/share/clang/cmake/ClangConfig.cmake file so that
|
||||
# find_package(Clang) works. Install the target list with it.
|
||||
install(EXPORT ClangTargets DESTINATION ${CLANG_INSTALL_PACKAGE_DIR})
|
||||
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/ClangConfig.cmake
|
||||
${CLANG_BINARY_DIR}/share/clang/cmake/ClangTargets.cmake
|
||||
DESTINATION share/clang/cmake)
|
||||
|
||||
# Also copy ClangConfig.cmake to the build directory so that dependent projects
|
||||
|
@ -110,7 +110,7 @@ will be chosen, so you'll almost always have to change it via flags.
|
||||
|
||||
Typical flags include:
|
||||
* ``-mcpu=<cpu-name>``, like x86-64, swift, cortex-a15
|
||||
* ``-fpu=<fpu-name>``, like SSE3, NEON, controlling the FP unit available
|
||||
* ``-mfpu=<fpu-name>``, like SSE3, NEON, controlling the FP unit available
|
||||
* ``-mfloat-abi=<fabi>``, like soft, hard, controlling which registers
|
||||
to use for floating-point
|
||||
|
||||
|
@ -138,12 +138,12 @@ The driver functionality is conceptually divided into five stages:
|
||||
this vector instead of storing its values directly.
|
||||
|
||||
The clang driver can dump the results of this stage using the
|
||||
``-ccc-print-options`` flag (which must precede any actual command
|
||||
``-###`` flag (which must precede any actual command
|
||||
line arguments). For example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ clang -ccc-print-options -Xarch_i386 -fomit-frame-pointer -Wa,-fast -Ifoo -I foo t.c
|
||||
$ clang -### -Xarch_i386 -fomit-frame-pointer -Wa,-fast -Ifoo -I foo t.c
|
||||
Option 0 - Name: "-Xarch_", Values: {"i386", "-fomit-frame-pointer"}
|
||||
Option 1 - Name: "-Wa,", Values: {"-fast"}
|
||||
Option 2 - Name: "-I", Values: {"foo"}
|
||||
|
@ -169,7 +169,7 @@ You should now be able to run the syntax checker, which is located in
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
cat "int main() { return 0; }" > test.cpp
|
||||
echo "int main() { return 0; }" > test.cpp
|
||||
bin/loop-convert test.cpp --
|
||||
|
||||
Note the two dashes after we specify the source file. The additional
|
||||
|
@ -1216,6 +1216,32 @@ behavior. Code that is not exercised in the profile will be optimized as if it
|
||||
is unimportant, and the compiler may make poor optimization choices for code
|
||||
that is disproportionately used while profiling.
|
||||
|
||||
Differences Between Sampling and Instrumentation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Although both techniques are used for similar purposes, there are important
|
||||
differences between the two:
|
||||
|
||||
1. Profile data generated with one cannot be used by the other, and there is no
|
||||
conversion tool that can convert one to the other. So, a profile generated
|
||||
via ``-fprofile-instr-generate`` must be used with ``-fprofile-instr-use``.
|
||||
Similarly, sampling profiles generated by external profilers must be
|
||||
converted and used with ``-fprofile-sample-use``.
|
||||
|
||||
2. Instrumentation profile data can be used for code coverage analysis and
|
||||
optimization.
|
||||
|
||||
3. Sampling profiles can only be used for optimization. They cannot be used for
|
||||
code coverage analysis. Although it would be technically possible to use
|
||||
sampling profiles for code coverage, sample-based profiles are too
|
||||
coarse-grained for code coverage purposes; it would yield poor results.
|
||||
|
||||
4. Sampling profiles must be generated by an external tool. The profile
|
||||
generated by that tool must then be converted into a format that can be read
|
||||
by LLVM. The section on sampling profilers describes one of the supported
|
||||
sampling profile formats.
|
||||
|
||||
|
||||
Using Sampling Profilers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@ -1283,21 +1309,38 @@ usual build cycle when using sample profilers for optimization:
|
||||
$ clang++ -O2 -gline-tables-only -fprofile-sample-use=code.prof code.cc -o code
|
||||
|
||||
|
||||
Sample Profile Format
|
||||
"""""""""""""""""""""
|
||||
Sample Profile Formats
|
||||
""""""""""""""""""""""
|
||||
|
||||
If you are not using Linux Perf to collect profiles, you will need to
|
||||
write a conversion tool from your profiler to LLVM's format. This section
|
||||
explains the file format expected by the backend.
|
||||
Since external profilers generate profile data in a variety of custom formats,
|
||||
the data generated by the profiler must be converted into a format that can be
|
||||
read by the backend. LLVM supports three different sample profile formats:
|
||||
|
||||
NOTE: This format is not intended to be used for code coverage. For that,
|
||||
you need to use Clang's instrumentation based profiling
|
||||
(``-fprofile-instr-generate``).
|
||||
1. ASCII text. This is the easiest one to generate. The file is divided into
|
||||
sections, which correspond to each of the functions with profile
|
||||
information. The format is described below.
|
||||
|
||||
Sample profiles are written as ASCII text. The file is divided into sections,
|
||||
which correspond to each of the functions executed at runtime. Each
|
||||
section has the following format (taken from
|
||||
https://github.com/google/autofdo/blob/master/profile_writer.h):
|
||||
2. Binary encoding. This uses a more efficient encoding that yields smaller
|
||||
profile files, which may be useful when generating large profiles. It can be
|
||||
generated from the text format using the ``llvm-profdata`` tool.
|
||||
|
||||
3. GCC encoding. This is based on the gcov format, which is accepted by GCC. It
|
||||
is only interesting in environments where GCC and Clang co-exist. Similarly
|
||||
to the binary encoding, it can be generated using the ``llvm-profdata`` tool.
|
||||
|
||||
If you are using Linux Perf to generate sampling profiles, you can use the
|
||||
conversion tool ``create_llvm_prof`` described in the previous section.
|
||||
Otherwise, you will need to write a conversion tool that converts your
|
||||
profiler's native format into one of these three.
|
||||
|
||||
|
||||
Sample Profile Text Format
|
||||
""""""""""""""""""""""""""
|
||||
|
||||
This section describes the ASCII text format for sampling profiles. It is,
|
||||
arguably, the easiest one to generate. If you are interested in generating any
|
||||
of the other two, consult the ``ProfileData`` library in in LLVM's source tree
|
||||
(specifically, ``llvm/lib/ProfileData/SampleProfWriter.cpp``).
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
@ -1404,8 +1447,8 @@ instrumentation:
|
||||
$ LLVM_PROFILE_FILE="code-%p.profraw" ./code
|
||||
|
||||
3. Combine profiles from multiple runs and convert the "raw" profile format to
|
||||
the input expected by clang. Use the ``merge`` command of the llvm-profdata
|
||||
tool to do this.
|
||||
the input expected by clang. Use the ``merge`` command of the
|
||||
``llvm-profdata`` tool to do this.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
|
@ -236,7 +236,11 @@ class NamedDecl : public Decl {
|
||||
bool isHidden() const { return Hidden; }
|
||||
|
||||
/// \brief Set whether this declaration is hidden from name lookup.
|
||||
void setHidden(bool Hide) { Hidden = Hide; }
|
||||
void setHidden(bool Hide) {
|
||||
assert((!Hide || isFromASTFile() || hasLocalOwningModuleStorage()) &&
|
||||
"declaration with no owning module can't be hidden");
|
||||
Hidden = Hide;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this declaration is a C++ class member.
|
||||
bool isCXXClassMember() const {
|
||||
|
@ -637,6 +637,8 @@ class Decl {
|
||||
|
||||
private:
|
||||
Module *getOwningModuleSlow() const;
|
||||
protected:
|
||||
bool hasLocalOwningModuleStorage() const;
|
||||
|
||||
public:
|
||||
/// \brief Get the imported owning module, if this decl is from an imported
|
||||
@ -656,7 +658,7 @@ class Decl {
|
||||
return reinterpret_cast<Module *const *>(this)[-1];
|
||||
}
|
||||
void setLocalOwningModule(Module *M) {
|
||||
assert(!isFromASTFile() && Hidden &&
|
||||
assert(!isFromASTFile() && Hidden && hasLocalOwningModuleStorage() &&
|
||||
"should not have a cached owning module");
|
||||
reinterpret_cast<Module **>(this)[-1] = M;
|
||||
}
|
||||
|
@ -1392,6 +1392,10 @@ class CXXRecordDecl : public RecordDecl {
|
||||
/// \brief Returns the destructor decl for this class.
|
||||
CXXDestructorDecl *getDestructor() const;
|
||||
|
||||
/// \brief Returns true if the class destructor, or any implicitly invoked
|
||||
/// destructors are marked noreturn.
|
||||
bool isAnyDestructorNoReturn() const;
|
||||
|
||||
/// \brief If the class is a local class [class.local], returns
|
||||
/// the enclosing function declaration.
|
||||
const FunctionDecl *isLocalClass() const {
|
||||
|
@ -1476,6 +1476,23 @@ const internal::VariadicDynCastAllOfMatcher<
|
||||
Stmt,
|
||||
ConditionalOperator> conditionalOperator;
|
||||
|
||||
/// \brief Matches a C++ static_assert declaration.
|
||||
///
|
||||
/// Example:
|
||||
/// staticAssertExpr()
|
||||
/// matches
|
||||
/// static_assert(sizeof(S) == sizeof(int))
|
||||
/// in
|
||||
/// \code
|
||||
/// struct S {
|
||||
/// int x;
|
||||
/// };
|
||||
/// static_assert(sizeof(S) == sizeof(int));
|
||||
/// \endcode
|
||||
const internal::VariadicDynCastAllOfMatcher<
|
||||
Decl,
|
||||
StaticAssertDecl> staticAssertDecl;
|
||||
|
||||
/// \brief Matches a reinterpret_cast expression.
|
||||
///
|
||||
/// Either the source expression or the destination type can be matched
|
||||
|
@ -738,6 +738,7 @@ class CFG {
|
||||
bool AddTemporaryDtors;
|
||||
bool AddStaticInitBranches;
|
||||
bool AddCXXNewAllocator;
|
||||
bool AddCXXDefaultInitExprInCtors;
|
||||
|
||||
bool alwaysAdd(const Stmt *stmt) const {
|
||||
return alwaysAddMask[stmt->getStmtClass()];
|
||||
@ -758,7 +759,7 @@ class CFG {
|
||||
PruneTriviallyFalseEdges(true), AddEHEdges(false),
|
||||
AddInitializers(false), AddImplicitDtors(false),
|
||||
AddTemporaryDtors(false), AddStaticInitBranches(false),
|
||||
AddCXXNewAllocator(false) {}
|
||||
AddCXXNewAllocator(false), AddCXXDefaultInitExprInCtors(false) {}
|
||||
};
|
||||
|
||||
/// \brief Provides a custom implementation of the iterator class to have the
|
||||
|
@ -115,7 +115,23 @@ def err_integer_literal_too_large : Error<
|
||||
def ext_integer_literal_too_large_for_signed : ExtWarn<
|
||||
"integer literal is too large to be represented in a signed integer type, "
|
||||
"interpreting as unsigned">,
|
||||
InGroup<DiagGroup<"implicitly-unsigned-literal">>;
|
||||
InGroup<ImplicitlyUnsignedLiteral>;
|
||||
def warn_old_implicitly_unsigned_long : Warning<
|
||||
"integer literal is too large to be represented in type 'long', "
|
||||
"interpreting as 'unsigned long' per C89; this literal will "
|
||||
"%select{have type 'long long'|be ill-formed}0 in C99 onwards">,
|
||||
InGroup<C99Compat>;
|
||||
def warn_old_implicitly_unsigned_long_cxx : Warning<
|
||||
"integer literal is too large to be represented in type 'long', "
|
||||
"interpreting as 'unsigned long' per C++98; this literal will "
|
||||
"%select{have type 'long long'|be ill-formed}0 in C++11 onwards">,
|
||||
InGroup<CXX11Compat>;
|
||||
def ext_old_implicitly_unsigned_long_cxx : ExtWarn<
|
||||
"integer literal is too large to be represented in type 'long' and is "
|
||||
"subject to undefined behavior under C++98, interpreting as 'unsigned long'; "
|
||||
"this literal will %select{have type 'long long'|be ill-formed}0 "
|
||||
"in C++11 onwards">,
|
||||
InGroup<CXX11Compat>;
|
||||
|
||||
// SEH
|
||||
def err_seh_expected_handler : Error<
|
||||
|
@ -239,6 +239,7 @@ def MultiChar : DiagGroup<"multichar">;
|
||||
def : DiagGroup<"nested-externs">;
|
||||
def CXX11LongLong : DiagGroup<"c++11-long-long">;
|
||||
def LongLong : DiagGroup<"long-long", [CXX11LongLong]>;
|
||||
def ImplicitlyUnsignedLiteral : DiagGroup<"implicitly-unsigned-literal">;
|
||||
def MethodSignatures : DiagGroup<"method-signatures">;
|
||||
def MismatchedParameterTypes : DiagGroup<"mismatched-parameter-types">;
|
||||
def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">;
|
||||
@ -264,6 +265,8 @@ def : DiagGroup<"overflow">;
|
||||
def ForwardClassReceiver : DiagGroup<"receiver-forward-class">;
|
||||
def MethodAccess : DiagGroup<"objc-method-access">;
|
||||
def ObjCReceiver : DiagGroup<"receiver-expr">;
|
||||
// FIXME: Remove this when Xcode removes the warning setting.
|
||||
def : DiagGroup<"receiver-is-weak">;
|
||||
def OperatorNewReturnsNull : DiagGroup<"new-returns-null">;
|
||||
def OverlengthStrings : DiagGroup<"overlength-strings">;
|
||||
def OverloadedVirtual : DiagGroup<"overloaded-virtual">;
|
||||
|
@ -908,10 +908,6 @@ def warn_dealloc_in_category : Warning<
|
||||
InGroup<DeallocInCategory>;
|
||||
def err_gc_weak_property_strong_type : Error<
|
||||
"weak attribute declared on a __strong type property in GC mode">;
|
||||
def warn_receiver_is_weak : Warning <
|
||||
"weak %select{receiver|property|implicit property}0 may be "
|
||||
"unpredictably set to nil">,
|
||||
InGroup<DiagGroup<"receiver-is-weak">>, DefaultIgnore;
|
||||
def warn_arc_repeated_use_of_weak : Warning <
|
||||
"weak %select{variable|property|implicit property|instance variable}0 %1 is "
|
||||
"accessed multiple times in this %select{function|method|block|lambda}2 "
|
||||
@ -2262,8 +2258,7 @@ def err_attribute_dll_member_of_dll_class : Error<
|
||||
"attribute %q0 cannot be applied to member of %q1 class">;
|
||||
def warn_attribute_dll_instantiated_base_class : Warning<
|
||||
"propagating dll attribute to %select{already instantiated|explicitly specialized}0 "
|
||||
"base class template "
|
||||
"%select{without dll attribute|with different dll attribute}1 is not supported">,
|
||||
"base class template without dll attribute is not supported">,
|
||||
InGroup<DiagGroup<"unsupported-dll-base-class-template">>, DefaultIgnore;
|
||||
def err_attribute_weakref_not_static : Error<
|
||||
"weakref declaration must have internal linkage">;
|
||||
@ -5390,6 +5385,10 @@ def err_bad_const_cast_dest : Error<
|
||||
"which is not a reference, pointer-to-object, or pointer-to-data-member">;
|
||||
def ext_cast_fn_obj : Extension<
|
||||
"cast between pointer-to-function and pointer-to-object is an extension">;
|
||||
def ext_ms_cast_fn_obj : ExtWarn<
|
||||
"static_cast between pointer-to-function and pointer-to-object is a "
|
||||
"Microsoft extension">,
|
||||
InGroup<Microsoft>;
|
||||
def warn_cxx98_compat_cast_fn_obj : Warning<
|
||||
"cast between pointer-to-function and pointer-to-object is incompatible with C++98">,
|
||||
InGroup<CXX98CompatPedantic>, DefaultIgnore;
|
||||
@ -6334,6 +6333,9 @@ let CategoryName = "Inline Assembly Issue" in {
|
||||
"remove the cast or build with -fheinous-gnu-extensions">;
|
||||
def err_invalid_asm_value_for_constraint
|
||||
: Error <"value '%0' out of range for constraint '%1'">;
|
||||
def err_asm_bitfield_in_memory_constraint
|
||||
: Error <"reference to a bit-field in asm "
|
||||
"%select{input|output}0 with a memory constraint '%1'">;
|
||||
|
||||
def warn_asm_label_on_auto_decl : Warning<
|
||||
"ignored asm label '%0' on automatic variable">;
|
||||
@ -7404,8 +7406,6 @@ def err_omp_unexpected_clause_value : Error<
|
||||
"expected %0 in OpenMP clause '%1'">;
|
||||
def err_omp_expected_var_name : Error<
|
||||
"expected variable name">;
|
||||
def err_omp_required_method : Error<
|
||||
"%0 variable must have an accessible, unambiguous %select{default constructor|copy constructor|copy assignment operator|'%2'|destructor}1">;
|
||||
def note_omp_task_predetermined_firstprivate_here : Note<
|
||||
"predetermined as a firstprivate in a task construct here">;
|
||||
def err_omp_clause_ref_type_arg : Error<
|
||||
|
@ -10,7 +10,8 @@
|
||||
// This file defines the TokenKind database. This includes normal tokens like
|
||||
// tok::ampamp (corresponding to the && token) as well as keywords for various
|
||||
// languages. Users of this file must optionally #define the TOK, KEYWORD,
|
||||
// CXX11_KEYWORD, ALIAS, or PPKEYWORD macros to make use of this file.
|
||||
// CXX11_KEYWORD, CONCEPTS_KEYWORD, ALIAS, or PPKEYWORD macros to make use of
|
||||
// this file.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -26,6 +27,9 @@
|
||||
#ifndef CXX11_KEYWORD
|
||||
#define CXX11_KEYWORD(X,Y) KEYWORD(X,KEYCXX11|(Y))
|
||||
#endif
|
||||
#ifndef CONCEPTS_KEYWORD
|
||||
#define CONCEPTS_KEYWORD(X) KEYWORD(X,KEYCONCEPTS)
|
||||
#endif
|
||||
#ifndef TYPE_TRAIT
|
||||
#define TYPE_TRAIT(N,I,K) KEYWORD(I,K)
|
||||
#endif
|
||||
@ -226,6 +230,8 @@ PUNCTUATOR(greatergreatergreater, ">>>")
|
||||
// implementation namespace
|
||||
// KEYNOCXX - This is a keyword in every non-C++ dialect.
|
||||
// KEYCXX11 - This is a C++ keyword introduced to C++ in C++11
|
||||
// KEYCONCEPTS - This is a keyword if the C++ extensions for concepts
|
||||
// are enabled.
|
||||
// KEYGNU - This is a keyword if GNU extensions are enabled
|
||||
// KEYMS - This is a keyword if Microsoft extensions are enabled
|
||||
// KEYNOMS18 - This is a keyword that must never be enabled under
|
||||
@ -344,6 +350,10 @@ CXX11_KEYWORD(nullptr , 0)
|
||||
CXX11_KEYWORD(static_assert , 0)
|
||||
CXX11_KEYWORD(thread_local , 0)
|
||||
|
||||
// C++ concepts TS keywords
|
||||
CONCEPTS_KEYWORD(concept)
|
||||
CONCEPTS_KEYWORD(requires)
|
||||
|
||||
// GNU Extensions (in impl-reserved namespace)
|
||||
KEYWORD(_Decimal32 , KEYALL)
|
||||
KEYWORD(_Decimal64 , KEYALL)
|
||||
@ -738,6 +748,7 @@ ANNOTATION(module_end)
|
||||
#undef TYPE_TRAIT_2
|
||||
#undef TYPE_TRAIT_1
|
||||
#undef TYPE_TRAIT
|
||||
#undef CONCEPTS_KEYWORD
|
||||
#undef CXX11_KEYWORD
|
||||
#undef KEYWORD
|
||||
#undef PUNCTUATOR
|
||||
|
@ -8,6 +8,9 @@
|
||||
/* Bug report URL. */
|
||||
#define BUG_REPORT_URL "${BUG_REPORT_URL}"
|
||||
|
||||
/* Default OpenMP runtime used by -fopenmp. */
|
||||
#define CLANG_DEFAULT_OPENMP_RUNTIME "${CLANG_DEFAULT_OPENMP_RUNTIME}"
|
||||
|
||||
/* Multilib suffix for libdir. */
|
||||
#define CLANG_LIBDIR_SUFFIX "${CLANG_LIBDIR_SUFFIX}"
|
||||
|
||||
|
@ -8,6 +8,9 @@
|
||||
/* Bug report URL. */
|
||||
#undef BUG_REPORT_URL
|
||||
|
||||
/* Default OpenMP runtime used by -fopenmp. */
|
||||
#undef CLANG_DEFAULT_OPENMP_RUNTIME
|
||||
|
||||
/* Multilib suffix for libdir. */
|
||||
#undef CLANG_LIBDIR_SUFFIX
|
||||
|
||||
|
@ -202,6 +202,7 @@ def _SLASH_Fi : CLCompileJoined<"Fi">,
|
||||
def _SLASH_Fo : CLCompileJoined<"Fo">,
|
||||
HelpText<"Set output object file, or directory (ends in / or \\)">,
|
||||
MetaVarName<"<file or directory>">;
|
||||
def _SLASH_GL : CLFlag<"GL">, Alias<flto>;
|
||||
def _SLASH_LD : CLFlag<"LD">, HelpText<"Create DLL">;
|
||||
def _SLASH_LDd : CLFlag<"LDd">, HelpText<"Create debug DLL">;
|
||||
def _SLASH_link : CLRemainingArgs<"link">,
|
||||
@ -286,7 +287,6 @@ def _SLASH_G2 : CLFlag<"G2">;
|
||||
def _SLASH_Ge : CLFlag<"Ge">;
|
||||
def _SLASH_Gh : CLFlag<"Gh">;
|
||||
def _SLASH_GH : CLFlag<"GH">;
|
||||
def _SLASH_GL : CLFlag<"GL">;
|
||||
def _SLASH_GL_ : CLFlag<"GL-">;
|
||||
def _SLASH_Gm : CLFlag<"Gm">;
|
||||
def _SLASH_Gm_ : CLFlag<"Gm-">;
|
||||
|
@ -876,6 +876,7 @@ def fno_objc_nonfragile_abi : Flag<["-"], "fno-objc-nonfragile-abi">, Group<f_Gr
|
||||
def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>;
|
||||
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
|
||||
def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
|
||||
def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>, Flags<[NoArgumentUnused]>;
|
||||
def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>;
|
||||
def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
|
||||
def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
|
||||
|
@ -55,14 +55,14 @@ TYPE("objective-c++", ObjCXX, PP_ObjCXX, "mm", "u")
|
||||
|
||||
// C family input files to precompile.
|
||||
TYPE("c-header-cpp-output", PP_CHeader, INVALID, "i", "p")
|
||||
TYPE("c-header", CHeader, PP_CHeader, nullptr, "pu")
|
||||
TYPE("cl-header", CLHeader, PP_CHeader, nullptr, "pu")
|
||||
TYPE("c-header", CHeader, PP_CHeader, "h", "pu")
|
||||
TYPE("cl-header", CLHeader, PP_CHeader, "h", "pu")
|
||||
TYPE("objective-c-header-cpp-output", PP_ObjCHeader, INVALID, "mi", "p")
|
||||
TYPE("objective-c-header", ObjCHeader, PP_ObjCHeader, nullptr, "pu")
|
||||
TYPE("objective-c-header", ObjCHeader, PP_ObjCHeader, "h", "pu")
|
||||
TYPE("c++-header-cpp-output", PP_CXXHeader, INVALID, "ii", "p")
|
||||
TYPE("c++-header", CXXHeader, PP_CXXHeader, nullptr, "pu")
|
||||
TYPE("c++-header", CXXHeader, PP_CXXHeader, "hh", "pu")
|
||||
TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID, "mii", "p")
|
||||
TYPE("objective-c++-header", ObjCXXHeader, PP_ObjCXXHeader, nullptr, "pu")
|
||||
TYPE("objective-c++-header", ObjCXXHeader, PP_ObjCXXHeader, "h", "pu")
|
||||
|
||||
// Other languages.
|
||||
TYPE("ada", Ada, INVALID, nullptr, "u")
|
||||
|
@ -180,14 +180,14 @@ class HeaderSearchOptions : public RefCountedBase<HeaderSearchOptions> {
|
||||
/// AddPath - Add the \p Path path to the specified \p Group list.
|
||||
void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
|
||||
bool IsFramework, bool IgnoreSysRoot) {
|
||||
UserEntries.push_back(Entry(Path, Group, IsFramework, IgnoreSysRoot));
|
||||
UserEntries.emplace_back(Path, Group, IsFramework, IgnoreSysRoot);
|
||||
}
|
||||
|
||||
/// AddSystemHeaderPrefix - Override whether \#include directives naming a
|
||||
/// path starting with \p Prefix should be considered as naming a system
|
||||
/// header.
|
||||
void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
|
||||
SystemHeaderPrefixes.push_back(SystemHeaderPrefix(Prefix, IsSystemHeader));
|
||||
SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
|
||||
}
|
||||
|
||||
void AddVFSOverlayFile(StringRef Name) {
|
||||
|
@ -228,7 +228,7 @@ class Lexer : public PreprocessorLexer {
|
||||
/// Stringify - Convert the specified string into a C string by escaping '\'
|
||||
/// and " characters. This does not add surrounding ""'s to the string.
|
||||
/// If Charify is true, this escapes the ' character instead of ".
|
||||
static std::string Stringify(const std::string &Str, bool Charify = false);
|
||||
static std::string Stringify(StringRef Str, bool Charify = false);
|
||||
|
||||
/// Stringify - Convert the specified string into a C string by escaping '\'
|
||||
/// and " characters. This does not add surrounding ""'s to the string.
|
||||
|
@ -44,8 +44,8 @@ class MacroInfo {
|
||||
///
|
||||
/// ArgumentList points to the first of NumArguments pointers.
|
||||
///
|
||||
/// This can be empty, for, e.g. "#define X()". In a C99-style variadic macro, this
|
||||
/// includes the \c __VA_ARGS__ identifier on the list.
|
||||
/// This can be empty, for, e.g. "#define X()". In a C99-style variadic
|
||||
/// macro, this includes the \c __VA_ARGS__ identifier on the list.
|
||||
IdentifierInfo **ArgumentList;
|
||||
|
||||
/// \see ArgumentList
|
||||
@ -70,15 +70,15 @@ class MacroInfo {
|
||||
|
||||
/// \brief True if this macro is of the form "#define X(a...)".
|
||||
///
|
||||
/// The "a" identifier in the replacement list will be replaced with all arguments
|
||||
/// of the macro starting with the specified one.
|
||||
/// The "a" identifier in the replacement list will be replaced with all
|
||||
/// arguments of the macro starting with the specified one.
|
||||
bool IsGNUVarargs : 1;
|
||||
|
||||
/// \brief True if this macro requires processing before expansion.
|
||||
///
|
||||
/// This is the case for builtin macros such as __LINE__, so long as they have
|
||||
/// not been redefined, but not for regular predefined macros from the "<built-in>"
|
||||
/// memory buffer (see Preprocessing::getPredefinesFileID).
|
||||
/// not been redefined, but not for regular predefined macros from the
|
||||
/// "<built-in>" memory buffer (see Preprocessing::getPredefinesFileID).
|
||||
bool IsBuiltinMacro : 1;
|
||||
|
||||
/// \brief Whether this macro contains the sequence ", ## __VA_ARGS__"
|
||||
@ -143,14 +143,10 @@ class MacroInfo {
|
||||
bool Syntactically) const;
|
||||
|
||||
/// \brief Set or clear the isBuiltinMacro flag.
|
||||
void setIsBuiltinMacro(bool Val = true) {
|
||||
IsBuiltinMacro = Val;
|
||||
}
|
||||
void setIsBuiltinMacro(bool Val = true) { IsBuiltinMacro = Val; }
|
||||
|
||||
/// \brief Set the value of the IsUsed flag.
|
||||
void setIsUsed(bool Val) {
|
||||
IsUsed = Val;
|
||||
}
|
||||
void setIsUsed(bool Val) { IsUsed = Val; }
|
||||
|
||||
/// \brief Set the value of the IsAllowRedefinitionsWithoutWarning flag.
|
||||
void setIsAllowRedefinitionsWithoutWarning(bool Val) {
|
||||
@ -158,37 +154,40 @@ class MacroInfo {
|
||||
}
|
||||
|
||||
/// \brief Set the value of the IsWarnIfUnused flag.
|
||||
void setIsWarnIfUnused(bool val) {
|
||||
IsWarnIfUnused = val;
|
||||
}
|
||||
void setIsWarnIfUnused(bool val) { IsWarnIfUnused = val; }
|
||||
|
||||
/// \brief Set the specified list of identifiers as the argument list for
|
||||
/// this macro.
|
||||
void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs,
|
||||
void setArgumentList(IdentifierInfo *const *List, unsigned NumArgs,
|
||||
llvm::BumpPtrAllocator &PPAllocator) {
|
||||
assert(ArgumentList == nullptr && NumArguments == 0 &&
|
||||
"Argument list already set!");
|
||||
if (NumArgs == 0) return;
|
||||
if (NumArgs == 0)
|
||||
return;
|
||||
|
||||
NumArguments = NumArgs;
|
||||
ArgumentList = PPAllocator.Allocate<IdentifierInfo*>(NumArgs);
|
||||
ArgumentList = PPAllocator.Allocate<IdentifierInfo *>(NumArgs);
|
||||
for (unsigned i = 0; i != NumArgs; ++i)
|
||||
ArgumentList[i] = List[i];
|
||||
}
|
||||
|
||||
/// Arguments - The list of arguments for a function-like macro. This can be
|
||||
/// empty, for, e.g. "#define X()".
|
||||
typedef IdentifierInfo* const *arg_iterator;
|
||||
typedef IdentifierInfo *const *arg_iterator;
|
||||
bool arg_empty() const { return NumArguments == 0; }
|
||||
arg_iterator arg_begin() const { return ArgumentList; }
|
||||
arg_iterator arg_end() const { return ArgumentList+NumArguments; }
|
||||
arg_iterator arg_end() const { return ArgumentList + NumArguments; }
|
||||
unsigned getNumArgs() const { return NumArguments; }
|
||||
ArrayRef<const IdentifierInfo *> args() const {
|
||||
return ArrayRef<const IdentifierInfo *>(ArgumentList, NumArguments);
|
||||
}
|
||||
|
||||
/// \brief Return the argument number of the specified identifier,
|
||||
/// or -1 if the identifier is not a formal argument identifier.
|
||||
int getArgumentNum(IdentifierInfo *Arg) const {
|
||||
int getArgumentNum(const IdentifierInfo *Arg) const {
|
||||
for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
|
||||
if (*I == Arg) return I-arg_begin();
|
||||
if (*I == Arg)
|
||||
return I - arg_begin();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -226,15 +225,11 @@ class MacroInfo {
|
||||
}
|
||||
|
||||
/// \brief Return true if we should emit a warning if the macro is unused.
|
||||
bool isWarnIfUnused() const {
|
||||
return IsWarnIfUnused;
|
||||
}
|
||||
bool isWarnIfUnused() const { return IsWarnIfUnused; }
|
||||
|
||||
/// \brief Return the number of tokens that this macro expands to.
|
||||
///
|
||||
unsigned getNumTokens() const {
|
||||
return ReplacementTokens.size();
|
||||
}
|
||||
unsigned getNumTokens() const { return ReplacementTokens.size(); }
|
||||
|
||||
const Token &getReplacementToken(unsigned Tok) const {
|
||||
assert(Tok < ReplacementTokens.size() && "Invalid token #");
|
||||
@ -249,8 +244,9 @@ class MacroInfo {
|
||||
|
||||
/// \brief Add the specified token to the replacement text for the macro.
|
||||
void AddTokenToBody(const Token &Tok) {
|
||||
assert(!IsDefinitionLengthCached &&
|
||||
"Changing replacement tokens after definition length got calculated");
|
||||
assert(
|
||||
!IsDefinitionLengthCached &&
|
||||
"Changing replacement tokens after definition length got calculated");
|
||||
ReplacementTokens.push_back(Tok);
|
||||
}
|
||||
|
||||
@ -282,7 +278,7 @@ class MacroInfo {
|
||||
/// macro info.
|
||||
unsigned getOwningModuleID() const {
|
||||
if (isFromASTFile())
|
||||
return *(const unsigned*)(this+1);
|
||||
return *(const unsigned *)(this + 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -294,7 +290,7 @@ class MacroInfo {
|
||||
|
||||
void setOwningModuleID(unsigned ID) {
|
||||
assert(isFromASTFile());
|
||||
*(unsigned*)(this+1) = ID;
|
||||
*(unsigned *)(this + 1) = ID;
|
||||
}
|
||||
|
||||
friend class Preprocessor;
|
||||
@ -311,11 +307,7 @@ class DefMacroDirective;
|
||||
/// create additional DefMacroDirectives for the same MacroInfo.
|
||||
class MacroDirective {
|
||||
public:
|
||||
enum Kind {
|
||||
MD_Define,
|
||||
MD_Undefine,
|
||||
MD_Visibility
|
||||
};
|
||||
enum Kind { MD_Define, MD_Undefine, MD_Visibility };
|
||||
|
||||
protected:
|
||||
/// \brief Previous macro directive for the same identifier, or NULL.
|
||||
@ -345,9 +337,7 @@ class MacroDirective {
|
||||
SourceLocation getLocation() const { return Loc; }
|
||||
|
||||
/// \brief Set previous definition of the macro with the same name.
|
||||
void setPrevious(MacroDirective *Prev) {
|
||||
Previous = Prev;
|
||||
}
|
||||
void setPrevious(MacroDirective *Prev) { Previous = Prev; }
|
||||
|
||||
/// \brief Get previous definition of the macro with the same name.
|
||||
const MacroDirective *getPrevious() const { return Previous; }
|
||||
@ -366,19 +356,19 @@ class MacroDirective {
|
||||
bool IsPublic;
|
||||
|
||||
public:
|
||||
DefInfo() : DefDirective(nullptr), IsPublic(true) { }
|
||||
DefInfo() : DefDirective(nullptr), IsPublic(true) {}
|
||||
|
||||
DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
|
||||
bool isPublic)
|
||||
: DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) { }
|
||||
: DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) {}
|
||||
|
||||
const DefMacroDirective *getDirective() const { return DefDirective; }
|
||||
DefMacroDirective *getDirective() { return DefDirective; }
|
||||
DefMacroDirective *getDirective() { return DefDirective; }
|
||||
|
||||
inline SourceLocation getLocation() const;
|
||||
inline MacroInfo *getMacroInfo();
|
||||
const MacroInfo *getMacroInfo() const {
|
||||
return const_cast<DefInfo*>(this)->getMacroInfo();
|
||||
return const_cast<DefInfo *>(this)->getMacroInfo();
|
||||
}
|
||||
|
||||
SourceLocation getUndefLocation() const { return UndefLoc; }
|
||||
@ -393,7 +383,7 @@ class MacroDirective {
|
||||
|
||||
inline DefInfo getPreviousDefinition();
|
||||
const DefInfo getPreviousDefinition() const {
|
||||
return const_cast<DefInfo*>(this)->getPreviousDefinition();
|
||||
return const_cast<DefInfo *>(this)->getPreviousDefinition();
|
||||
}
|
||||
};
|
||||
|
||||
@ -402,7 +392,7 @@ class MacroDirective {
|
||||
/// (if there is one) and if it is public or private.
|
||||
DefInfo getDefinition();
|
||||
const DefInfo getDefinition() const {
|
||||
return const_cast<MacroDirective*>(this)->getDefinition();
|
||||
return const_cast<MacroDirective *>(this)->getDefinition();
|
||||
}
|
||||
|
||||
bool isDefined() const {
|
||||
@ -414,9 +404,7 @@ class MacroDirective {
|
||||
const MacroInfo *getMacroInfo() const {
|
||||
return getDefinition().getMacroInfo();
|
||||
}
|
||||
MacroInfo *getMacroInfo() {
|
||||
return getDefinition().getMacroInfo();
|
||||
}
|
||||
MacroInfo *getMacroInfo() { return getDefinition().getMacroInfo(); }
|
||||
|
||||
/// \brief Find macro definition active in the specified source location. If
|
||||
/// this macro was not defined there, return NULL.
|
||||
@ -450,7 +438,7 @@ class DefMacroDirective : public MacroDirective {
|
||||
};
|
||||
|
||||
/// \brief A directive for an undefined macro.
|
||||
class UndefMacroDirective : public MacroDirective {
|
||||
class UndefMacroDirective : public MacroDirective {
|
||||
public:
|
||||
explicit UndefMacroDirective(SourceLocation UndefLoc)
|
||||
: MacroDirective(MD_Undefine, UndefLoc) {
|
||||
@ -464,7 +452,7 @@ class UndefMacroDirective : public MacroDirective {
|
||||
};
|
||||
|
||||
/// \brief A directive for setting the module visibility of a macro.
|
||||
class VisibilityMacroDirective : public MacroDirective {
|
||||
class VisibilityMacroDirective : public MacroDirective {
|
||||
public:
|
||||
explicit VisibilityMacroDirective(SourceLocation Loc, bool Public)
|
||||
: MacroDirective(MD_Visibility, Loc) {
|
||||
@ -518,14 +506,14 @@ class ModuleMacro : public llvm::FoldingSetNode {
|
||||
unsigned NumOverriddenBy;
|
||||
/// The number of modules whose macros are directly overridden by this one.
|
||||
unsigned NumOverrides;
|
||||
//ModuleMacro *OverriddenMacros[NumOverrides];
|
||||
// ModuleMacro *OverriddenMacros[NumOverrides];
|
||||
|
||||
friend class Preprocessor;
|
||||
|
||||
ModuleMacro(Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro,
|
||||
ArrayRef<ModuleMacro *> Overrides)
|
||||
: II(II), Macro(Macro), OwningModule(OwningModule),
|
||||
NumOverriddenBy(0), NumOverrides(Overrides.size()) {
|
||||
: II(II), Macro(Macro), OwningModule(OwningModule), NumOverriddenBy(0),
|
||||
NumOverrides(Overrides.size()) {
|
||||
std::copy(Overrides.begin(), Overrides.end(),
|
||||
reinterpret_cast<ModuleMacro **>(this + 1));
|
||||
}
|
||||
|
@ -272,16 +272,11 @@ class ModuleMap {
|
||||
/// used from. Used to disambiguate if a header is present in multiple
|
||||
/// modules.
|
||||
///
|
||||
/// \param IncludeTextualHeaders If \c true, also find textual headers. By
|
||||
/// default, these are treated like excluded headers and result in no known
|
||||
/// header being found.
|
||||
///
|
||||
/// \returns The module KnownHeader, which provides the module that owns the
|
||||
/// given header file. The KnownHeader is default constructed to indicate
|
||||
/// that no module owns this header file.
|
||||
KnownHeader findModuleForHeader(const FileEntry *File,
|
||||
Module *RequestingModule = nullptr,
|
||||
bool IncludeTextualHeaders = false);
|
||||
Module *RequestingModule = nullptr);
|
||||
|
||||
/// \brief Reports errors if a module must not include a specific file.
|
||||
///
|
||||
|
@ -155,7 +155,7 @@ class PPCallbacks {
|
||||
/// \param Loc The location of the directive.
|
||||
/// \param str The text of the directive.
|
||||
///
|
||||
virtual void Ident(SourceLocation Loc, const std::string &str) {
|
||||
virtual void Ident(SourceLocation Loc, StringRef str) {
|
||||
}
|
||||
|
||||
/// \brief Callback invoked when start reading any pragma directive.
|
||||
@ -165,14 +165,13 @@ class PPCallbacks {
|
||||
|
||||
/// \brief Callback invoked when a \#pragma comment directive is read.
|
||||
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
|
||||
const std::string &Str) {
|
||||
StringRef Str) {
|
||||
}
|
||||
|
||||
/// \brief Callback invoked when a \#pragma detect_mismatch directive is
|
||||
/// read.
|
||||
virtual void PragmaDetectMismatch(SourceLocation Loc,
|
||||
const std::string &Name,
|
||||
const std::string &Value) {
|
||||
virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
|
||||
StringRef Value) {
|
||||
}
|
||||
|
||||
/// \brief Callback invoked when a \#pragma clang __debug directive is read.
|
||||
@ -375,19 +374,19 @@ class PPChainedCallbacks : public PPCallbacks {
|
||||
Second->EndOfMainFile();
|
||||
}
|
||||
|
||||
void Ident(SourceLocation Loc, const std::string &str) override {
|
||||
void Ident(SourceLocation Loc, StringRef str) override {
|
||||
First->Ident(Loc, str);
|
||||
Second->Ident(Loc, str);
|
||||
}
|
||||
|
||||
void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
|
||||
const std::string &Str) override {
|
||||
StringRef Str) override {
|
||||
First->PragmaComment(Loc, Kind, Str);
|
||||
Second->PragmaComment(Loc, Kind, Str);
|
||||
}
|
||||
|
||||
void PragmaDetectMismatch(SourceLocation Loc, const std::string &Name,
|
||||
const std::string &Value) override {
|
||||
void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
|
||||
StringRef Value) override {
|
||||
First->PragmaDetectMismatch(Loc, Name, Value);
|
||||
Second->PragmaDetectMismatch(Loc, Name, Value);
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ class PTHManager : public IdentifierInfoLookup {
|
||||
|
||||
/// Create - This method creates PTHManager objects. The 'file' argument
|
||||
/// is the name of the PTH file. This method returns NULL upon failure.
|
||||
static PTHManager *Create(const std::string& file, DiagnosticsEngine &Diags);
|
||||
static PTHManager *Create(StringRef file, DiagnosticsEngine &Diags);
|
||||
|
||||
void setPreprocessor(Preprocessor *pp) { PP = pp; }
|
||||
|
||||
|
@ -890,7 +890,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
|
||||
///
|
||||
/// These predefines are automatically injected when parsing the main file.
|
||||
void setPredefines(const char *P) { Predefines = P; }
|
||||
void setPredefines(const std::string &P) { Predefines = P; }
|
||||
void setPredefines(StringRef P) { Predefines = P; }
|
||||
|
||||
/// Return information about the specified preprocessor
|
||||
/// identifier token.
|
||||
@ -1617,9 +1617,9 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
|
||||
|
||||
void PushIncludeMacroStack() {
|
||||
assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer");
|
||||
IncludeMacroStack.push_back(IncludeStackInfo(
|
||||
IncludeMacroStack.emplace_back(
|
||||
CurLexerKind, CurSubmodule, std::move(CurLexer), std::move(CurPTHLexer),
|
||||
CurPPLexer, std::move(CurTokenLexer), CurDirLookup));
|
||||
CurPPLexer, std::move(CurTokenLexer), CurDirLookup);
|
||||
CurPPLexer = nullptr;
|
||||
}
|
||||
|
||||
|
@ -149,18 +149,14 @@ class PreprocessorOptions : public RefCountedBase<PreprocessorOptions> {
|
||||
RetainRemappedFileBuffers(false),
|
||||
ObjCXXARCStandardLibrary(ARCXX_nolib) { }
|
||||
|
||||
void addMacroDef(StringRef Name) {
|
||||
Macros.push_back(std::make_pair(Name, false));
|
||||
}
|
||||
void addMacroUndef(StringRef Name) {
|
||||
Macros.push_back(std::make_pair(Name, true));
|
||||
}
|
||||
void addMacroDef(StringRef Name) { Macros.emplace_back(Name, false); }
|
||||
void addMacroUndef(StringRef Name) { Macros.emplace_back(Name, true); }
|
||||
void addRemappedFile(StringRef From, StringRef To) {
|
||||
RemappedFiles.push_back(std::make_pair(From, To));
|
||||
RemappedFiles.emplace_back(From, To);
|
||||
}
|
||||
|
||||
void addRemappedFile(StringRef From, llvm::MemoryBuffer *To) {
|
||||
RemappedFileBuffers.push_back(std::make_pair(From, To));
|
||||
RemappedFileBuffers.emplace_back(From, To);
|
||||
}
|
||||
|
||||
void clearRemappedFiles() {
|
||||
|
@ -302,10 +302,14 @@ class LookupResult {
|
||||
if (!D->isInIdentifierNamespace(IDNS))
|
||||
return nullptr;
|
||||
|
||||
if (isHiddenDeclarationVisible() || isVisible(getSema(), D))
|
||||
if (isVisible(getSema(), D))
|
||||
return D;
|
||||
|
||||
return getAcceptableDeclSlow(D);
|
||||
if (auto *Visible = getAcceptableDeclSlow(D))
|
||||
return Visible;
|
||||
|
||||
// Even if hidden declarations are visible, prefer a visible declaration.
|
||||
return isHiddenDeclarationVisible() ? D : nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -5110,6 +5110,10 @@ class Sema {
|
||||
bool AnyErrors);
|
||||
|
||||
void checkClassLevelDLLAttribute(CXXRecordDecl *Class);
|
||||
void propagateDLLAttrToBaseClassTemplate(
|
||||
CXXRecordDecl *Class, Attr *ClassAttr,
|
||||
ClassTemplateSpecializationDecl *BaseTemplateSpec,
|
||||
SourceLocation BaseLoc);
|
||||
void CheckCompletedCXXClass(CXXRecordDecl *Record);
|
||||
void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
|
||||
Decl *TagDecl,
|
||||
|
@ -19,6 +19,7 @@
|
||||
#ifndef LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
|
||||
#define LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
|
||||
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <set>
|
||||
@ -77,22 +78,24 @@ class Replacement {
|
||||
/// \param FilePath A source file accessible via a SourceManager.
|
||||
/// \param Offset The byte offset of the start of the range in the file.
|
||||
/// \param Length The length of the range in bytes.
|
||||
Replacement(StringRef FilePath, unsigned Offset,
|
||||
unsigned Length, StringRef ReplacementText);
|
||||
Replacement(StringRef FilePath, unsigned Offset, unsigned Length,
|
||||
StringRef ReplacementText);
|
||||
|
||||
/// \brief Creates a Replacement of the range [Start, Start+Length) with
|
||||
/// ReplacementText.
|
||||
Replacement(const SourceManager &Sources, SourceLocation Start, unsigned Length,
|
||||
StringRef ReplacementText);
|
||||
Replacement(const SourceManager &Sources, SourceLocation Start,
|
||||
unsigned Length, StringRef ReplacementText);
|
||||
|
||||
/// \brief Creates a Replacement of the given range with ReplacementText.
|
||||
Replacement(const SourceManager &Sources, const CharSourceRange &Range,
|
||||
StringRef ReplacementText);
|
||||
StringRef ReplacementText,
|
||||
const LangOptions &LangOpts = LangOptions());
|
||||
|
||||
/// \brief Creates a Replacement of the node with ReplacementText.
|
||||
template <typename Node>
|
||||
Replacement(const SourceManager &Sources, const Node &NodeToReplace,
|
||||
StringRef ReplacementText);
|
||||
StringRef ReplacementText,
|
||||
const LangOptions &LangOpts = LangOptions());
|
||||
|
||||
/// \brief Returns whether this replacement can be applied to a file.
|
||||
///
|
||||
@ -114,11 +117,13 @@ class Replacement {
|
||||
std::string toString() const;
|
||||
|
||||
private:
|
||||
void setFromSourceLocation(const SourceManager &Sources, SourceLocation Start,
|
||||
unsigned Length, StringRef ReplacementText);
|
||||
void setFromSourceRange(const SourceManager &Sources,
|
||||
const CharSourceRange &Range,
|
||||
StringRef ReplacementText);
|
||||
void setFromSourceLocation(const SourceManager &Sources,
|
||||
SourceLocation Start, unsigned Length,
|
||||
StringRef ReplacementText);
|
||||
void setFromSourceRange(const SourceManager &Sources,
|
||||
const CharSourceRange &Range,
|
||||
StringRef ReplacementText,
|
||||
const LangOptions &LangOpts);
|
||||
|
||||
std::string FilePath;
|
||||
Range ReplacementRange;
|
||||
@ -217,10 +222,11 @@ std::string applyAllReplacements(StringRef Code, const Replacements &Replaces);
|
||||
|
||||
template <typename Node>
|
||||
Replacement::Replacement(const SourceManager &Sources,
|
||||
const Node &NodeToReplace, StringRef ReplacementText) {
|
||||
const Node &NodeToReplace, StringRef ReplacementText,
|
||||
const LangOptions &LangOpts) {
|
||||
const CharSourceRange Range =
|
||||
CharSourceRange::getTokenRange(NodeToReplace->getSourceRange());
|
||||
setFromSourceRange(Sources, Range, ReplacementText);
|
||||
setFromSourceRange(Sources, Range, ReplacementText, LangOpts);
|
||||
}
|
||||
|
||||
} // end namespace tooling
|
||||
|
@ -2283,7 +2283,7 @@ bool arcmt::getFileRemappingsFromFileList(
|
||||
continue;
|
||||
}
|
||||
|
||||
remap.push_back(std::make_pair(I->first->getName(), TempFile));
|
||||
remap.emplace_back(I->first->getName(), TempFile);
|
||||
}
|
||||
|
||||
return hasErrorOccurred;
|
||||
|
@ -80,6 +80,10 @@ Module *Decl::getOwningModuleSlow() const {
|
||||
return getASTContext().getExternalSource()->getModule(getOwningModuleID());
|
||||
}
|
||||
|
||||
bool Decl::hasLocalOwningModuleStorage() const {
|
||||
return getASTContext().getLangOpts().ModulesLocalVisibility;
|
||||
}
|
||||
|
||||
const char *Decl::getDeclKindName() const {
|
||||
switch (DeclKind) {
|
||||
default: llvm_unreachable("Declaration not in DeclNodes.inc!");
|
||||
|
@ -1315,6 +1315,28 @@ CXXDestructorDecl *CXXRecordDecl::getDestructor() const {
|
||||
return Dtor;
|
||||
}
|
||||
|
||||
bool CXXRecordDecl::isAnyDestructorNoReturn() const {
|
||||
// Destructor is noreturn.
|
||||
if (const CXXDestructorDecl *Destructor = getDestructor())
|
||||
if (Destructor->isNoReturn())
|
||||
return true;
|
||||
|
||||
// Check base classes destructor for noreturn.
|
||||
for (const auto &Base : bases())
|
||||
if (Base.getType()->getAsCXXRecordDecl()->isAnyDestructorNoReturn())
|
||||
return true;
|
||||
|
||||
// Check fields for noreturn.
|
||||
for (const auto *Field : fields())
|
||||
if (const CXXRecordDecl *RD =
|
||||
Field->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl())
|
||||
if (RD->isAnyDestructorNoReturn())
|
||||
return true;
|
||||
|
||||
// All destructors are not noreturn.
|
||||
return false;
|
||||
}
|
||||
|
||||
void CXXRecordDecl::completeDefinition() {
|
||||
completeDefinition(nullptr);
|
||||
}
|
||||
|
@ -733,8 +733,10 @@ void DeclPrinter::VisitImportDecl(ImportDecl *D) {
|
||||
void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) {
|
||||
Out << "static_assert(";
|
||||
D->getAssertExpr()->printPretty(Out, nullptr, Policy, Indentation);
|
||||
Out << ", ";
|
||||
D->getMessage()->printPretty(Out, nullptr, Policy, Indentation);
|
||||
if (StringLiteral *SL = D->getMessage()) {
|
||||
Out << ", ";
|
||||
SL->printPretty(Out, nullptr, Policy, Indentation);
|
||||
}
|
||||
Out << ")";
|
||||
}
|
||||
|
||||
|
@ -4276,6 +4276,9 @@ class ExprEvaluatorBase
|
||||
|
||||
BlockScopeRAII Scope(Info);
|
||||
const CompoundStmt *CS = E->getSubStmt();
|
||||
if (CS->body_empty())
|
||||
return true;
|
||||
|
||||
for (CompoundStmt::const_body_iterator BI = CS->body_begin(),
|
||||
BE = CS->body_end();
|
||||
/**/; ++BI) {
|
||||
@ -4301,6 +4304,8 @@ class ExprEvaluatorBase
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
llvm_unreachable("Return from function from the loop above.");
|
||||
}
|
||||
|
||||
/// Visit a value which is evaluated, but whose value is ignored.
|
||||
|
@ -2021,23 +2021,29 @@ void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals,
|
||||
uint64_t Width = getASTContext().getTypeSize(T);
|
||||
// Pattern match exactly the typedefs in our intrinsic headers. Anything that
|
||||
// doesn't match the Intel types uses a custom mangling below.
|
||||
bool IntelVector = true;
|
||||
if (Width == 64 && ET->getKind() == BuiltinType::LongLong) {
|
||||
Out << "T__m64";
|
||||
} else if (Width == 128 || Width == 256) {
|
||||
if (ET->getKind() == BuiltinType::Float)
|
||||
Out << "T__m" << Width;
|
||||
else if (ET->getKind() == BuiltinType::LongLong)
|
||||
Out << "T__m" << Width << 'i';
|
||||
else if (ET->getKind() == BuiltinType::Double)
|
||||
Out << "U__m" << Width << 'd';
|
||||
else
|
||||
IntelVector = false;
|
||||
bool IsBuiltin = true;
|
||||
llvm::Triple::ArchType AT =
|
||||
getASTContext().getTargetInfo().getTriple().getArch();
|
||||
if (AT == llvm::Triple::x86 || AT == llvm::Triple::x86_64) {
|
||||
if (Width == 64 && ET->getKind() == BuiltinType::LongLong) {
|
||||
Out << "T__m64";
|
||||
} else if (Width >= 128) {
|
||||
if (ET->getKind() == BuiltinType::Float)
|
||||
Out << "T__m" << Width;
|
||||
else if (ET->getKind() == BuiltinType::LongLong)
|
||||
Out << "T__m" << Width << 'i';
|
||||
else if (ET->getKind() == BuiltinType::Double)
|
||||
Out << "U__m" << Width << 'd';
|
||||
else
|
||||
IsBuiltin = false;
|
||||
} else {
|
||||
IsBuiltin = false;
|
||||
}
|
||||
} else {
|
||||
IntelVector = false;
|
||||
IsBuiltin = false;
|
||||
}
|
||||
|
||||
if (!IntelVector) {
|
||||
if (!IsBuiltin) {
|
||||
// The MS ABI doesn't have a special mangling for vector types, so we define
|
||||
// our own mangling to handle uses of __vector_size__ on user-specified
|
||||
// types, and for extensions like __v4sf.
|
||||
|
@ -592,7 +592,7 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
|
||||
SourceLocation EndLoc =
|
||||
getAsmString()->getLocationOfByte(CurPtr - StrStart, SM, LO, TI);
|
||||
|
||||
Pieces.push_back(AsmStringPiece(N, Str, BeginLoc, EndLoc));
|
||||
Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -626,7 +626,7 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
|
||||
SourceLocation EndLoc =
|
||||
getAsmString()->getLocationOfByte(NameEnd + 1 - StrStart, SM, LO, TI);
|
||||
|
||||
Pieces.push_back(AsmStringPiece(N, Str, BeginLoc, EndLoc));
|
||||
Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
|
||||
|
||||
CurPtr = NameEnd+1;
|
||||
continue;
|
||||
|
@ -396,8 +396,9 @@ void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) {
|
||||
}
|
||||
|
||||
VisitStringLiteral(Node->getOutputConstraintLiteral(i));
|
||||
OS << " ";
|
||||
OS << " (";
|
||||
Visit(Node->getOutputExpr(i));
|
||||
OS << ")";
|
||||
}
|
||||
|
||||
// Inputs
|
||||
@ -415,8 +416,9 @@ void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) {
|
||||
}
|
||||
|
||||
VisitStringLiteral(Node->getInputConstraintLiteral(i));
|
||||
OS << " ";
|
||||
OS << " (";
|
||||
Visit(Node->getInputExpr(i));
|
||||
OS << ")";
|
||||
}
|
||||
|
||||
// Clobbers
|
||||
@ -1395,13 +1397,16 @@ void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
|
||||
bool NeedsEquals = true;
|
||||
for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(),
|
||||
DEnd = Node->designators_end();
|
||||
D != DEnd; ++D) {
|
||||
if (D->isFieldDesignator()) {
|
||||
if (D->getDotLoc().isInvalid()) {
|
||||
if (IdentifierInfo *II = D->getFieldName())
|
||||
if (IdentifierInfo *II = D->getFieldName()) {
|
||||
OS << II->getName() << ":";
|
||||
NeedsEquals = false;
|
||||
}
|
||||
} else {
|
||||
OS << "." << D->getFieldName()->getName();
|
||||
}
|
||||
@ -1418,7 +1423,10 @@ void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
|
||||
}
|
||||
}
|
||||
|
||||
OS << " = ";
|
||||
if (NeedsEquals)
|
||||
OS << " = ";
|
||||
else
|
||||
OS << " ";
|
||||
PrintExpr(Node->getInit());
|
||||
}
|
||||
|
||||
|
@ -912,37 +912,37 @@ MatchFinder::~MatchFinder() {}
|
||||
|
||||
void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch,
|
||||
MatchCallback *Action) {
|
||||
Matchers.DeclOrStmt.push_back(std::make_pair(NodeMatch, Action));
|
||||
Matchers.DeclOrStmt.emplace_back(NodeMatch, Action);
|
||||
Matchers.AllCallbacks.push_back(Action);
|
||||
}
|
||||
|
||||
void MatchFinder::addMatcher(const TypeMatcher &NodeMatch,
|
||||
MatchCallback *Action) {
|
||||
Matchers.Type.push_back(std::make_pair(NodeMatch, Action));
|
||||
Matchers.Type.emplace_back(NodeMatch, Action);
|
||||
Matchers.AllCallbacks.push_back(Action);
|
||||
}
|
||||
|
||||
void MatchFinder::addMatcher(const StatementMatcher &NodeMatch,
|
||||
MatchCallback *Action) {
|
||||
Matchers.DeclOrStmt.push_back(std::make_pair(NodeMatch, Action));
|
||||
Matchers.DeclOrStmt.emplace_back(NodeMatch, Action);
|
||||
Matchers.AllCallbacks.push_back(Action);
|
||||
}
|
||||
|
||||
void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
|
||||
MatchCallback *Action) {
|
||||
Matchers.NestedNameSpecifier.push_back(std::make_pair(NodeMatch, Action));
|
||||
Matchers.NestedNameSpecifier.emplace_back(NodeMatch, Action);
|
||||
Matchers.AllCallbacks.push_back(Action);
|
||||
}
|
||||
|
||||
void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
|
||||
MatchCallback *Action) {
|
||||
Matchers.NestedNameSpecifierLoc.push_back(std::make_pair(NodeMatch, Action));
|
||||
Matchers.NestedNameSpecifierLoc.emplace_back(NodeMatch, Action);
|
||||
Matchers.AllCallbacks.push_back(Action);
|
||||
}
|
||||
|
||||
void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch,
|
||||
MatchCallback *Action) {
|
||||
Matchers.TypeLoc.push_back(std::make_pair(NodeMatch, Action));
|
||||
Matchers.TypeLoc.emplace_back(NodeMatch, Action);
|
||||
Matchers.AllCallbacks.push_back(Action);
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ namespace ast_matchers {
|
||||
namespace dynamic {
|
||||
Diagnostics::ArgStream Diagnostics::pushContextFrame(ContextType Type,
|
||||
SourceRange Range) {
|
||||
ContextStack.push_back(ContextFrame());
|
||||
ContextStack.emplace_back();
|
||||
ContextFrame& data = ContextStack.back();
|
||||
data.Type = Type;
|
||||
data.Range = Range;
|
||||
@ -65,10 +65,10 @@ Diagnostics::ArgStream &Diagnostics::ArgStream::operator<<(const Twine &Arg) {
|
||||
|
||||
Diagnostics::ArgStream Diagnostics::addError(const SourceRange &Range,
|
||||
ErrorType Error) {
|
||||
Errors.push_back(ErrorContent());
|
||||
Errors.emplace_back();
|
||||
ErrorContent &Last = Errors.back();
|
||||
Last.ContextStack = ContextStack;
|
||||
Last.Messages.push_back(ErrorContent::Message());
|
||||
Last.Messages.emplace_back();
|
||||
Last.Messages.back().Range = Range;
|
||||
Last.Messages.back().Type = Error;
|
||||
return ArgStream(&Last.Messages.back().Args);
|
||||
|
@ -311,6 +311,7 @@ RegistryMaps::RegistryMaps() {
|
||||
REGISTER_MATCHER(specifiesTypeLoc);
|
||||
REGISTER_MATCHER(statementCountIs);
|
||||
REGISTER_MATCHER(staticCastExpr);
|
||||
REGISTER_MATCHER(staticAssertDecl);
|
||||
REGISTER_MATCHER(stmt);
|
||||
REGISTER_MATCHER(stringLiteral);
|
||||
REGISTER_MATCHER(substNonTypeTemplateParmExpr);
|
||||
|
@ -1095,6 +1095,19 @@ CFGBlock *CFGBuilder::addInitializer(CXXCtorInitializer *I) {
|
||||
// generating destructors for the second time.
|
||||
return Visit(cast<ExprWithCleanups>(Init)->getSubExpr());
|
||||
}
|
||||
if (BuildOpts.AddCXXDefaultInitExprInCtors) {
|
||||
if (CXXDefaultInitExpr *Default = dyn_cast<CXXDefaultInitExpr>(Init)) {
|
||||
// In general, appending the expression wrapped by a CXXDefaultInitExpr
|
||||
// may cause the same Expr to appear more than once in the CFG. Doing it
|
||||
// here is safe because there's only one initializer per field.
|
||||
autoCreateBlock();
|
||||
appendStmt(Block, Default);
|
||||
if (Stmt *Child = Default->getExpr())
|
||||
if (CFGBlock *R = Visit(Child))
|
||||
Block = R;
|
||||
return Block;
|
||||
}
|
||||
}
|
||||
return Visit(Init);
|
||||
}
|
||||
|
||||
@ -1179,8 +1192,7 @@ void CFGBuilder::addAutomaticObjDtors(LocalScope::const_iterator B,
|
||||
}
|
||||
Ty = Context->getBaseElementType(Ty);
|
||||
|
||||
const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor();
|
||||
if (Dtor->isNoReturn())
|
||||
if (Ty->getAsCXXRecordDecl()->isAnyDestructorNoReturn())
|
||||
Block = createNoReturnBlock();
|
||||
else
|
||||
autoCreateBlock();
|
||||
@ -3682,7 +3694,7 @@ CFGBlock *CFGBuilder::VisitCXXBindTemporaryExprForTemporaryDtors(
|
||||
|
||||
const CXXDestructorDecl *Dtor = E->getTemporary()->getDestructor();
|
||||
|
||||
if (Dtor->isNoReturn()) {
|
||||
if (Dtor->getParent()->isAnyDestructorNoReturn()) {
|
||||
// If the destructor is marked as a no-return destructor, we need to
|
||||
// create a new block for the destructor which does not have as a
|
||||
// successor anything built thus far. Control won't flow out of this
|
||||
|
@ -112,7 +112,7 @@ void DiagnosticsEngine::Reset() {
|
||||
|
||||
// Create a DiagState and DiagStatePoint representing diagnostic changes
|
||||
// through command-line.
|
||||
DiagStates.push_back(DiagState());
|
||||
DiagStates.emplace_back();
|
||||
DiagStatePoints.push_back(DiagStatePoint(&DiagStates.back(), FullSourceLoc()));
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,8 @@ namespace {
|
||||
KEYNOOPENCL = 0x02000,
|
||||
WCHARSUPPORT = 0x04000,
|
||||
HALFSUPPORT = 0x08000,
|
||||
KEYALL = (0xffff & ~KEYNOMS18 &
|
||||
KEYCONCEPTS = 0x10000,
|
||||
KEYALL = (0x1ffff & ~KEYNOMS18 &
|
||||
~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude.
|
||||
};
|
||||
|
||||
@ -143,6 +144,7 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts,
|
||||
// We treat bridge casts as objective-C keywords so we can warn on them
|
||||
// in non-arc mode.
|
||||
if (LangOpts.ObjC2 && (Flags & KEYARC)) return KS_Enabled;
|
||||
if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS)) return KS_Enabled;
|
||||
if (LangOpts.CPlusPlus && (Flags & KEYCXX11)) return KS_Future;
|
||||
return KS_Disabled;
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ const char *FullSourceLoc::getCharacterData(bool *Invalid) const {
|
||||
|
||||
StringRef FullSourceLoc::getBufferData(bool *Invalid) const {
|
||||
assert(isValid());
|
||||
return SrcMgr->getBuffer(SrcMgr->getFileID(*this), Invalid)->getBuffer();;
|
||||
return SrcMgr->getBuffer(SrcMgr->getFileID(*this), Invalid)->getBuffer();
|
||||
}
|
||||
|
||||
std::pair<FileID, unsigned> FullSourceLoc::getDecomposedLoc() const {
|
||||
|
@ -389,7 +389,7 @@ class LinuxTargetInfo : public OSTargetInfo<Target> {
|
||||
if (Triple.getEnvironment() == llvm::Triple::Android) {
|
||||
Builder.defineMacro("__ANDROID__", "1");
|
||||
unsigned Maj, Min, Rev;
|
||||
Triple.getOSVersion(Maj, Min, Rev);
|
||||
Triple.getEnvironmentVersion(Maj, Min, Rev);
|
||||
this->PlatformName = "android";
|
||||
this->PlatformMinVersion = VersionTuple(Maj, Min, Rev);
|
||||
}
|
||||
@ -3596,11 +3596,8 @@ class MicrosoftX86_32TargetInfo : public WindowsX86_32TargetInfo {
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
static void addMinGWDefines(const LangOptions &Opts, MacroBuilder &Builder) {
|
||||
Builder.defineMacro("__MSVCRT__");
|
||||
Builder.defineMacro("__MINGW32__");
|
||||
|
||||
// Mingw defines __declspec(a) to __attribute__((a)). Clang supports
|
||||
static void addCygMingDefines(const LangOptions &Opts, MacroBuilder &Builder) {
|
||||
// Mingw and cygwin define __declspec(a) to __attribute__((a)). Clang supports
|
||||
// __declspec natively under -fms-extensions, but we define a no-op __declspec
|
||||
// macro anyway for pre-processor compatibility.
|
||||
if (Opts.MicrosoftExt)
|
||||
@ -3623,6 +3620,12 @@ static void addMinGWDefines(const LangOptions &Opts, MacroBuilder &Builder) {
|
||||
}
|
||||
}
|
||||
|
||||
static void addMinGWDefines(const LangOptions &Opts, MacroBuilder &Builder) {
|
||||
Builder.defineMacro("__MSVCRT__");
|
||||
Builder.defineMacro("__MINGW32__");
|
||||
addCygMingDefines(Opts, Builder);
|
||||
}
|
||||
|
||||
namespace {
|
||||
// x86-32 MinGW target
|
||||
class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
|
||||
@ -3655,6 +3658,7 @@ class CygwinX86_32TargetInfo : public X86_32TargetInfo {
|
||||
Builder.defineMacro("_X86_");
|
||||
Builder.defineMacro("__CYGWIN__");
|
||||
Builder.defineMacro("__CYGWIN32__");
|
||||
addCygMingDefines(Opts, Builder);
|
||||
DefineStd(Builder, "unix", Opts);
|
||||
if (Opts.CPlusPlus)
|
||||
Builder.defineMacro("_GNU_SOURCE");
|
||||
@ -4184,9 +4188,7 @@ class ARMTargetInfo : public TargetInfo {
|
||||
// FIXME: This should be based on Arch attributes, not CPU names.
|
||||
void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
|
||||
StringRef ArchName = getTriple().getArchName();
|
||||
unsigned ArchKind =
|
||||
llvm::ARMTargetParser::parseArch(
|
||||
llvm::ARMTargetParser::getCanonicalArchName(ArchName));
|
||||
unsigned ArchKind = llvm::ARMTargetParser::parseArch(ArchName);
|
||||
bool IsV8 = (ArchKind == llvm::ARM::AK_ARMV8A ||
|
||||
ArchKind == llvm::ARM::AK_ARMV8_1A);
|
||||
|
||||
@ -4293,9 +4295,7 @@ class ARMTargetInfo : public TargetInfo {
|
||||
.Case("hwdiv-arm", HWDiv & HWDivARM)
|
||||
.Default(false);
|
||||
}
|
||||
// FIXME: Should we actually have some table instead of these switches?
|
||||
const char *getCPUDefineSuffix(StringRef Name) const {
|
||||
// FIXME: Use ARMTargetParser
|
||||
if(Name == "generic") {
|
||||
auto subarch = getTriple().getSubArch();
|
||||
switch (subarch) {
|
||||
@ -4306,34 +4306,33 @@ class ARMTargetInfo : public TargetInfo {
|
||||
}
|
||||
}
|
||||
|
||||
return llvm::StringSwitch<const char *>(Name)
|
||||
.Cases("arm8", "arm810", "4")
|
||||
.Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110",
|
||||
"4")
|
||||
.Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
|
||||
.Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
|
||||
.Case("ep9312", "4T")
|
||||
.Cases("arm10tdmi", "arm1020t", "5T")
|
||||
.Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
|
||||
.Case("arm926ej-s", "5TEJ")
|
||||
.Cases("arm10e", "arm1020e", "arm1022e", "5TE")
|
||||
.Cases("xscale", "iwmmxt", "5TE")
|
||||
.Case("arm1136j-s", "6J")
|
||||
.Case("arm1136jf-s", "6")
|
||||
.Cases("mpcorenovfp", "mpcore", "6K")
|
||||
.Cases("arm1176jz-s", "arm1176jzf-s", "6K")
|
||||
.Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
|
||||
.Cases("cortex-a5", "cortex-a7", "cortex-a8", "7A")
|
||||
.Cases("cortex-a9", "cortex-a12", "cortex-a15", "cortex-a17", "krait",
|
||||
"7A")
|
||||
.Cases("cortex-r4", "cortex-r4f", "cortex-r5", "cortex-r7", "7R")
|
||||
.Case("swift", "7S")
|
||||
.Case("cyclone", "8A")
|
||||
.Cases("sc300", "cortex-m3", "7M")
|
||||
.Cases("cortex-m4", "cortex-m7", "7EM")
|
||||
.Cases("sc000", "cortex-m0", "cortex-m0plus", "cortex-m1", "6M")
|
||||
.Cases("cortex-a53", "cortex-a57", "cortex-a72", "8A")
|
||||
.Default(nullptr);
|
||||
unsigned ArchKind = llvm::ARMTargetParser::parseCPUArch(Name);
|
||||
if (ArchKind == llvm::ARM::AK_INVALID)
|
||||
return "";
|
||||
|
||||
// For most sub-arches, the build attribute CPU name is enough.
|
||||
// For Cortex variants, it's slightly different.
|
||||
switch(ArchKind) {
|
||||
default:
|
||||
return llvm::ARMTargetParser::getCPUAttr(ArchKind);
|
||||
case llvm::ARM::AK_ARMV6M:
|
||||
case llvm::ARM::AK_ARMV6SM:
|
||||
return "6M";
|
||||
case llvm::ARM::AK_ARMV7:
|
||||
case llvm::ARM::AK_ARMV7A:
|
||||
case llvm::ARM::AK_ARMV7S:
|
||||
return "7A";
|
||||
case llvm::ARM::AK_ARMV7R:
|
||||
return "7R";
|
||||
case llvm::ARM::AK_ARMV7M:
|
||||
return "7M";
|
||||
case llvm::ARM::AK_ARMV7EM:
|
||||
return "7EM";
|
||||
case llvm::ARM::AK_ARMV8A:
|
||||
return "8A";
|
||||
case llvm::ARM::AK_ARMV8_1A:
|
||||
return "8_1A";
|
||||
}
|
||||
}
|
||||
const char *getCPUProfile(StringRef Name) const {
|
||||
if(Name == "generic") {
|
||||
@ -5500,6 +5499,16 @@ class SparcV8TargetInfo : public SparcTargetInfo {
|
||||
public:
|
||||
SparcV8TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) {
|
||||
DescriptionString = "E-m:e-p:32:32-i64:64-f128:64-n32-S64";
|
||||
// NetBSD uses long (same as llvm default); everyone else uses int.
|
||||
if (getTriple().getOS() == llvm::Triple::NetBSD) {
|
||||
SizeType = UnsignedLong;
|
||||
IntPtrType = SignedLong;
|
||||
PtrDiffType = SignedLong;
|
||||
} else {
|
||||
SizeType = UnsignedInt;
|
||||
IntPtrType = SignedInt;
|
||||
PtrDiffType = SignedInt;
|
||||
}
|
||||
}
|
||||
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
@ -5572,15 +5581,6 @@ class SparcV9TargetInfo : public SparcTargetInfo {
|
||||
}
|
||||
};
|
||||
|
||||
class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
|
||||
public:
|
||||
SolarisSparcV8TargetInfo(const llvm::Triple &Triple)
|
||||
: SolarisTargetInfo<SparcV8TargetInfo>(Triple) {
|
||||
SizeType = UnsignedInt;
|
||||
PtrDiffType = SignedInt;
|
||||
}
|
||||
};
|
||||
|
||||
class SystemZTargetInfo : public TargetInfo {
|
||||
static const Builtin::Info BuiltinInfo[];
|
||||
static const char *const GCCRegNames[];
|
||||
@ -7022,7 +7022,7 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
|
||||
case llvm::Triple::Linux:
|
||||
return new LinuxTargetInfo<SparcV8TargetInfo>(Triple);
|
||||
case llvm::Triple::Solaris:
|
||||
return new SolarisSparcV8TargetInfo(Triple);
|
||||
return new SolarisTargetInfo<SparcV8TargetInfo>(Triple);
|
||||
case llvm::Triple::NetBSD:
|
||||
return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple);
|
||||
case llvm::Triple::OpenBSD:
|
||||
|
@ -453,10 +453,8 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
|
||||
std::string FeaturesStr;
|
||||
if (!TargetOpts.Features.empty()) {
|
||||
SubtargetFeatures Features;
|
||||
for (std::vector<std::string>::const_iterator
|
||||
it = TargetOpts.Features.begin(),
|
||||
ie = TargetOpts.Features.end(); it != ie; ++it)
|
||||
Features.AddFeature(*it);
|
||||
for (const std::string &Feature : TargetOpts.Features)
|
||||
Features.AddFeature(Feature);
|
||||
FeaturesStr = Features.getString();
|
||||
}
|
||||
|
||||
@ -624,10 +622,9 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
|
||||
PrettyStackTraceString CrashInfo("Per-function optimization");
|
||||
|
||||
PerFunctionPasses->doInitialization();
|
||||
for (Module::iterator I = TheModule->begin(),
|
||||
E = TheModule->end(); I != E; ++I)
|
||||
if (!I->isDeclaration())
|
||||
PerFunctionPasses->run(*I);
|
||||
for (Function &F : *TheModule)
|
||||
if (!F.isDeclaration())
|
||||
PerFunctionPasses->run(F);
|
||||
PerFunctionPasses->doFinalization();
|
||||
}
|
||||
|
||||
|
@ -698,6 +698,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
||||
std::pair<llvm::Value*, unsigned> Dest =
|
||||
EmitPointerWithAlignment(E->getArg(0));
|
||||
Value *SizeVal = EmitScalarExpr(E->getArg(1));
|
||||
EmitNonNullArgCheck(RValue::get(Dest.first), E->getArg(0)->getType(),
|
||||
E->getArg(0)->getExprLoc(), FD, 0);
|
||||
Builder.CreateMemSet(Dest.first, Builder.getInt8(0), SizeVal,
|
||||
Dest.second, false);
|
||||
return RValue::get(Dest.first);
|
||||
@ -710,6 +712,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
||||
EmitPointerWithAlignment(E->getArg(1));
|
||||
Value *SizeVal = EmitScalarExpr(E->getArg(2));
|
||||
unsigned Align = std::min(Dest.second, Src.second);
|
||||
EmitNonNullArgCheck(RValue::get(Dest.first), E->getArg(0)->getType(),
|
||||
E->getArg(0)->getExprLoc(), FD, 0);
|
||||
EmitNonNullArgCheck(RValue::get(Src.first), E->getArg(1)->getType(),
|
||||
E->getArg(1)->getExprLoc(), FD, 1);
|
||||
Builder.CreateMemCpy(Dest.first, Src.first, SizeVal, Align, false);
|
||||
return RValue::get(Dest.first);
|
||||
}
|
||||
@ -767,6 +773,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
||||
EmitPointerWithAlignment(E->getArg(1));
|
||||
Value *SizeVal = EmitScalarExpr(E->getArg(2));
|
||||
unsigned Align = std::min(Dest.second, Src.second);
|
||||
EmitNonNullArgCheck(RValue::get(Dest.first), E->getArg(0)->getType(),
|
||||
E->getArg(0)->getExprLoc(), FD, 0);
|
||||
EmitNonNullArgCheck(RValue::get(Src.first), E->getArg(1)->getType(),
|
||||
E->getArg(1)->getExprLoc(), FD, 1);
|
||||
Builder.CreateMemMove(Dest.first, Src.first, SizeVal, Align, false);
|
||||
return RValue::get(Dest.first);
|
||||
}
|
||||
@ -777,6 +787,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
||||
Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
|
||||
Builder.getInt8Ty());
|
||||
Value *SizeVal = EmitScalarExpr(E->getArg(2));
|
||||
EmitNonNullArgCheck(RValue::get(Dest.first), E->getArg(0)->getType(),
|
||||
E->getArg(0)->getExprLoc(), FD, 0);
|
||||
Builder.CreateMemSet(Dest.first, ByteVal, SizeVal, Dest.second, false);
|
||||
return RValue::get(Dest.first);
|
||||
}
|
||||
@ -3479,6 +3491,13 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
|
||||
}
|
||||
}
|
||||
|
||||
// Find out if any arguments are required to be integer constant
|
||||
// expressions.
|
||||
unsigned ICEArguments = 0;
|
||||
ASTContext::GetBuiltinTypeError Error;
|
||||
getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
|
||||
assert(Error == ASTContext::GE_None && "Should not codegen an error");
|
||||
|
||||
SmallVector<Value*, 4> Ops;
|
||||
llvm::Value *Align = nullptr;
|
||||
for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) {
|
||||
@ -3541,7 +3560,17 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Ops.push_back(EmitScalarExpr(E->getArg(i)));
|
||||
|
||||
if ((ICEArguments & (1 << i)) == 0) {
|
||||
Ops.push_back(EmitScalarExpr(E->getArg(i)));
|
||||
} else {
|
||||
// If this is required to be a constant, constant fold it so that we know
|
||||
// that the generated intrinsic gets a ConstantInt.
|
||||
llvm::APSInt Result;
|
||||
bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
|
||||
assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst;
|
||||
Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
|
||||
}
|
||||
}
|
||||
|
||||
switch (BuiltinID) {
|
||||
@ -4001,38 +4030,6 @@ Value *CodeGenFunction::vectorWrapScalar8(Value *Op) {
|
||||
return Op;
|
||||
}
|
||||
|
||||
Value *CodeGenFunction::
|
||||
emitVectorWrappedScalar8Intrinsic(unsigned Int, SmallVectorImpl<Value*> &Ops,
|
||||
const char *Name) {
|
||||
// i8 is not a legal types for AArch64, so we can't just use
|
||||
// a normal overloaded intrinsic call for these scalar types. Instead
|
||||
// we'll build 64-bit vectors w/ lane zero being our input values and
|
||||
// perform the operation on that. The back end can pattern match directly
|
||||
// to the scalar instruction.
|
||||
Ops[0] = vectorWrapScalar8(Ops[0]);
|
||||
Ops[1] = vectorWrapScalar8(Ops[1]);
|
||||
llvm::Type *VTy = llvm::VectorType::get(Int8Ty, 8);
|
||||
Value *V = EmitNeonCall(CGM.getIntrinsic(Int, VTy), Ops, Name);
|
||||
Constant *CI = ConstantInt::get(SizeTy, 0);
|
||||
return Builder.CreateExtractElement(V, CI, "lane0");
|
||||
}
|
||||
|
||||
Value *CodeGenFunction::
|
||||
emitVectorWrappedScalar16Intrinsic(unsigned Int, SmallVectorImpl<Value*> &Ops,
|
||||
const char *Name) {
|
||||
// i16 is not a legal types for AArch64, so we can't just use
|
||||
// a normal overloaded intrinsic call for these scalar types. Instead
|
||||
// we'll build 64-bit vectors w/ lane zero being our input values and
|
||||
// perform the operation on that. The back end can pattern match directly
|
||||
// to the scalar instruction.
|
||||
Ops[0] = vectorWrapScalar16(Ops[0]);
|
||||
Ops[1] = vectorWrapScalar16(Ops[1]);
|
||||
llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4);
|
||||
Value *V = EmitNeonCall(CGM.getIntrinsic(Int, VTy), Ops, Name);
|
||||
Constant *CI = ConstantInt::get(SizeTy, 0);
|
||||
return Builder.CreateExtractElement(V, CI, "lane0");
|
||||
}
|
||||
|
||||
Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
|
||||
const CallExpr *E) {
|
||||
unsigned HintID = static_cast<unsigned>(-1);
|
||||
@ -4242,9 +4239,27 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
|
||||
return Builder.CreateCall(F, {Arg0, Arg1});
|
||||
}
|
||||
|
||||
// Find out if any arguments are required to be integer constant
|
||||
// expressions.
|
||||
unsigned ICEArguments = 0;
|
||||
ASTContext::GetBuiltinTypeError Error;
|
||||
getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
|
||||
assert(Error == ASTContext::GE_None && "Should not codegen an error");
|
||||
|
||||
llvm::SmallVector<Value*, 4> Ops;
|
||||
for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++)
|
||||
Ops.push_back(EmitScalarExpr(E->getArg(i)));
|
||||
for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) {
|
||||
if ((ICEArguments & (1 << i)) == 0) {
|
||||
Ops.push_back(EmitScalarExpr(E->getArg(i)));
|
||||
} else {
|
||||
// If this is required to be a constant, constant fold it so that we know
|
||||
// that the generated intrinsic gets a ConstantInt.
|
||||
llvm::APSInt Result;
|
||||
bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
|
||||
assert(IsConst && "Constant arg isn't actually constant?");
|
||||
(void)IsConst;
|
||||
Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
|
||||
}
|
||||
}
|
||||
|
||||
auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap);
|
||||
const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
|
||||
|
@ -218,6 +218,8 @@ llvm::Function *CodeGenModule::codegenCXXStructor(const CXXMethodDecl *MD,
|
||||
}
|
||||
|
||||
setFunctionLinkage(GD, Fn);
|
||||
setFunctionDLLStorageClass(GD, Fn);
|
||||
|
||||
CodeGenFunction(*this).GenerateCode(GD, Fn, FnInfo);
|
||||
setFunctionDefinitionAttributes(MD, Fn);
|
||||
SetLLVMFunctionAttributesForDefinition(MD, Fn);
|
||||
|
@ -2719,27 +2719,28 @@ void CallArgList::freeArgumentMemory(CodeGenFunction &CGF) const {
|
||||
}
|
||||
}
|
||||
|
||||
static void emitNonNullArgCheck(CodeGenFunction &CGF, RValue RV,
|
||||
QualType ArgType, SourceLocation ArgLoc,
|
||||
const FunctionDecl *FD, unsigned ParmNum) {
|
||||
if (!CGF.SanOpts.has(SanitizerKind::NonnullAttribute) || !FD)
|
||||
void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
|
||||
SourceLocation ArgLoc,
|
||||
const FunctionDecl *FD,
|
||||
unsigned ParmNum) {
|
||||
if (!SanOpts.has(SanitizerKind::NonnullAttribute) || !FD)
|
||||
return;
|
||||
auto PVD = ParmNum < FD->getNumParams() ? FD->getParamDecl(ParmNum) : nullptr;
|
||||
unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum;
|
||||
auto NNAttr = getNonNullAttr(FD, PVD, ArgType, ArgNo);
|
||||
if (!NNAttr)
|
||||
return;
|
||||
CodeGenFunction::SanitizerScope SanScope(&CGF);
|
||||
SanitizerScope SanScope(this);
|
||||
assert(RV.isScalar());
|
||||
llvm::Value *V = RV.getScalarVal();
|
||||
llvm::Value *Cond =
|
||||
CGF.Builder.CreateICmpNE(V, llvm::Constant::getNullValue(V->getType()));
|
||||
Builder.CreateICmpNE(V, llvm::Constant::getNullValue(V->getType()));
|
||||
llvm::Constant *StaticData[] = {
|
||||
CGF.EmitCheckSourceLocation(ArgLoc),
|
||||
CGF.EmitCheckSourceLocation(NNAttr->getLocation()),
|
||||
llvm::ConstantInt::get(CGF.Int32Ty, ArgNo + 1),
|
||||
EmitCheckSourceLocation(ArgLoc),
|
||||
EmitCheckSourceLocation(NNAttr->getLocation()),
|
||||
llvm::ConstantInt::get(Int32Ty, ArgNo + 1),
|
||||
};
|
||||
CGF.EmitCheck(std::make_pair(Cond, SanitizerKind::NonnullAttribute),
|
||||
EmitCheck(std::make_pair(Cond, SanitizerKind::NonnullAttribute),
|
||||
"nonnull_arg", StaticData, None);
|
||||
}
|
||||
|
||||
@ -2767,7 +2768,7 @@ void CodeGenFunction::EmitCallArgs(CallArgList &Args,
|
||||
for (int I = ArgTypes.size() - 1; I >= 0; --I) {
|
||||
CallExpr::const_arg_iterator Arg = ArgBeg + I;
|
||||
EmitCallArg(Args, *Arg, ArgTypes[I]);
|
||||
emitNonNullArgCheck(*this, Args.back().RV, ArgTypes[I], Arg->getExprLoc(),
|
||||
EmitNonNullArgCheck(Args.back().RV, ArgTypes[I], Arg->getExprLoc(),
|
||||
CalleeDecl, ParamsToSkip + I);
|
||||
}
|
||||
|
||||
@ -2781,7 +2782,7 @@ void CodeGenFunction::EmitCallArgs(CallArgList &Args,
|
||||
CallExpr::const_arg_iterator Arg = ArgBeg + I;
|
||||
assert(Arg != ArgEnd);
|
||||
EmitCallArg(Args, *Arg, ArgTypes[I]);
|
||||
emitNonNullArgCheck(*this, Args.back().RV, ArgTypes[I], Arg->getExprLoc(),
|
||||
EmitNonNullArgCheck(Args.back().RV, ArgTypes[I], Arg->getExprLoc(),
|
||||
CalleeDecl, ParamsToSkip + I);
|
||||
}
|
||||
}
|
||||
@ -3081,10 +3082,18 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
|
||||
// If the call returns a temporary with struct return, create a temporary
|
||||
// alloca to hold the result, unless one is given to us.
|
||||
llvm::Value *SRetPtr = nullptr;
|
||||
size_t UnusedReturnSize = 0;
|
||||
if (RetAI.isIndirect() || RetAI.isInAlloca()) {
|
||||
SRetPtr = ReturnValue.getValue();
|
||||
if (!SRetPtr)
|
||||
if (!SRetPtr) {
|
||||
SRetPtr = CreateMemTemp(RetTy);
|
||||
if (HaveInsertPoint() && ReturnValue.isUnused()) {
|
||||
uint64_t size =
|
||||
CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(RetTy));
|
||||
if (EmitLifetimeStart(size, SRetPtr))
|
||||
UnusedReturnSize = size;
|
||||
}
|
||||
}
|
||||
if (IRFunctionArgs.hasSRetArg()) {
|
||||
IRCallArgs[IRFunctionArgs.getSRetArgNo()] = SRetPtr;
|
||||
} else {
|
||||
@ -3416,6 +3425,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
|
||||
// insertion point; this allows the rest of IRgen to discard
|
||||
// unreachable code.
|
||||
if (CS.doesNotReturn()) {
|
||||
if (UnusedReturnSize)
|
||||
EmitLifetimeEnd(llvm::ConstantInt::get(Int64Ty, UnusedReturnSize),
|
||||
SRetPtr);
|
||||
|
||||
Builder.CreateUnreachable();
|
||||
Builder.ClearInsertionPoint();
|
||||
|
||||
@ -3444,8 +3457,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
|
||||
RValue Ret = [&] {
|
||||
switch (RetAI.getKind()) {
|
||||
case ABIArgInfo::InAlloca:
|
||||
case ABIArgInfo::Indirect:
|
||||
return convertTempToRValue(SRetPtr, RetTy, SourceLocation());
|
||||
case ABIArgInfo::Indirect: {
|
||||
RValue ret = convertTempToRValue(SRetPtr, RetTy, SourceLocation());
|
||||
if (UnusedReturnSize)
|
||||
EmitLifetimeEnd(llvm::ConstantInt::get(Int64Ty, UnusedReturnSize),
|
||||
SRetPtr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
case ABIArgInfo::Ignore:
|
||||
// If we are ignoring an argument that had a result, make sure to
|
||||
|
@ -155,17 +155,25 @@ namespace CodeGen {
|
||||
/// ReturnValueSlot - Contains the address where the return value of a
|
||||
/// function can be stored, and whether the address is volatile or not.
|
||||
class ReturnValueSlot {
|
||||
llvm::PointerIntPair<llvm::Value *, 1, bool> Value;
|
||||
llvm::PointerIntPair<llvm::Value *, 2, unsigned int> Value;
|
||||
|
||||
// Return value slot flags
|
||||
enum Flags {
|
||||
IS_VOLATILE = 0x1,
|
||||
IS_UNUSED = 0x2,
|
||||
};
|
||||
|
||||
public:
|
||||
ReturnValueSlot() {}
|
||||
ReturnValueSlot(llvm::Value *Value, bool IsVolatile)
|
||||
: Value(Value, IsVolatile) {}
|
||||
ReturnValueSlot(llvm::Value *Value, bool IsVolatile, bool IsUnused = false)
|
||||
: Value(Value,
|
||||
(IsVolatile ? IS_VOLATILE : 0) | (IsUnused ? IS_UNUSED : 0)) {}
|
||||
|
||||
bool isNull() const { return !getValue(); }
|
||||
|
||||
bool isVolatile() const { return Value.getInt(); }
|
||||
|
||||
bool isVolatile() const { return Value.getInt() & IS_VOLATILE; }
|
||||
llvm::Value *getValue() const { return Value.getPointer(); }
|
||||
bool isUnused() const { return Value.getInt() & IS_UNUSED; }
|
||||
};
|
||||
|
||||
} // end namespace CodeGen
|
||||
|
@ -34,6 +34,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
|
||||
CodeGenFunction &CGF;
|
||||
CGBuilderTy &Builder;
|
||||
AggValueSlot Dest;
|
||||
bool IsResultUnused;
|
||||
|
||||
/// We want to use 'dest' as the return slot except under two
|
||||
/// conditions:
|
||||
@ -48,7 +49,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
|
||||
if (!shouldUseDestForReturnSlot())
|
||||
return ReturnValueSlot();
|
||||
|
||||
return ReturnValueSlot(Dest.getAddr(), Dest.isVolatile());
|
||||
return ReturnValueSlot(Dest.getAddr(), Dest.isVolatile(), IsResultUnused);
|
||||
}
|
||||
|
||||
AggValueSlot EnsureSlot(QualType T) {
|
||||
@ -61,9 +62,9 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
|
||||
}
|
||||
|
||||
public:
|
||||
AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest)
|
||||
: CGF(cgf), Builder(CGF.Builder), Dest(Dest) {
|
||||
}
|
||||
AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest, bool IsResultUnused)
|
||||
: CGF(cgf), Builder(CGF.Builder), Dest(Dest),
|
||||
IsResultUnused(IsResultUnused) { }
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Utilities
|
||||
@ -1394,7 +1395,7 @@ void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot) {
|
||||
// Optimize the slot if possible.
|
||||
CheckAggExprForMemSetUse(Slot, E, *this);
|
||||
|
||||
AggExprEmitter(*this, Slot).Visit(const_cast<Expr*>(E));
|
||||
AggExprEmitter(*this, Slot, Slot.isIgnored()).Visit(const_cast<Expr*>(E));
|
||||
}
|
||||
|
||||
LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
|
||||
|
@ -1349,8 +1349,14 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM,
|
||||
}
|
||||
|
||||
// For unions, stop after the first named field.
|
||||
if (record->isUnion() && Field->getDeclName())
|
||||
break;
|
||||
if (record->isUnion()) {
|
||||
if (Field->getIdentifier())
|
||||
break;
|
||||
if (const auto *FieldRD =
|
||||
dyn_cast_or_null<RecordDecl>(Field->getType()->getAsTagDecl()))
|
||||
if (FieldRD->findFirstNamedDataMember())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the virtual bases, if we're working with the complete object.
|
||||
|
@ -13,8 +13,7 @@
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
using namespace clang;
|
||||
using namespace CodeGen;
|
||||
using namespace clang::CodeGen;
|
||||
using namespace llvm;
|
||||
|
||||
static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) {
|
||||
|
@ -1057,7 +1057,7 @@ llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, Selector Sel,
|
||||
SelValue = llvm::GlobalAlias::create(
|
||||
SelectorTy, llvm::GlobalValue::PrivateLinkage,
|
||||
".objc_selector_" + Sel.getAsString(), &TheModule);
|
||||
Types.push_back(TypedSelector(TypeEncoding, SelValue));
|
||||
Types.emplace_back(TypeEncoding, SelValue);
|
||||
}
|
||||
|
||||
if (lval) {
|
||||
@ -2121,9 +2121,8 @@ void CGObjCGNU::RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {
|
||||
// Get the class declaration for which the alias is specified.
|
||||
ObjCInterfaceDecl *ClassDecl =
|
||||
const_cast<ObjCInterfaceDecl *>(OAD->getClassInterface());
|
||||
std::string ClassName = ClassDecl->getNameAsString();
|
||||
std::string AliasName = OAD->getNameAsString();
|
||||
ClassAliases.push_back(ClassAliasPair(ClassName,AliasName));
|
||||
ClassAliases.emplace_back(ClassDecl->getNameAsString(),
|
||||
OAD->getNameAsString());
|
||||
}
|
||||
|
||||
void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
|
||||
|
@ -314,9 +314,13 @@ void CGRecordLowering::lowerUnion() {
|
||||
// If this is the case, then we aught not to try and come up with a "better"
|
||||
// type, it might not be very easy to come up with a Constant which
|
||||
// correctly initializes it.
|
||||
if (!SeenNamedMember && Field->getDeclName()) {
|
||||
SeenNamedMember = true;
|
||||
if (!isZeroInitializable(Field)) {
|
||||
if (!SeenNamedMember) {
|
||||
SeenNamedMember = Field->getIdentifier();
|
||||
if (!SeenNamedMember)
|
||||
if (const auto *FieldRD =
|
||||
dyn_cast_or_null<RecordDecl>(Field->getType()->getAsTagDecl()))
|
||||
SeenNamedMember = FieldRD->findFirstNamedDataMember();
|
||||
if (SeenNamedMember && !isZeroInitializable(Field)) {
|
||||
IsZeroInitializable = IsZeroInitializableAsBase = false;
|
||||
StorageType = FieldType;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ set(LLVM_LINK_COMPONENTS
|
||||
ProfileData
|
||||
ScalarOpts
|
||||
Support
|
||||
Target
|
||||
TransformUtils
|
||||
)
|
||||
|
||||
|
@ -2563,14 +2563,7 @@ class CodeGenFunction : public CodeGenTypeCache {
|
||||
// Helper functions for EmitAArch64BuiltinExpr.
|
||||
llvm::Value *vectorWrapScalar8(llvm::Value *Op);
|
||||
llvm::Value *vectorWrapScalar16(llvm::Value *Op);
|
||||
llvm::Value *emitVectorWrappedScalar8Intrinsic(
|
||||
unsigned Int, SmallVectorImpl<llvm::Value *> &Ops, const char *Name);
|
||||
llvm::Value *emitVectorWrappedScalar16Intrinsic(
|
||||
unsigned Int, SmallVectorImpl<llvm::Value *> &Ops, const char *Name);
|
||||
llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
|
||||
llvm::Value *EmitNeon64Call(llvm::Function *F,
|
||||
llvm::SmallVectorImpl<llvm::Value *> &O,
|
||||
const char *name);
|
||||
|
||||
llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops);
|
||||
llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
|
||||
@ -2843,6 +2836,11 @@ class CodeGenFunction : public CodeGenTypeCache {
|
||||
/// conditional branch to it, for the -ftrapv checks.
|
||||
void EmitTrapCheck(llvm::Value *Checked);
|
||||
|
||||
/// \brief Create a check for a function parameter that may potentially be
|
||||
/// declared as non-null.
|
||||
void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc,
|
||||
const FunctionDecl *FD, unsigned ParmNum);
|
||||
|
||||
/// EmitCallArg - Emit a single call argument.
|
||||
void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);
|
||||
|
||||
|
@ -676,6 +676,25 @@ CodeGenModule::getFunctionLinkage(GlobalDecl GD) {
|
||||
return getLLVMLinkageForDeclarator(D, Linkage, /*isConstantVariable=*/false);
|
||||
}
|
||||
|
||||
void CodeGenModule::setFunctionDLLStorageClass(GlobalDecl GD, llvm::Function *F) {
|
||||
const auto *FD = cast<FunctionDecl>(GD.getDecl());
|
||||
|
||||
if (const auto *Dtor = dyn_cast_or_null<CXXDestructorDecl>(FD)) {
|
||||
if (getCXXABI().useThunkForDtorVariant(Dtor, GD.getDtorType())) {
|
||||
// Don't dllexport/import destructor thunks.
|
||||
F->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD->hasAttr<DLLImportAttr>())
|
||||
F->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
|
||||
else if (FD->hasAttr<DLLExportAttr>())
|
||||
F->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass);
|
||||
else
|
||||
F->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass);
|
||||
}
|
||||
|
||||
void CodeGenModule::setFunctionDefinitionAttributes(const FunctionDecl *D,
|
||||
llvm::Function *F) {
|
||||
setNonAliasAttributes(D, F);
|
||||
@ -817,7 +836,7 @@ void CodeGenModule::setNonAliasAttributes(const Decl *D,
|
||||
if (const SectionAttr *SA = D->getAttr<SectionAttr>())
|
||||
GO->setSection(SA->getName());
|
||||
|
||||
getTargetCodeGenInfo().SetTargetAttributes(D, GO, *this);
|
||||
getTargetCodeGenInfo().setTargetAttributes(D, GO, *this);
|
||||
}
|
||||
|
||||
void CodeGenModule::SetInternalFunctionAttributes(const Decl *D,
|
||||
@ -889,13 +908,6 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
|
||||
|
||||
setLinkageAndVisibilityForGV(F, FD);
|
||||
|
||||
if (const auto *Dtor = dyn_cast_or_null<CXXDestructorDecl>(FD)) {
|
||||
if (getCXXABI().useThunkForDtorVariant(Dtor, GD.getDtorType())) {
|
||||
// Don't dllexport/import destructor thunks.
|
||||
F->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (const SectionAttr *SA = FD->getAttr<SectionAttr>())
|
||||
F->setSection(SA->getName());
|
||||
|
||||
@ -909,13 +921,13 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
|
||||
void CodeGenModule::addUsedGlobal(llvm::GlobalValue *GV) {
|
||||
assert(!GV->isDeclaration() &&
|
||||
"Only globals with definition can force usage.");
|
||||
LLVMUsed.push_back(GV);
|
||||
LLVMUsed.emplace_back(GV);
|
||||
}
|
||||
|
||||
void CodeGenModule::addCompilerUsedGlobal(llvm::GlobalValue *GV) {
|
||||
assert(!GV->isDeclaration() &&
|
||||
"Only globals with definition can force usage.");
|
||||
LLVMCompilerUsed.push_back(GV);
|
||||
LLVMCompilerUsed.emplace_back(GV);
|
||||
}
|
||||
|
||||
static void emitUsed(CodeGenModule &CGM, StringRef Name,
|
||||
@ -2455,12 +2467,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
|
||||
// declarations).
|
||||
auto *Fn = cast<llvm::Function>(GV);
|
||||
setFunctionLinkage(GD, Fn);
|
||||
if (D->hasAttr<DLLImportAttr>())
|
||||
GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
|
||||
else if (D->hasAttr<DLLExportAttr>())
|
||||
GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass);
|
||||
else
|
||||
GV->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass);
|
||||
setFunctionDLLStorageClass(GD, Fn);
|
||||
|
||||
// FIXME: this is redundant with part of setFunctionDefinitionAttributes
|
||||
setGlobalVisibility(Fn, D);
|
||||
|
@ -329,7 +329,7 @@ class CodeGenModule : public CodeGenTypeCache {
|
||||
};
|
||||
std::vector<DeferredGlobal> DeferredDeclsToEmit;
|
||||
void addDeferredDeclToEmit(llvm::GlobalValue *GV, GlobalDecl GD) {
|
||||
DeferredDeclsToEmit.push_back(DeferredGlobal(GV, GD));
|
||||
DeferredDeclsToEmit.emplace_back(GV, GD);
|
||||
}
|
||||
|
||||
/// List of alias we have emitted. Used to make sure that what they point to
|
||||
@ -876,7 +876,7 @@ class CodeGenModule : public CodeGenTypeCache {
|
||||
|
||||
/// Add a destructor and object to add to the C++ global destructor function.
|
||||
void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object) {
|
||||
CXXGlobalDtors.push_back(std::make_pair(DtorFn, Object));
|
||||
CXXGlobalDtors.emplace_back(DtorFn, Object);
|
||||
}
|
||||
|
||||
/// Create a new runtime function with the specified type and name.
|
||||
@ -1018,6 +1018,9 @@ class CodeGenModule : public CodeGenTypeCache {
|
||||
F->setLinkage(getFunctionLinkage(GD));
|
||||
}
|
||||
|
||||
/// Set the DLL storage class on F.
|
||||
void setFunctionDLLStorageClass(GlobalDecl GD, llvm::Function *F);
|
||||
|
||||
/// Return the appropriate linkage for the vtable, VTT, and type information
|
||||
/// of the given class.
|
||||
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD);
|
||||
|
@ -773,6 +773,8 @@ CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
|
||||
// Turn on Cold attribute for cold functions.
|
||||
// FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal.
|
||||
Fn->addFnAttr(llvm::Attribute::Cold);
|
||||
|
||||
Fn->setEntryCount(FunctionCount);
|
||||
}
|
||||
|
||||
void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S) {
|
||||
|
@ -649,7 +649,7 @@ class X86_32TargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
static bool isStructReturnInRegABI(
|
||||
const llvm::Triple &Triple, const CodeGenOptions &Opts);
|
||||
|
||||
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const override;
|
||||
|
||||
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
|
||||
@ -826,7 +826,8 @@ ABIArgInfo X86_32ABIInfo::getIndirectReturnResult(CCState &State) const {
|
||||
return ABIArgInfo::getIndirect(/*Align=*/0, /*ByVal=*/false);
|
||||
}
|
||||
|
||||
ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, CCState &State) const {
|
||||
ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
|
||||
CCState &State) const {
|
||||
if (RetTy->isVoidType())
|
||||
return ABIArgInfo::getIgnore();
|
||||
|
||||
@ -1330,7 +1331,7 @@ bool X86_32TargetCodeGenInfo::isStructReturnInRegABI(
|
||||
}
|
||||
}
|
||||
|
||||
void X86_32TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
|
||||
void X86_32TargetCodeGenInfo::setTargetAttributes(const Decl *D,
|
||||
llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const {
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
@ -1664,7 +1665,7 @@ class WinX86_32TargetCodeGenInfo : public X86_32TargetCodeGenInfo {
|
||||
bool d, bool p, bool w, unsigned RegParms)
|
||||
: X86_32TargetCodeGenInfo(CGT, d, p, w, RegParms) {}
|
||||
|
||||
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const override;
|
||||
|
||||
void getDependentLibraryOption(llvm::StringRef Lib,
|
||||
@ -1687,15 +1688,16 @@ static void addStackProbeSizeTargetAttribute(const Decl *D,
|
||||
if (CGM.getCodeGenOpts().StackProbeSize != 4096) {
|
||||
llvm::Function *Fn = cast<llvm::Function>(GV);
|
||||
|
||||
Fn->addFnAttr("stack-probe-size", llvm::utostr(CGM.getCodeGenOpts().StackProbeSize));
|
||||
Fn->addFnAttr("stack-probe-size",
|
||||
llvm::utostr(CGM.getCodeGenOpts().StackProbeSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WinX86_32TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
|
||||
void WinX86_32TargetCodeGenInfo::setTargetAttributes(const Decl *D,
|
||||
llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const {
|
||||
X86_32TargetCodeGenInfo::SetTargetAttributes(D, GV, CGM);
|
||||
X86_32TargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
|
||||
|
||||
addStackProbeSizeTargetAttribute(D, GV, CGM);
|
||||
}
|
||||
@ -1707,7 +1709,7 @@ class WinX86_64TargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
WinX86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
|
||||
: TargetCodeGenInfo(new WinX86_64ABIInfo(CGT)) {}
|
||||
|
||||
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const override;
|
||||
|
||||
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
|
||||
@ -1741,10 +1743,10 @@ class WinX86_64TargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
}
|
||||
};
|
||||
|
||||
void WinX86_64TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
|
||||
void WinX86_64TargetCodeGenInfo::setTargetAttributes(const Decl *D,
|
||||
llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const {
|
||||
TargetCodeGenInfo::SetTargetAttributes(D, GV, CGM);
|
||||
TargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
|
||||
|
||||
addStackProbeSizeTargetAttribute(D, GV, CGM);
|
||||
}
|
||||
@ -2225,9 +2227,16 @@ llvm::Type *X86_64ABIInfo::GetByteVectorType(QualType Ty) const {
|
||||
Ty = QualType(InnerTy, 0);
|
||||
|
||||
llvm::Type *IRType = CGT.ConvertType(Ty);
|
||||
assert(isa<llvm::VectorType>(IRType) &&
|
||||
"Trying to return a non-vector type in a vector register!");
|
||||
return IRType;
|
||||
if(isa<llvm::VectorType>(IRType))
|
||||
return IRType;
|
||||
|
||||
// We couldn't find the preferred IR vector type for 'Ty'.
|
||||
uint64_t Size = getContext().getTypeSize(Ty);
|
||||
assert((Size == 128 || Size == 256) && "Invalid type found!");
|
||||
|
||||
// Return a LLVM IR vector type based on the size of 'Ty'.
|
||||
return llvm::VectorType::get(llvm::Type::getDoubleTy(getVMContext()),
|
||||
Size / 64);
|
||||
}
|
||||
|
||||
/// BitsContainNoUserData - Return true if the specified [start,end) bit range
|
||||
@ -2847,7 +2856,7 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
unsigned neededInt, neededSSE;
|
||||
|
||||
Ty = CGF.getContext().getCanonicalType(Ty);
|
||||
ABIArgInfo AI = classifyArgumentType(Ty, 0, neededInt, neededSSE,
|
||||
ABIArgInfo AI = classifyArgumentType(Ty, 0, neededInt, neededSSE,
|
||||
/*isNamedArg*/false);
|
||||
|
||||
// AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
|
||||
@ -3126,7 +3135,8 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
|
||||
|
||||
class PPC32TargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
public:
|
||||
PPC32TargetCodeGenInfo(CodeGenTypes &CGT) : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT)) {}
|
||||
PPC32TargetCodeGenInfo(CodeGenTypes &CGT)
|
||||
: TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT)) {}
|
||||
|
||||
int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
|
||||
// This is recovered from gcc output.
|
||||
@ -3153,19 +3163,25 @@ llvm::Value *PPC32_SVR4_ABIInfo::EmitVAArg(llvm::Value *VAListAddr,
|
||||
}
|
||||
|
||||
bool isI64 = Ty->isIntegerType() && getContext().getTypeSize(Ty) == 64;
|
||||
bool isInt = Ty->isIntegerType() || Ty->isPointerType() || Ty->isAggregateType();
|
||||
bool isInt =
|
||||
Ty->isIntegerType() || Ty->isPointerType() || Ty->isAggregateType();
|
||||
llvm::Type *CharPtr = CGF.Int8PtrTy;
|
||||
llvm::Type *CharPtrPtr = CGF.Int8PtrPtrTy;
|
||||
|
||||
CGBuilderTy &Builder = CGF.Builder;
|
||||
llvm::Value *GPRPtr = Builder.CreateBitCast(VAListAddr, CharPtr, "gprptr");
|
||||
llvm::Value *GPRPtrAsInt = Builder.CreatePtrToInt(GPRPtr, CGF.Int32Ty);
|
||||
llvm::Value *FPRPtrAsInt = Builder.CreateAdd(GPRPtrAsInt, Builder.getInt32(1));
|
||||
llvm::Value *FPRPtrAsInt =
|
||||
Builder.CreateAdd(GPRPtrAsInt, Builder.getInt32(1));
|
||||
llvm::Value *FPRPtr = Builder.CreateIntToPtr(FPRPtrAsInt, CharPtr);
|
||||
llvm::Value *OverflowAreaPtrAsInt = Builder.CreateAdd(FPRPtrAsInt, Builder.getInt32(3));
|
||||
llvm::Value *OverflowAreaPtr = Builder.CreateIntToPtr(OverflowAreaPtrAsInt, CharPtrPtr);
|
||||
llvm::Value *RegsaveAreaPtrAsInt = Builder.CreateAdd(OverflowAreaPtrAsInt, Builder.getInt32(4));
|
||||
llvm::Value *RegsaveAreaPtr = Builder.CreateIntToPtr(RegsaveAreaPtrAsInt, CharPtrPtr);
|
||||
llvm::Value *OverflowAreaPtrAsInt =
|
||||
Builder.CreateAdd(FPRPtrAsInt, Builder.getInt32(3));
|
||||
llvm::Value *OverflowAreaPtr =
|
||||
Builder.CreateIntToPtr(OverflowAreaPtrAsInt, CharPtrPtr);
|
||||
llvm::Value *RegsaveAreaPtrAsInt =
|
||||
Builder.CreateAdd(OverflowAreaPtrAsInt, Builder.getInt32(4));
|
||||
llvm::Value *RegsaveAreaPtr =
|
||||
Builder.CreateIntToPtr(RegsaveAreaPtrAsInt, CharPtrPtr);
|
||||
llvm::Value *GPR = Builder.CreateLoad(GPRPtr, false, "gpr");
|
||||
// Align GPR when TY is i64.
|
||||
if (isI64) {
|
||||
@ -3175,18 +3191,23 @@ llvm::Value *PPC32_SVR4_ABIInfo::EmitVAArg(llvm::Value *VAListAddr,
|
||||
GPR = Builder.CreateSelect(CC64, GPRPlusOne, GPR);
|
||||
}
|
||||
llvm::Value *FPR = Builder.CreateLoad(FPRPtr, false, "fpr");
|
||||
llvm::Value *OverflowArea = Builder.CreateLoad(OverflowAreaPtr, false, "overflow_area");
|
||||
llvm::Value *OverflowAreaAsInt = Builder.CreatePtrToInt(OverflowArea, CGF.Int32Ty);
|
||||
llvm::Value *RegsaveArea = Builder.CreateLoad(RegsaveAreaPtr, false, "regsave_area");
|
||||
llvm::Value *RegsaveAreaAsInt = Builder.CreatePtrToInt(RegsaveArea, CGF.Int32Ty);
|
||||
llvm::Value *OverflowArea =
|
||||
Builder.CreateLoad(OverflowAreaPtr, false, "overflow_area");
|
||||
llvm::Value *OverflowAreaAsInt =
|
||||
Builder.CreatePtrToInt(OverflowArea, CGF.Int32Ty);
|
||||
llvm::Value *RegsaveArea =
|
||||
Builder.CreateLoad(RegsaveAreaPtr, false, "regsave_area");
|
||||
llvm::Value *RegsaveAreaAsInt =
|
||||
Builder.CreatePtrToInt(RegsaveArea, CGF.Int32Ty);
|
||||
|
||||
llvm::Value *CC = Builder.CreateICmpULT(isInt ? GPR : FPR,
|
||||
Builder.getInt8(8), "cond");
|
||||
llvm::Value *CC =
|
||||
Builder.CreateICmpULT(isInt ? GPR : FPR, Builder.getInt8(8), "cond");
|
||||
|
||||
llvm::Value *RegConstant = Builder.CreateMul(isInt ? GPR : FPR,
|
||||
Builder.getInt8(isInt ? 4 : 8));
|
||||
llvm::Value *RegConstant =
|
||||
Builder.CreateMul(isInt ? GPR : FPR, Builder.getInt8(isInt ? 4 : 8));
|
||||
|
||||
llvm::Value *OurReg = Builder.CreateAdd(RegsaveAreaAsInt, Builder.CreateSExt(RegConstant, CGF.Int32Ty));
|
||||
llvm::Value *OurReg = Builder.CreateAdd(
|
||||
RegsaveAreaAsInt, Builder.CreateSExt(RegConstant, CGF.Int32Ty));
|
||||
|
||||
if (Ty->isFloatingType())
|
||||
OurReg = Builder.CreateAdd(OurReg, Builder.getInt32(32));
|
||||
@ -3215,8 +3236,10 @@ llvm::Value *PPC32_SVR4_ABIInfo::EmitVAArg(llvm::Value *VAListAddr,
|
||||
|
||||
// Increase the overflow area.
|
||||
llvm::Value *Result2 = Builder.CreateIntToPtr(OverflowAreaAsInt, PTy);
|
||||
OverflowAreaAsInt = Builder.CreateAdd(OverflowAreaAsInt, Builder.getInt32(isInt ? 4 : 8));
|
||||
Builder.CreateStore(Builder.CreateIntToPtr(OverflowAreaAsInt, CharPtr), OverflowAreaPtr);
|
||||
OverflowAreaAsInt =
|
||||
Builder.CreateAdd(OverflowAreaAsInt, Builder.getInt32(isInt ? 4 : 8));
|
||||
Builder.CreateStore(Builder.CreateIntToPtr(OverflowAreaAsInt, CharPtr),
|
||||
OverflowAreaPtr);
|
||||
CGF.EmitBranch(Cont);
|
||||
|
||||
CGF.EmitBlock(Cont);
|
||||
@ -3226,7 +3249,7 @@ llvm::Value *PPC32_SVR4_ABIInfo::EmitVAArg(llvm::Value *VAListAddr,
|
||||
Result->addIncoming(Result2, UsingOverflow);
|
||||
|
||||
if (Ty->isAggregateType()) {
|
||||
llvm::Value *AGGPtr = Builder.CreateBitCast(Result, CharPtrPtr, "aggrptr") ;
|
||||
llvm::Value *AGGPtr = Builder.CreateBitCast(Result, CharPtrPtr, "aggrptr");
|
||||
return Builder.CreateLoad(AGGPtr, false, "aggr");
|
||||
}
|
||||
|
||||
@ -3795,8 +3818,10 @@ llvm::Value *PPC64_SVR4_ABIInfo::EmitVAArg(llvm::Value *VAListAddr,
|
||||
llvm::Value *RealAddr = Builder.CreatePtrToInt(Addr, CGF.Int64Ty);
|
||||
llvm::Value *ImagAddr = RealAddr;
|
||||
if (CGF.CGM.getDataLayout().isBigEndian()) {
|
||||
RealAddr = Builder.CreateAdd(RealAddr, Builder.getInt64(8 - CplxBaseSize));
|
||||
ImagAddr = Builder.CreateAdd(ImagAddr, Builder.getInt64(16 - CplxBaseSize));
|
||||
RealAddr =
|
||||
Builder.CreateAdd(RealAddr, Builder.getInt64(8 - CplxBaseSize));
|
||||
ImagAddr =
|
||||
Builder.CreateAdd(ImagAddr, Builder.getInt64(16 - CplxBaseSize));
|
||||
} else {
|
||||
ImagAddr = Builder.CreateAdd(ImagAddr, Builder.getInt64(8));
|
||||
}
|
||||
@ -4354,8 +4379,9 @@ llvm::Value *AArch64ABIInfo::EmitAAPCSVAArg(llvm::Value *VAListAddr,
|
||||
return ResAddr;
|
||||
}
|
||||
|
||||
llvm::Value *AArch64ABIInfo::EmitDarwinVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
CodeGenFunction &CGF) const {
|
||||
llvm::Value *AArch64ABIInfo::EmitDarwinVAArg(llvm::Value *VAListAddr,
|
||||
QualType Ty,
|
||||
CodeGenFunction &CGF) const {
|
||||
// We do not support va_arg for aggregates or illegal vector types.
|
||||
// Lower VAArg here for these cases and use the LLVM va_arg instruction for
|
||||
// other cases.
|
||||
@ -4511,7 +4537,7 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
return TargetCodeGenInfo::getSizeOfUnwindException();
|
||||
}
|
||||
|
||||
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const override {
|
||||
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
|
||||
if (!FD)
|
||||
@ -4558,7 +4584,7 @@ class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo {
|
||||
WindowsARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIInfo::ABIKind K)
|
||||
: ARMTargetCodeGenInfo(CGT, K) {}
|
||||
|
||||
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const override;
|
||||
};
|
||||
|
||||
@ -4574,16 +4600,17 @@ void WindowsARMTargetCodeGenInfo::addStackProbeSizeTargetAttribute(
|
||||
llvm::utostr(CGM.getCodeGenOpts().StackProbeSize));
|
||||
}
|
||||
|
||||
void WindowsARMTargetCodeGenInfo::SetTargetAttributes(
|
||||
void WindowsARMTargetCodeGenInfo::setTargetAttributes(
|
||||
const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {
|
||||
ARMTargetCodeGenInfo::SetTargetAttributes(D, GV, CGM);
|
||||
ARMTargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
|
||||
addStackProbeSizeTargetAttribute(D, GV, CGM);
|
||||
}
|
||||
}
|
||||
|
||||
void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {
|
||||
if (!getCXXABI().classifyReturnType(FI))
|
||||
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), FI.isVariadic());
|
||||
FI.getReturnInfo() =
|
||||
classifyReturnType(FI.getReturnType(), FI.isVariadic());
|
||||
|
||||
for (auto &I : FI.arguments())
|
||||
I.info = classifyArgumentType(I.type, FI.isVariadic());
|
||||
@ -5031,7 +5058,7 @@ class NVPTXTargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
NVPTXTargetCodeGenInfo(CodeGenTypes &CGT)
|
||||
: TargetCodeGenInfo(new NVPTXABIInfo(CGT)) {}
|
||||
|
||||
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &M) const override;
|
||||
private:
|
||||
// Adds a NamedMDNode with F, Name, and Operand as operands, and adds the
|
||||
@ -5087,7 +5114,7 @@ llvm::Value *NVPTXABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
}
|
||||
|
||||
void NVPTXTargetCodeGenInfo::
|
||||
SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &M) const{
|
||||
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
|
||||
if (!FD) return;
|
||||
@ -5499,13 +5526,13 @@ class MSP430TargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
public:
|
||||
MSP430TargetCodeGenInfo(CodeGenTypes &CGT)
|
||||
: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {}
|
||||
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &M) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void MSP430TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
|
||||
void MSP430TargetCodeGenInfo::setTargetAttributes(const Decl *D,
|
||||
llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &M) const {
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
@ -5565,7 +5592,7 @@ class MIPSTargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
return 29;
|
||||
}
|
||||
|
||||
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const override {
|
||||
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
|
||||
if (!FD) return;
|
||||
@ -5587,8 +5614,8 @@ class MIPSTargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
};
|
||||
}
|
||||
|
||||
void MipsABIInfo::CoerceToIntArgs(uint64_t TySize,
|
||||
SmallVectorImpl<llvm::Type *> &ArgList) const {
|
||||
void MipsABIInfo::CoerceToIntArgs(
|
||||
uint64_t TySize, SmallVectorImpl<llvm::Type *> &ArgList) const {
|
||||
llvm::IntegerType *IntTy =
|
||||
llvm::IntegerType::get(getVMContext(), MinABIStackAlignInBytes * 8);
|
||||
|
||||
@ -5627,7 +5654,7 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const {
|
||||
const RecordDecl *RD = RT->getDecl();
|
||||
const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
|
||||
assert(!(TySize % 8) && "Size of structure must be multiple of 8.");
|
||||
|
||||
|
||||
uint64_t LastOffset = 0;
|
||||
unsigned idx = 0;
|
||||
llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64);
|
||||
@ -5729,7 +5756,7 @@ MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const {
|
||||
// 1. The size of the struct/class is no larger than 128-bit.
|
||||
// 2. The struct/class has one or two fields all of which are floating
|
||||
// point types.
|
||||
// 3. The offset of the first field is zero (this follows what gcc does).
|
||||
// 3. The offset of the first field is zero (this follows what gcc does).
|
||||
//
|
||||
// Any other composite results are returned in integer registers.
|
||||
//
|
||||
@ -5799,7 +5826,7 @@ void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const {
|
||||
if (!getCXXABI().classifyReturnType(FI))
|
||||
RetInfo = classifyReturnType(FI.getReturnType());
|
||||
|
||||
// Check if a pointer to an aggregate is passed as a hidden argument.
|
||||
// Check if a pointer to an aggregate is passed as a hidden argument.
|
||||
uint64_t Offset = RetInfo.isIndirect() ? MinABIStackAlignInBytes : 0;
|
||||
|
||||
for (auto &I : FI.arguments())
|
||||
@ -5821,7 +5848,7 @@ llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
Ty = CGF.getContext().getIntTypeForBitwidth(SlotSizeInBits,
|
||||
Ty->isSignedIntegerType());
|
||||
}
|
||||
|
||||
|
||||
CGBuilderTy &Builder = CGF.Builder;
|
||||
llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap");
|
||||
llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
|
||||
@ -5840,7 +5867,7 @@ llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
AddrTyped = CGF.Builder.CreateIntToPtr(And, PTy);
|
||||
}
|
||||
else
|
||||
AddrTyped = Builder.CreateBitCast(Addr, PTy);
|
||||
AddrTyped = Builder.CreateBitCast(Addr, PTy);
|
||||
|
||||
llvm::Value *AlignedAddr = Builder.CreateBitCast(AddrTyped, BP);
|
||||
TypeAlign = std::max((unsigned)TypeAlign, MinABIStackAlignInBytes);
|
||||
@ -5850,17 +5877,17 @@ llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
Builder.CreateGEP(AlignedAddr, llvm::ConstantInt::get(IntTy, Offset),
|
||||
"ap.next");
|
||||
Builder.CreateStore(NextAddr, VAListAddrAsBPP);
|
||||
|
||||
|
||||
return AddrTyped;
|
||||
}
|
||||
|
||||
bool MipsABIInfo::shouldSignExtUnsignedType(QualType Ty) const {
|
||||
int TySize = getContext().getTypeSize(Ty);
|
||||
|
||||
|
||||
// MIPS64 ABI requires unsigned 32 bit integers to be sign extended.
|
||||
if (Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32)
|
||||
return true;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5894,7 +5921,7 @@ MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TCE ABI Implementation (see http://tce.cs.tut.fi). Uses mostly the defaults.
|
||||
// Currently subclassed only to implement custom OpenCL C function attribute
|
||||
// Currently subclassed only to implement custom OpenCL C function attribute
|
||||
// handling.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -5905,18 +5932,17 @@ class TCETargetCodeGenInfo : public DefaultTargetCodeGenInfo {
|
||||
TCETargetCodeGenInfo(CodeGenTypes &CGT)
|
||||
: DefaultTargetCodeGenInfo(CGT) {}
|
||||
|
||||
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &M) const override;
|
||||
};
|
||||
|
||||
void TCETargetCodeGenInfo::SetTargetAttributes(const Decl *D,
|
||||
llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &M) const {
|
||||
void TCETargetCodeGenInfo::setTargetAttributes(
|
||||
const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {
|
||||
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
|
||||
if (!FD) return;
|
||||
|
||||
llvm::Function *F = cast<llvm::Function>(GV);
|
||||
|
||||
|
||||
if (M.getLangOpts().OpenCL) {
|
||||
if (FD->hasAttr<OpenCLKernelAttr>()) {
|
||||
// OpenCL C Kernel functions are not subject to inlining
|
||||
@ -5925,8 +5951,9 @@ void TCETargetCodeGenInfo::SetTargetAttributes(const Decl *D,
|
||||
if (Attr) {
|
||||
// Convert the reqd_work_group_size() attributes to metadata.
|
||||
llvm::LLVMContext &Context = F->getContext();
|
||||
llvm::NamedMDNode *OpenCLMetadata =
|
||||
M.getModule().getOrInsertNamedMetadata("opencl.kernel_wg_size_info");
|
||||
llvm::NamedMDNode *OpenCLMetadata =
|
||||
M.getModule().getOrInsertNamedMetadata(
|
||||
"opencl.kernel_wg_size_info");
|
||||
|
||||
SmallVector<llvm::Metadata *, 5> Operands;
|
||||
Operands.push_back(llvm::ConstantAsMetadata::get(F));
|
||||
@ -5941,9 +5968,9 @@ void TCETargetCodeGenInfo::SetTargetAttributes(const Decl *D,
|
||||
llvm::ConstantAsMetadata::get(llvm::Constant::getIntegerValue(
|
||||
M.Int32Ty, llvm::APInt(32, Attr->getZDim()))));
|
||||
|
||||
// Add a boolean constant operand for "required" (true) or "hint" (false)
|
||||
// for implementing the work_group_size_hint attr later. Currently
|
||||
// always true as the hint is not yet implemented.
|
||||
// Add a boolean constant operand for "required" (true) or "hint"
|
||||
// (false) for implementing the work_group_size_hint attr later.
|
||||
// Currently always true as the hint is not yet implemented.
|
||||
Operands.push_back(
|
||||
llvm::ConstantAsMetadata::get(llvm::ConstantInt::getTrue(Context)));
|
||||
OpenCLMetadata->addOperand(llvm::MDNode::get(Context, Operands));
|
||||
@ -6097,13 +6124,13 @@ class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
public:
|
||||
AMDGPUTargetCodeGenInfo(CodeGenTypes &CGT)
|
||||
: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {}
|
||||
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &M) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void AMDGPUTargetCodeGenInfo::SetTargetAttributes(
|
||||
void AMDGPUTargetCodeGenInfo::setTargetAttributes(
|
||||
const Decl *D,
|
||||
llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &M) const {
|
||||
@ -6419,7 +6446,7 @@ SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
|
||||
// FSR = 70
|
||||
// CSR = 71
|
||||
AssignToArrayRange(Builder, Address, Eight8, 64, 71);
|
||||
|
||||
|
||||
// 72-87: d0-15, the 8-byte floating-point registers
|
||||
AssignToArrayRange(Builder, Address, Eight8, 72, 87);
|
||||
|
||||
@ -6692,7 +6719,7 @@ StringRef TypeStringCache::lookupStr(const IdentifierInfo *ID) {
|
||||
///
|
||||
/// The TypeString carries type, qualifier, name, size & value details.
|
||||
/// Please see 'Tools Development Guide' section 2.16.2 for format details:
|
||||
/// <https://www.xmos.com/download/public/Tools-Development-Guide%28X9114A%29.pdf>
|
||||
/// https://www.xmos.com/download/public/Tools-Development-Guide%28X9114A%29.pdf
|
||||
/// The output is tested by test/CodeGen/xcore-stringtype.c.
|
||||
///
|
||||
static bool getTypeString(SmallStringEnc &Enc, const Decl *D,
|
||||
@ -6718,7 +6745,8 @@ static bool appendType(SmallStringEnc &Enc, QualType QType,
|
||||
TypeStringCache &TSC);
|
||||
|
||||
/// Helper function for appendRecordType().
|
||||
/// Builds a SmallVector containing the encoded field types in declaration order.
|
||||
/// Builds a SmallVector containing the encoded field types in declaration
|
||||
/// order.
|
||||
static bool extractFieldType(SmallVectorImpl<FieldEncoding> &FE,
|
||||
const RecordDecl *RD,
|
||||
const CodeGen::CodeGenModule &CGM,
|
||||
@ -6741,7 +6769,7 @@ static bool extractFieldType(SmallVectorImpl<FieldEncoding> &FE,
|
||||
if (Field->isBitField())
|
||||
Enc += ')';
|
||||
Enc += '}';
|
||||
FE.push_back(FieldEncoding(!Field->getName().empty(), Enc));
|
||||
FE.emplace_back(!Field->getName().empty(), Enc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -7155,17 +7183,13 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
|
||||
bool IsWin32FloatStructABI = Triple.isOSWindows() && !Triple.isOSCygMing();
|
||||
|
||||
if (Triple.getOS() == llvm::Triple::Win32) {
|
||||
return *(TheTargetCodeGenInfo =
|
||||
new WinX86_32TargetCodeGenInfo(Types,
|
||||
IsDarwinVectorABI, IsSmallStructInRegABI,
|
||||
IsWin32FloatStructABI,
|
||||
CodeGenOpts.NumRegisterParameters));
|
||||
return *(TheTargetCodeGenInfo = new WinX86_32TargetCodeGenInfo(
|
||||
Types, IsDarwinVectorABI, IsSmallStructInRegABI,
|
||||
IsWin32FloatStructABI, CodeGenOpts.NumRegisterParameters));
|
||||
} else {
|
||||
return *(TheTargetCodeGenInfo =
|
||||
new X86_32TargetCodeGenInfo(Types,
|
||||
IsDarwinVectorABI, IsSmallStructInRegABI,
|
||||
IsWin32FloatStructABI,
|
||||
CodeGenOpts.NumRegisterParameters));
|
||||
return *(TheTargetCodeGenInfo = new X86_32TargetCodeGenInfo(
|
||||
Types, IsDarwinVectorABI, IsSmallStructInRegABI,
|
||||
IsWin32FloatStructABI, CodeGenOpts.NumRegisterParameters));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,12 +53,12 @@ class TargetCodeGenInfo {
|
||||
/// getABIInfo() - Returns ABI info helper for the target.
|
||||
const ABIInfo &getABIInfo() const { return *Info; }
|
||||
|
||||
/// SetTargetAttributes - Provides a convenient hook to handle extra
|
||||
/// setTargetAttributes - Provides a convenient hook to handle extra
|
||||
/// target-specific attributes for the given global.
|
||||
virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &M) const {}
|
||||
|
||||
/// EmitTargetMD - Provides a convenient hook to handle extra
|
||||
/// emitTargetMD - Provides a convenient hook to handle extra
|
||||
/// target-specific metadata for the given global.
|
||||
virtual void emitTargetMD(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &M) const {}
|
||||
|
@ -140,10 +140,8 @@ InputArgList *Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings) {
|
||||
}
|
||||
}
|
||||
|
||||
for (arg_iterator it = Args->filtered_begin(options::OPT_UNKNOWN),
|
||||
ie = Args->filtered_end(); it != ie; ++it) {
|
||||
Diags.Report(diag::err_drv_unknown_argument) << (*it) ->getAsString(*Args);
|
||||
}
|
||||
for (const Arg *A : Args->filtered(options::OPT_UNKNOWN))
|
||||
Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(*Args);
|
||||
|
||||
return Args;
|
||||
}
|
||||
@ -347,9 +345,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
|
||||
DefaultTargetTriple = A->getValue();
|
||||
if (const Arg *A = Args->getLastArg(options::OPT_ccc_install_dir))
|
||||
Dir = InstalledDir = A->getValue();
|
||||
for (arg_iterator it = Args->filtered_begin(options::OPT_B),
|
||||
ie = Args->filtered_end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
for (const Arg *A : Args->filtered(options::OPT_B)) {
|
||||
A->claim();
|
||||
PrefixDirs.push_back(A->getValue(0));
|
||||
}
|
||||
@ -1467,9 +1463,8 @@ void Driver::BuildJobs(Compilation &C) const {
|
||||
if (Opt.getKind() == Option::FlagClass) {
|
||||
bool DuplicateClaimed = false;
|
||||
|
||||
for (arg_iterator it = C.getArgs().filtered_begin(&Opt),
|
||||
ie = C.getArgs().filtered_end(); it != ie; ++it) {
|
||||
if ((*it)->isClaimed()) {
|
||||
for (const Arg *AA : C.getArgs().filtered(&Opt)) {
|
||||
if (AA->isClaimed()) {
|
||||
DuplicateClaimed = true;
|
||||
break;
|
||||
}
|
||||
@ -1697,8 +1692,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
|
||||
assert(AtTopLevel && isa<PreprocessJobAction>(JA));
|
||||
StringRef BaseName = llvm::sys::path::filename(BaseInput);
|
||||
StringRef NameArg;
|
||||
if (Arg *A = C.getArgs().getLastArg(options::OPT__SLASH_Fi,
|
||||
options::OPT__SLASH_o))
|
||||
if (Arg *A = C.getArgs().getLastArg(options::OPT__SLASH_Fi))
|
||||
NameArg = A->getValue();
|
||||
return C.addResultFile(MakeCLOutputFilename(C.getArgs(), NameArg, BaseName,
|
||||
types::TY_PP_C), &JA);
|
||||
@ -1744,7 +1738,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
|
||||
// Determine what the derived output name should be.
|
||||
const char *NamedOutput;
|
||||
|
||||
if (JA.getType() == types::TY_Object &&
|
||||
if ((JA.getType() == types::TY_Object || JA.getType() == types::TY_LTO_BC) &&
|
||||
C.getArgs().hasArg(options::OPT__SLASH_Fo, options::OPT__SLASH_o)) {
|
||||
// The /Fo or /o flag decides the object filename.
|
||||
StringRef Val = C.getArgs().getLastArg(options::OPT__SLASH_Fo,
|
||||
@ -1878,8 +1872,8 @@ void
|
||||
Driver::generatePrefixedToolNames(const char *Tool, const ToolChain &TC,
|
||||
SmallVectorImpl<std::string> &Names) const {
|
||||
// FIXME: Needs a better variable than DefaultTargetTriple
|
||||
Names.push_back(DefaultTargetTriple + "-" + Tool);
|
||||
Names.push_back(Tool);
|
||||
Names.emplace_back(DefaultTargetTriple + "-" + Tool);
|
||||
Names.emplace_back(Tool);
|
||||
}
|
||||
|
||||
static bool ScanDirForExecutable(SmallString<128> &Dir,
|
||||
@ -2185,6 +2179,6 @@ std::pair<unsigned, unsigned> Driver::getIncludeExcludeOptionFlagMasks() const {
|
||||
return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask);
|
||||
}
|
||||
|
||||
bool clang::driver::isOptimizationLevelFast(const llvm::opt::ArgList &Args) {
|
||||
bool clang::driver::isOptimizationLevelFast(const ArgList &Args) {
|
||||
return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group, false);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ToolChains.h"
|
||||
#include "Tools.h"
|
||||
#include "clang/Basic/CharInfo.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Driver/Compilation.h"
|
||||
@ -495,3 +496,29 @@ void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const {
|
||||
// FIXME: There should probably be logic here to find libc++ on Windows.
|
||||
}
|
||||
|
||||
std::string
|
||||
MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
|
||||
types::ID InputType) const {
|
||||
std::string TripleStr =
|
||||
ToolChain::ComputeEffectiveClangTriple(Args, InputType);
|
||||
llvm::Triple Triple(TripleStr);
|
||||
VersionTuple MSVT =
|
||||
tools::visualstudio::getMSVCVersion(/*D=*/nullptr, Triple, Args,
|
||||
/*IsWindowsMSVC=*/true);
|
||||
if (MSVT.empty())
|
||||
return TripleStr;
|
||||
|
||||
MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
|
||||
MSVT.getSubminor().getValueOr(0));
|
||||
|
||||
if (Triple.getEnvironment() == llvm::Triple::MSVC) {
|
||||
StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
|
||||
if (ObjFmt.empty())
|
||||
Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
|
||||
else
|
||||
Triple.setEnvironmentName(
|
||||
(Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
|
||||
}
|
||||
return Triple.getTriple();
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
|
||||
// Thumb2 is the default for V7 on Darwin.
|
||||
//
|
||||
// FIXME: Thumb should just be another -target-feaure, not in the triple.
|
||||
StringRef CPU = Triple.isOSBinFormatMachO()
|
||||
std::string CPU = Triple.isOSBinFormatMachO()
|
||||
? tools::arm::getARMCPUForMArch(Args, Triple)
|
||||
: tools::arm::getARMTargetCPU(Args, Triple);
|
||||
StringRef Suffix =
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/Program.h"
|
||||
#include "llvm/Support/TargetParser.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstdlib> // ::getenv
|
||||
#include <system_error>
|
||||
@ -108,9 +109,12 @@ bool Darwin::hasBlocksRuntime() const {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Use ARMTargetParser.
|
||||
static const char *GetArmArchForMArch(StringRef Value) {
|
||||
return llvm::StringSwitch<const char*>(Value)
|
||||
// This is just a MachO name translation routine and there's no
|
||||
// way to join this into ARMTargetParser without breaking all
|
||||
// other assumptions. Maybe MachO should consider standardising
|
||||
// their nomenclature.
|
||||
static const char *ArmMachOArchName(StringRef Arch) {
|
||||
return llvm::StringSwitch<const char*>(Arch)
|
||||
.Case("armv6k", "armv6")
|
||||
.Case("armv6m", "armv6m")
|
||||
.Case("armv5tej", "armv5")
|
||||
@ -126,22 +130,23 @@ static const char *GetArmArchForMArch(StringRef Value) {
|
||||
.Default(nullptr);
|
||||
}
|
||||
|
||||
// FIXME: Use ARMTargetParser.
|
||||
static const char *GetArmArchForMCpu(StringRef Value) {
|
||||
return llvm::StringSwitch<const char *>(Value)
|
||||
.Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s","armv5")
|
||||
.Cases("arm10e", "arm10tdmi", "armv5")
|
||||
.Cases("arm1020t", "arm1020e", "arm1022e", "arm1026ej-s", "armv5")
|
||||
.Case("xscale", "xscale")
|
||||
.Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6")
|
||||
.Cases("sc000", "cortex-m0", "cortex-m0plus", "cortex-m1", "armv6m")
|
||||
.Cases("cortex-a5", "cortex-a7", "cortex-a8", "armv7")
|
||||
.Cases("cortex-a9", "cortex-a12", "cortex-a15", "cortex-a17", "krait", "armv7")
|
||||
.Cases("cortex-r4", "cortex-r4f", "cortex-r5", "cortex-r7", "armv7r")
|
||||
.Cases("sc300", "cortex-m3", "armv7m")
|
||||
.Cases("cortex-m4", "cortex-m7", "armv7em")
|
||||
.Case("swift", "armv7s")
|
||||
.Default(nullptr);
|
||||
static const char *ArmMachOArchNameCPU(StringRef CPU) {
|
||||
unsigned ArchKind = llvm::ARMTargetParser::parseCPUArch(CPU);
|
||||
if (ArchKind == llvm::ARM::AK_INVALID)
|
||||
return nullptr;
|
||||
StringRef Arch = llvm::ARMTargetParser::getArchName(ArchKind);
|
||||
|
||||
// FIXME: Make sure this MachO triple mangling is really necessary.
|
||||
// ARMv5* normalises to ARMv5.
|
||||
if (Arch.startswith("armv5"))
|
||||
Arch = Arch.substr(0, 5);
|
||||
// ARMv6*, except ARMv6M, normalises to ARMv6.
|
||||
else if (Arch.startswith("armv6") && !Arch.endswith("6m"))
|
||||
Arch = Arch.substr(0, 5);
|
||||
// ARMv7A normalises to ARMv7.
|
||||
else if (Arch.endswith("v7a"))
|
||||
Arch = Arch.substr(0, 5);
|
||||
return Arch.data();
|
||||
}
|
||||
|
||||
static bool isSoftFloatABI(const ArgList &Args) {
|
||||
@ -166,11 +171,11 @@ StringRef MachO::getMachOArchName(const ArgList &Args) const {
|
||||
case llvm::Triple::thumb:
|
||||
case llvm::Triple::arm: {
|
||||
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
|
||||
if (const char *Arch = GetArmArchForMArch(A->getValue()))
|
||||
if (const char *Arch = ArmMachOArchName(A->getValue()))
|
||||
return Arch;
|
||||
|
||||
if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
|
||||
if (const char *Arch = GetArmArchForMCpu(A->getValue()))
|
||||
if (const char *Arch = ArmMachOArchNameCPU(A->getValue()))
|
||||
return Arch;
|
||||
|
||||
return "arm";
|
||||
@ -874,8 +879,8 @@ DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
|
||||
return DAL;
|
||||
}
|
||||
|
||||
void MachO::AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
|
||||
llvm::opt::ArgStringList &CmdArgs) const {
|
||||
void MachO::AddLinkRuntimeLibArgs(const ArgList &Args,
|
||||
ArgStringList &CmdArgs) const {
|
||||
// Embedded targets are simple at the moment, not supporting sanitizers and
|
||||
// with different libraries for each member of the product { static, PIC } x
|
||||
// { hard-float, soft-float }
|
||||
@ -984,8 +989,8 @@ bool MachO::SupportsProfiling() const {
|
||||
return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64;
|
||||
}
|
||||
|
||||
void Darwin::addMinVersionArgs(const llvm::opt::ArgList &Args,
|
||||
llvm::opt::ArgStringList &CmdArgs) const {
|
||||
void Darwin::addMinVersionArgs(const ArgList &Args,
|
||||
ArgStringList &CmdArgs) const {
|
||||
VersionTuple TargetVersion = getTargetVersion();
|
||||
|
||||
if (isTargetIOSSimulator())
|
||||
@ -1000,8 +1005,8 @@ void Darwin::addMinVersionArgs(const llvm::opt::ArgList &Args,
|
||||
CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
|
||||
}
|
||||
|
||||
void Darwin::addStartObjectFileArgs(const llvm::opt::ArgList &Args,
|
||||
llvm::opt::ArgStringList &CmdArgs) const {
|
||||
void Darwin::addStartObjectFileArgs(const ArgList &Args,
|
||||
ArgStringList &CmdArgs) const {
|
||||
// Derived from startfile spec.
|
||||
if (Args.hasArg(options::OPT_dynamiclib)) {
|
||||
// Derived from darwin_dylib1 spec.
|
||||
@ -1570,7 +1575,7 @@ static Multilib makeMultilib(StringRef commonSuffix) {
|
||||
}
|
||||
|
||||
static bool findMIPSMultilibs(const llvm::Triple &TargetTriple, StringRef Path,
|
||||
const llvm::opt::ArgList &Args,
|
||||
const ArgList &Args,
|
||||
DetectedMultilibs &Result) {
|
||||
// Some MIPS toolchains put libraries and object files compiled
|
||||
// using different options in to the sub-directoris which names
|
||||
@ -2072,21 +2077,26 @@ bool Generic_GCC::isPICDefaultForced() const {
|
||||
}
|
||||
|
||||
bool Generic_GCC::IsIntegratedAssemblerDefault() const {
|
||||
return getTriple().getArch() == llvm::Triple::x86 ||
|
||||
getTriple().getArch() == llvm::Triple::x86_64 ||
|
||||
getTriple().getArch() == llvm::Triple::aarch64 ||
|
||||
getTriple().getArch() == llvm::Triple::aarch64_be ||
|
||||
getTriple().getArch() == llvm::Triple::arm ||
|
||||
getTriple().getArch() == llvm::Triple::armeb ||
|
||||
getTriple().getArch() == llvm::Triple::thumb ||
|
||||
getTriple().getArch() == llvm::Triple::thumbeb ||
|
||||
getTriple().getArch() == llvm::Triple::ppc ||
|
||||
getTriple().getArch() == llvm::Triple::ppc64 ||
|
||||
getTriple().getArch() == llvm::Triple::ppc64le ||
|
||||
getTriple().getArch() == llvm::Triple::sparc ||
|
||||
getTriple().getArch() == llvm::Triple::sparcel ||
|
||||
getTriple().getArch() == llvm::Triple::sparcv9 ||
|
||||
getTriple().getArch() == llvm::Triple::systemz;
|
||||
switch (getTriple().getArch()) {
|
||||
case llvm::Triple::x86:
|
||||
case llvm::Triple::x86_64:
|
||||
case llvm::Triple::aarch64:
|
||||
case llvm::Triple::aarch64_be:
|
||||
case llvm::Triple::arm:
|
||||
case llvm::Triple::armeb:
|
||||
case llvm::Triple::thumb:
|
||||
case llvm::Triple::thumbeb:
|
||||
case llvm::Triple::ppc:
|
||||
case llvm::Triple::ppc64:
|
||||
case llvm::Triple::ppc64le:
|
||||
case llvm::Triple::sparc:
|
||||
case llvm::Triple::sparcel:
|
||||
case llvm::Triple::sparcv9:
|
||||
case llvm::Triple::systemz:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs,
|
||||
@ -2164,14 +2174,9 @@ static void GetHexagonLibraryPaths(
|
||||
//----------------------------------------------------------------------------
|
||||
// -L Args
|
||||
//----------------------------------------------------------------------------
|
||||
for (arg_iterator
|
||||
it = Args.filtered_begin(options::OPT_L),
|
||||
ie = Args.filtered_end();
|
||||
it != ie;
|
||||
++it) {
|
||||
for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
|
||||
LibPaths->push_back((*it)->getValue(i));
|
||||
}
|
||||
for (const Arg *A : Args.filtered(options::OPT_L))
|
||||
for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
|
||||
LibPaths->push_back(A->getValue(i));
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Other standard paths
|
||||
@ -3105,6 +3110,14 @@ static std::string getMultiarchTriple(const llvm::Triple &TargetTriple,
|
||||
if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
|
||||
return "powerpc64le-linux-gnu";
|
||||
return TargetTriple.str();
|
||||
case llvm::Triple::sparc:
|
||||
if (llvm::sys::fs::exists(SysRoot + "/lib/sparc-linux-gnu"))
|
||||
return "sparc-linux-gnu";
|
||||
return TargetTriple.str();
|
||||
case llvm::Triple::sparcv9:
|
||||
if (llvm::sys::fs::exists(SysRoot + "/lib/sparc64-linux-gnu"))
|
||||
return "sparc64-linux-gnu";
|
||||
return TargetTriple.str();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3457,6 +3470,12 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
const StringRef PPC64LEMultiarchIncludeDirs[] = {
|
||||
"/usr/include/powerpc64le-linux-gnu"
|
||||
};
|
||||
const StringRef SparcMultiarchIncludeDirs[] = {
|
||||
"/usr/include/sparc-linux-gnu"
|
||||
};
|
||||
const StringRef Sparc64MultiarchIncludeDirs[] = {
|
||||
"/usr/include/sparc64-linux-gnu"
|
||||
};
|
||||
ArrayRef<StringRef> MultiarchIncludeDirs;
|
||||
if (getTriple().getArch() == llvm::Triple::x86_64) {
|
||||
MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
|
||||
@ -3484,6 +3503,10 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
|
||||
} else if (getTriple().getArch() == llvm::Triple::ppc64le) {
|
||||
MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs;
|
||||
} else if (getTriple().getArch() == llvm::Triple::sparc) {
|
||||
MultiarchIncludeDirs = SparcMultiarchIncludeDirs;
|
||||
} else if (getTriple().getArch() == llvm::Triple::sparcv9) {
|
||||
MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs;
|
||||
}
|
||||
for (StringRef Dir : MultiarchIncludeDirs) {
|
||||
if (llvm::sys::fs::exists(SysRoot + Dir)) {
|
||||
@ -3695,8 +3718,8 @@ void XCore::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
}
|
||||
}
|
||||
|
||||
void XCore::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const {
|
||||
void XCore::addClangTargetOptions(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const {
|
||||
CC1Args.push_back("-nostdsysteminc");
|
||||
}
|
||||
|
||||
|
@ -807,6 +807,9 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
|
||||
bool getVisualStudioBinariesFolder(const char *clangProgramPath,
|
||||
std::string &path) const;
|
||||
|
||||
std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
|
||||
types::ID InputType) const override;
|
||||
|
||||
protected:
|
||||
void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,6 +10,7 @@
|
||||
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLS_H
|
||||
#define LLVM_CLANG_LIB_DRIVER_TOOLS_H
|
||||
|
||||
#include "clang/Basic/VersionTuple.h"
|
||||
#include "clang/Driver/Tool.h"
|
||||
#include "clang/Driver/Types.h"
|
||||
#include "clang/Driver/Util.h"
|
||||
@ -224,8 +225,8 @@ namespace hexagon {
|
||||
} // end namespace hexagon.
|
||||
|
||||
namespace arm {
|
||||
StringRef getARMTargetCPU(const llvm::opt::ArgList &Args,
|
||||
const llvm::Triple &Triple);
|
||||
std::string getARMTargetCPU(const llvm::opt::ArgList &Args,
|
||||
const llvm::Triple &Triple);
|
||||
const StringRef getARMArch(const llvm::opt::ArgList &Args,
|
||||
const llvm::Triple &Triple);
|
||||
const char* getARMCPUForMArch(const llvm::opt::ArgList &Args,
|
||||
@ -630,6 +631,10 @@ namespace dragonfly {
|
||||
|
||||
/// Visual studio tools.
|
||||
namespace visualstudio {
|
||||
VersionTuple getMSVCVersion(const Driver *D, const llvm::Triple &Triple,
|
||||
const llvm::opt::ArgList &Args,
|
||||
bool IsWindowsMSVC);
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY Link : public Tool {
|
||||
public:
|
||||
Link(const ToolChain &TC) : Tool("visualstudio::Link", "linker", TC,
|
||||
@ -726,7 +731,7 @@ class LLVM_LIBRARY_VISIBILITY Link : public Tool {
|
||||
};
|
||||
}
|
||||
|
||||
} // end namespace toolchains
|
||||
} // end namespace tools
|
||||
} // end namespace driver
|
||||
} // end namespace clang
|
||||
|
||||
|
@ -45,7 +45,7 @@ types::ID types::getPreprocessedType(ID Id) {
|
||||
}
|
||||
|
||||
const char *types::getTypeTempSuffix(ID Id, bool CLMode) {
|
||||
if (Id == TY_Object && CLMode)
|
||||
if ((Id == TY_Object || Id == TY_LTO_BC) && CLMode)
|
||||
return "obj";
|
||||
if (Id == TY_Image && CLMode)
|
||||
return "exe";
|
||||
|
@ -183,7 +183,7 @@ void BreakableStringLiteral::insertBreak(unsigned LineIndex,
|
||||
}
|
||||
|
||||
static StringRef getLineCommentIndentPrefix(StringRef Comment) {
|
||||
static const char *const KnownPrefixes[] = { "///", "//" };
|
||||
static const char *const KnownPrefixes[] = { "///", "//", "//!" };
|
||||
StringRef LongestPrefix;
|
||||
for (StringRef KnownPrefix : KnownPrefixes) {
|
||||
if (Comment.startswith(KnownPrefix)) {
|
||||
@ -210,6 +210,8 @@ BreakableLineComment::BreakableLineComment(
|
||||
Prefix = "// ";
|
||||
else if (Prefix == "///")
|
||||
Prefix = "/// ";
|
||||
else if (Prefix == "//!")
|
||||
Prefix = "//! ";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,8 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
|
||||
if (((Previous.is(TT_DictLiteral) && Previous.is(tok::l_brace)) ||
|
||||
Previous.is(TT_ArrayInitializerLSquare)) &&
|
||||
Style.ColumnLimit > 0 &&
|
||||
getLengthToMatchingParen(Previous) + State.Column > getColumnLimit(State))
|
||||
getLengthToMatchingParen(Previous) + State.Column - 1 >
|
||||
getColumnLimit(State))
|
||||
return true;
|
||||
if (Current.is(TT_CtorInitializerColon) &&
|
||||
((Style.AllowShortFunctionsOnASingleLine != FormatStyle::SFS_All) ||
|
||||
@ -328,7 +329,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
|
||||
State.Column > getNewLineColumn(State))
|
||||
State.Stack.back().ContainsUnwrappedBuilder = true;
|
||||
|
||||
if (Current.is(TT_LambdaArrow))
|
||||
if (Current.is(TT_LambdaArrow) && Style.Language == FormatStyle::LK_Java)
|
||||
State.Stack.back().NoLineBreak = true;
|
||||
if (Current.isMemberAccess() && Previous.is(tok::r_paren) &&
|
||||
(Previous.MatchingParen &&
|
||||
@ -462,6 +463,8 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
|
||||
if (NextNonComment->is(tok::question) ||
|
||||
(PreviousNonComment && PreviousNonComment->is(tok::question)))
|
||||
State.Stack.back().BreakBeforeParameter = true;
|
||||
if (Current.is(TT_BinaryOperator) && Current.CanBreakBefore)
|
||||
State.Stack.back().BreakBeforeParameter = false;
|
||||
|
||||
if (!DryRun) {
|
||||
unsigned Newlines = std::max(
|
||||
@ -481,11 +484,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
|
||||
bool NestedBlockSpecialCase =
|
||||
Current.is(tok::r_brace) && State.Stack.size() > 1 &&
|
||||
State.Stack[State.Stack.size() - 2].NestedBlockInlined;
|
||||
if (!NestedBlockSpecialCase) {
|
||||
for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
|
||||
if (!NestedBlockSpecialCase)
|
||||
for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i)
|
||||
State.Stack[i].BreakBeforeParameter = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (PreviousNonComment &&
|
||||
!PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
|
||||
@ -689,11 +690,9 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
|
||||
// }, a, b, c);
|
||||
if (Current.isNot(tok::comment) && Previous && Previous->is(tok::l_brace) &&
|
||||
State.Stack.size() > 1) {
|
||||
if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline) {
|
||||
for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
|
||||
if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline)
|
||||
for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i)
|
||||
State.Stack[i].NoLineBreak = true;
|
||||
}
|
||||
}
|
||||
State.Stack[State.Stack.size() - 2].NestedBlockInlined = false;
|
||||
}
|
||||
if (Previous && (Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) ||
|
||||
|
@ -297,11 +297,11 @@ struct ParenState {
|
||||
if (VariablePos != Other.VariablePos)
|
||||
return VariablePos < Other.VariablePos;
|
||||
if (ContainsLineBreak != Other.ContainsLineBreak)
|
||||
return ContainsLineBreak < Other.ContainsLineBreak;
|
||||
return ContainsLineBreak;
|
||||
if (ContainsUnwrappedBuilder != Other.ContainsUnwrappedBuilder)
|
||||
return ContainsUnwrappedBuilder < Other.ContainsUnwrappedBuilder;
|
||||
return ContainsUnwrappedBuilder;
|
||||
if (NestedBlockInlined != Other.NestedBlockInlined)
|
||||
return NestedBlockInlined < Other.NestedBlockInlined;
|
||||
return NestedBlockInlined;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
@ -1640,8 +1640,6 @@ FormatStyle getStyle(StringRef StyleName, StringRef FileName,
|
||||
return Style;
|
||||
}
|
||||
}
|
||||
llvm::errs() << "Can't find usable .clang-format, using " << FallbackStyle
|
||||
<< " style\n";
|
||||
if (!UnsuitableConfigFiles.empty()) {
|
||||
llvm::errs() << "Configuration file(s) do(es) not support "
|
||||
<< getLanguageName(Style.Language) << ": "
|
||||
|
@ -51,6 +51,7 @@ enum TokenType {
|
||||
TT_InlineASMBrace,
|
||||
TT_InlineASMColon,
|
||||
TT_JavaAnnotation,
|
||||
TT_JsComputedPropertyName,
|
||||
TT_JsFatArrow,
|
||||
TT_JsTypeColon,
|
||||
TT_JsTypeOptionalQuestion,
|
||||
|
@ -260,6 +260,7 @@ class AnnotatingParser {
|
||||
Left->ParentBracket = Contexts.back().ContextKind;
|
||||
FormatToken *Parent = Left->getPreviousNonComment();
|
||||
bool StartsObjCMethodExpr =
|
||||
Style.Language == FormatStyle::LK_Cpp &&
|
||||
Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
|
||||
CurrentToken->isNot(tok::l_brace) &&
|
||||
(!Parent ||
|
||||
@ -268,19 +269,31 @@ class AnnotatingParser {
|
||||
Parent->isUnaryOperator() ||
|
||||
Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
|
||||
getBinOpPrecedence(Parent->Tok.getKind(), true, true) > prec::Unknown);
|
||||
ScopedContextCreator ContextCreator(*this, tok::l_square, 10);
|
||||
Contexts.back().IsExpression = true;
|
||||
bool ColonFound = false;
|
||||
|
||||
if (StartsObjCMethodExpr) {
|
||||
Contexts.back().ColonIsObjCMethodExpr = true;
|
||||
Left->Type = TT_ObjCMethodExpr;
|
||||
} else if (Parent && Parent->is(tok::at)) {
|
||||
Left->Type = TT_ArrayInitializerLSquare;
|
||||
} else if (Left->is(TT_Unknown)) {
|
||||
Left->Type = TT_ArraySubscriptLSquare;
|
||||
unsigned BindingIncrease = 1;
|
||||
if (Left->is(TT_Unknown)) {
|
||||
if (StartsObjCMethodExpr) {
|
||||
Left->Type = TT_ObjCMethodExpr;
|
||||
} else if (Style.Language == FormatStyle::LK_JavaScript && Parent &&
|
||||
Contexts.back().ContextKind == tok::l_brace &&
|
||||
Parent->isOneOf(tok::l_brace, tok::comma)) {
|
||||
Left->Type = TT_JsComputedPropertyName;
|
||||
} else if (Parent &&
|
||||
Parent->isOneOf(tok::at, tok::equal, tok::comma, tok::l_paren,
|
||||
tok::l_square, tok::question, tok::colon,
|
||||
tok::kw_return)) {
|
||||
Left->Type = TT_ArrayInitializerLSquare;
|
||||
} else {
|
||||
BindingIncrease = 10;
|
||||
Left->Type = TT_ArraySubscriptLSquare;
|
||||
}
|
||||
}
|
||||
|
||||
ScopedContextCreator ContextCreator(*this, tok::l_square, BindingIncrease);
|
||||
Contexts.back().IsExpression = true;
|
||||
Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
|
||||
|
||||
while (CurrentToken) {
|
||||
if (CurrentToken->is(tok::r_square)) {
|
||||
if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren) &&
|
||||
@ -321,10 +334,8 @@ class AnnotatingParser {
|
||||
}
|
||||
ColonFound = true;
|
||||
}
|
||||
if (CurrentToken->is(tok::comma) &&
|
||||
Style.Language != FormatStyle::LK_Proto &&
|
||||
(Left->is(TT_ArraySubscriptLSquare) ||
|
||||
(Left->is(TT_ObjCMethodExpr) && !ColonFound)))
|
||||
if (CurrentToken->is(tok::comma) && Left->is(TT_ObjCMethodExpr) &&
|
||||
!ColonFound)
|
||||
Left->Type = TT_ArrayInitializerLSquare;
|
||||
FormatToken *Tok = CurrentToken;
|
||||
if (!consumeToken())
|
||||
@ -437,7 +448,8 @@ class AnnotatingParser {
|
||||
!Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
|
||||
Contexts.back().ContextKind == tok::l_paren || // function params
|
||||
Contexts.back().ContextKind == tok::l_square || // array type
|
||||
Line.MustBeDeclaration) { // method/property declaration
|
||||
(Contexts.size() == 1 &&
|
||||
Line.MustBeDeclaration)) { // method/property declaration
|
||||
Tok->Type = TT_JsTypeColon;
|
||||
break;
|
||||
}
|
||||
@ -742,8 +754,8 @@ class AnnotatingParser {
|
||||
// recovered from an error (e.g. failure to find the matching >).
|
||||
if (!CurrentToken->isOneOf(TT_LambdaLSquare, TT_ForEachMacro,
|
||||
TT_FunctionLBrace, TT_ImplicitStringLiteral,
|
||||
TT_InlineASMBrace, TT_RegexLiteral,
|
||||
TT_TrailingReturnArrow))
|
||||
TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow,
|
||||
TT_RegexLiteral))
|
||||
CurrentToken->Type = TT_Unknown;
|
||||
CurrentToken->Role.reset();
|
||||
CurrentToken->MatchingParen = nullptr;
|
||||
@ -832,6 +844,8 @@ class AnnotatingParser {
|
||||
Contexts.back().IsExpression = true;
|
||||
} else if (Current.is(TT_TrailingReturnArrow)) {
|
||||
Contexts.back().IsExpression = false;
|
||||
} else if (Current.is(TT_LambdaArrow)) {
|
||||
Contexts.back().IsExpression = Style.Language == FormatStyle::LK_Java;
|
||||
} else if (Current.is(tok::l_paren) && !Line.MustBeDeclaration &&
|
||||
!Line.InPPDirective &&
|
||||
(!Current.Previous ||
|
||||
@ -1308,25 +1322,27 @@ class ExpressionParser {
|
||||
const FormatToken *NextNonComment = Current->getNextNonComment();
|
||||
if (Current->is(TT_ConditionalExpr))
|
||||
return prec::Conditional;
|
||||
else if (NextNonComment && NextNonComment->is(tok::colon) &&
|
||||
NextNonComment->is(TT_DictLiteral))
|
||||
if (NextNonComment && NextNonComment->is(tok::colon) &&
|
||||
NextNonComment->is(TT_DictLiteral))
|
||||
return prec::Comma;
|
||||
else if (Current->is(TT_LambdaArrow))
|
||||
if (Current->is(TT_LambdaArrow))
|
||||
return prec::Comma;
|
||||
else if (Current->isOneOf(tok::semi, TT_InlineASMColon,
|
||||
TT_SelectorName) ||
|
||||
(Current->is(tok::comment) && NextNonComment &&
|
||||
NextNonComment->is(TT_SelectorName)))
|
||||
if (Current->is(TT_JsFatArrow))
|
||||
return prec::Assignment;
|
||||
if (Current->isOneOf(tok::semi, TT_InlineASMColon, TT_SelectorName,
|
||||
TT_JsComputedPropertyName) ||
|
||||
(Current->is(tok::comment) && NextNonComment &&
|
||||
NextNonComment->is(TT_SelectorName)))
|
||||
return 0;
|
||||
else if (Current->is(TT_RangeBasedForLoopColon))
|
||||
if (Current->is(TT_RangeBasedForLoopColon))
|
||||
return prec::Comma;
|
||||
else if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
|
||||
if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
|
||||
return Current->getPrecedence();
|
||||
else if (Current->isOneOf(tok::period, tok::arrow))
|
||||
if (Current->isOneOf(tok::period, tok::arrow))
|
||||
return PrecedenceArrowAndPeriod;
|
||||
else if (Style.Language == FormatStyle::LK_Java &&
|
||||
Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
|
||||
Keywords.kw_throws))
|
||||
if (Style.Language == FormatStyle::LK_Java &&
|
||||
Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
|
||||
Keywords.kw_throws))
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
@ -1615,7 +1631,8 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
|
||||
// Slightly prefer formatting local lambda definitions like functions.
|
||||
if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal))
|
||||
return 50;
|
||||
if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare))
|
||||
if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
|
||||
TT_ArrayInitializerLSquare))
|
||||
return 500;
|
||||
}
|
||||
|
||||
@ -1631,7 +1648,7 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
|
||||
}
|
||||
if (Right.is(TT_PointerOrReference))
|
||||
return 190;
|
||||
if (Right.is(TT_TrailingReturnArrow))
|
||||
if (Right.is(TT_LambdaArrow))
|
||||
return 110;
|
||||
if (Left.is(tok::equal) && Right.is(tok::l_brace))
|
||||
return 150;
|
||||
@ -1867,7 +1884,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
|
||||
Left.isOneOf(Keywords.kw_returns, Keywords.kw_option))
|
||||
return true;
|
||||
} else if (Style.Language == FormatStyle::LK_JavaScript) {
|
||||
if (Left.is(Keywords.kw_var))
|
||||
if (Left.isOneOf(Keywords.kw_var, TT_JsFatArrow))
|
||||
return true;
|
||||
if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion))
|
||||
return false;
|
||||
@ -1886,8 +1903,6 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
|
||||
} else if (Style.Language == FormatStyle::LK_Java) {
|
||||
if (Left.is(tok::r_square) && Right.is(tok::l_brace))
|
||||
return true;
|
||||
if (Left.is(TT_LambdaArrow) || Right.is(TT_LambdaArrow))
|
||||
return true;
|
||||
if (Left.is(Keywords.kw_synchronized) && Right.is(tok::l_paren))
|
||||
return Style.SpaceBeforeParens != FormatStyle::SBPO_Never;
|
||||
if ((Left.isOneOf(tok::kw_static, tok::kw_public, tok::kw_private,
|
||||
@ -1912,7 +1927,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
|
||||
(Right.is(tok::equal) || Left.is(tok::equal)))
|
||||
return false;
|
||||
|
||||
if (Right.is(TT_TrailingReturnArrow) || Left.is(TT_TrailingReturnArrow))
|
||||
if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
|
||||
Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow))
|
||||
return true;
|
||||
if (Left.is(tok::comma))
|
||||
return true;
|
||||
@ -1947,10 +1963,9 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
|
||||
return Style.SpaceAfterCStyleCast ||
|
||||
Right.isOneOf(TT_BinaryOperator, TT_SelectorName);
|
||||
|
||||
if (Left.is(tok::greater) && Right.is(tok::greater)) {
|
||||
if (Left.is(tok::greater) && Right.is(tok::greater))
|
||||
return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
|
||||
(Style.Standard != FormatStyle::LS_Cpp11 || Style.SpacesInAngles);
|
||||
}
|
||||
if (Right.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
|
||||
Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar))
|
||||
return false;
|
||||
@ -2094,6 +2109,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
|
||||
const FormatToken &Right) {
|
||||
const FormatToken &Left = *Right.Previous;
|
||||
|
||||
// Language-specific stuff.
|
||||
if (Style.Language == FormatStyle::LK_Java) {
|
||||
if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
|
||||
Keywords.kw_implements))
|
||||
@ -2101,6 +2117,9 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
|
||||
if (Right.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
|
||||
Keywords.kw_implements))
|
||||
return true;
|
||||
} else if (Style.Language == FormatStyle::LK_JavaScript) {
|
||||
if (Left.is(TT_JsFatArrow) && Right.is(tok::l_brace))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Left.is(tok::at))
|
||||
|
@ -887,9 +887,8 @@ void UnwrappedLineParser::parseStructuralElement() {
|
||||
// followed by a curly.
|
||||
if (FormatTok->is(TT_JsFatArrow)) {
|
||||
nextToken();
|
||||
if (FormatTok->is(tok::l_brace)) {
|
||||
if (FormatTok->is(tok::l_brace))
|
||||
parseChildBlock();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -912,6 +911,10 @@ void UnwrappedLineParser::parseStructuralElement() {
|
||||
}
|
||||
|
||||
bool UnwrappedLineParser::tryToParseLambda() {
|
||||
if (Style.Language != FormatStyle::LK_Cpp) {
|
||||
nextToken();
|
||||
return false;
|
||||
}
|
||||
// FIXME: This is a dirty way to access the previous token. Find a better
|
||||
// solution.
|
||||
if (!Line->Tokens.empty() &&
|
||||
@ -950,7 +953,7 @@ bool UnwrappedLineParser::tryToParseLambda() {
|
||||
nextToken();
|
||||
break;
|
||||
case tok::arrow:
|
||||
FormatTok->Type = TT_TrailingReturnArrow;
|
||||
FormatTok->Type = TT_LambdaArrow;
|
||||
nextToken();
|
||||
break;
|
||||
default:
|
||||
@ -1019,7 +1022,7 @@ void UnwrappedLineParser::tryToParseJSFunction() {
|
||||
return;
|
||||
|
||||
// Parse formal parameter list.
|
||||
parseBalanced(tok::l_paren, tok::r_paren);
|
||||
parseParens();
|
||||
|
||||
if (FormatTok->is(tok::colon)) {
|
||||
// Parse a type definition.
|
||||
@ -1027,34 +1030,16 @@ void UnwrappedLineParser::tryToParseJSFunction() {
|
||||
|
||||
// Eat the type declaration. For braced inline object types, balance braces,
|
||||
// otherwise just parse until finding an l_brace for the function body.
|
||||
if (FormatTok->is(tok::l_brace)) {
|
||||
parseBalanced(tok::l_brace, tok::r_brace);
|
||||
} else {
|
||||
while(FormatTok->isNot(tok::l_brace) && !eof()) {
|
||||
if (FormatTok->is(tok::l_brace))
|
||||
tryToParseBracedList();
|
||||
else
|
||||
while(FormatTok->isNot(tok::l_brace) && !eof())
|
||||
nextToken();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parseChildBlock();
|
||||
}
|
||||
|
||||
void UnwrappedLineParser::parseBalanced(tok::TokenKind OpenKind,
|
||||
tok::TokenKind CloseKind) {
|
||||
assert(FormatTok->is(OpenKind));
|
||||
nextToken();
|
||||
int Depth = 1;
|
||||
while (Depth > 0 && !eof()) {
|
||||
// Parse the formal parameter list.
|
||||
if (FormatTok->is(OpenKind)) {
|
||||
++Depth;
|
||||
} else if (FormatTok->is(CloseKind)) {
|
||||
--Depth;
|
||||
}
|
||||
nextToken();
|
||||
}
|
||||
}
|
||||
|
||||
bool UnwrappedLineParser::tryToParseBracedList() {
|
||||
if (FormatTok->BlockKind == BK_Unknown)
|
||||
calculateBraceTypes();
|
||||
@ -1076,7 +1061,8 @@ bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
|
||||
if (FormatTok->is(Keywords.kw_function)) {
|
||||
tryToParseJSFunction();
|
||||
continue;
|
||||
} else if (FormatTok->is(TT_JsFatArrow)) {
|
||||
}
|
||||
if (FormatTok->is(TT_JsFatArrow)) {
|
||||
nextToken();
|
||||
// Fat arrows can be followed by simple expressions or by child blocks
|
||||
// in curly braces.
|
||||
@ -1780,15 +1766,12 @@ void UnwrappedLineParser::addUnwrappedLine() {
|
||||
if (CurrentLines == &Lines)
|
||||
printDebugInfo(*Line);
|
||||
});
|
||||
CurrentLines->push_back(*Line);
|
||||
CurrentLines->push_back(std::move(*Line));
|
||||
Line->Tokens.clear();
|
||||
if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
|
||||
for (SmallVectorImpl<UnwrappedLine>::iterator
|
||||
I = PreprocessorDirectives.begin(),
|
||||
E = PreprocessorDirectives.end();
|
||||
I != E; ++I) {
|
||||
CurrentLines->push_back(*I);
|
||||
}
|
||||
CurrentLines->append(
|
||||
std::make_move_iterator(PreprocessorDirectives.begin()),
|
||||
std::make_move_iterator(PreprocessorDirectives.end()));
|
||||
PreprocessorDirectives.clear();
|
||||
}
|
||||
}
|
||||
|
@ -107,11 +107,6 @@ class UnwrappedLineParser {
|
||||
bool tryToParseLambda();
|
||||
bool tryToParseLambdaIntroducer();
|
||||
void tryToParseJSFunction();
|
||||
/// \brief Parses tokens until encountering the CloseKind token, but balances
|
||||
/// tokens when encountering more OpenKind tokens. Useful for e.g. parsing a
|
||||
/// curly brace delimited block that can contain nested blocks.
|
||||
/// The parser must be positioned on a token of OpenKind.
|
||||
void parseBalanced(tok::TokenKind OpenKind, tok::TokenKind CloseKind);
|
||||
void addUnwrappedLine();
|
||||
bool eof() const;
|
||||
void nextToken();
|
||||
|
@ -402,7 +402,7 @@ void WhitespaceManager::appendNewlineText(std::string &Text, unsigned Newlines,
|
||||
unsigned Offset =
|
||||
std::min<int>(EscapedNewlineColumn - 1, PreviousEndOfTokenColumn);
|
||||
for (unsigned i = 0; i < Newlines; ++i) {
|
||||
Text.append(std::string(EscapedNewlineColumn - Offset - 1, ' '));
|
||||
Text.append(EscapedNewlineColumn - Offset - 1, ' ');
|
||||
Text.append(UseCRLF ? "\\\r\n" : "\\\n");
|
||||
Offset = 0;
|
||||
}
|
||||
@ -414,7 +414,7 @@ void WhitespaceManager::appendIndentText(std::string &Text,
|
||||
unsigned WhitespaceStartColumn) {
|
||||
switch (Style.UseTab) {
|
||||
case FormatStyle::UT_Never:
|
||||
Text.append(std::string(Spaces, ' '));
|
||||
Text.append(Spaces, ' ');
|
||||
break;
|
||||
case FormatStyle::UT_Always: {
|
||||
unsigned FirstTabWidth =
|
||||
@ -424,8 +424,8 @@ void WhitespaceManager::appendIndentText(std::string &Text,
|
||||
Spaces -= FirstTabWidth;
|
||||
Text.append("\t");
|
||||
}
|
||||
Text.append(std::string(Spaces / Style.TabWidth, '\t'));
|
||||
Text.append(std::string(Spaces % Style.TabWidth, ' '));
|
||||
Text.append(Spaces / Style.TabWidth, '\t');
|
||||
Text.append(Spaces % Style.TabWidth, ' ');
|
||||
break;
|
||||
}
|
||||
case FormatStyle::UT_ForIndentation:
|
||||
@ -436,10 +436,10 @@ void WhitespaceManager::appendIndentText(std::string &Text,
|
||||
if (Indentation > Spaces)
|
||||
Indentation = Spaces;
|
||||
unsigned Tabs = Indentation / Style.TabWidth;
|
||||
Text.append(std::string(Tabs, '\t'));
|
||||
Text.append(Tabs, '\t');
|
||||
Spaces -= Tabs * Style.TabWidth;
|
||||
}
|
||||
Text.append(std::string(Spaces, ' '));
|
||||
Text.append(Spaces, ' ');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -613,7 +613,7 @@ void StoredDiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level Level,
|
||||
// about. This effectively drops diagnostics from modules we're building.
|
||||
// FIXME: In the long run, ee don't want to drop source managers from modules.
|
||||
if (!Info.hasSourceManager() || &Info.getSourceManager() == SourceMgr)
|
||||
StoredDiags.push_back(StoredDiagnostic(Level, Info));
|
||||
StoredDiags.emplace_back(Level, Info);
|
||||
}
|
||||
|
||||
ASTMutationListener *ASTUnit::getASTMutationListener() {
|
||||
|
@ -946,12 +946,11 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance,
|
||||
if (const FileEntry *ModuleMapFile =
|
||||
ModMap.getContainingModuleMapFile(Module)) {
|
||||
// Use the module map where this module resides.
|
||||
FrontendOpts.Inputs.push_back(
|
||||
FrontendInputFile(ModuleMapFile->getName(), IK));
|
||||
FrontendOpts.Inputs.emplace_back(ModuleMapFile->getName(), IK);
|
||||
} else {
|
||||
SmallString<128> FakeModuleMapFile(Module->Directory->getName());
|
||||
llvm::sys::path::append(FakeModuleMapFile, "__inferred_module.map");
|
||||
FrontendOpts.Inputs.push_back(FrontendInputFile(FakeModuleMapFile, IK));
|
||||
FrontendOpts.Inputs.emplace_back(FakeModuleMapFile, IK);
|
||||
|
||||
llvm::raw_string_ostream OS(InferredModuleMapContent);
|
||||
Module->print(OS);
|
||||
|
@ -126,7 +126,7 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
|
||||
} else {
|
||||
// Otherwise, add its value (for OPT_W_Joined and similar).
|
||||
for (const char *Arg : A->getValues())
|
||||
Diagnostics.push_back(Arg);
|
||||
Diagnostics.emplace_back(Arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -239,10 +239,8 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
|
||||
Opts.InlineMaxStackDepth, Diags);
|
||||
|
||||
Opts.CheckersControlList.clear();
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_analyzer_checker,
|
||||
OPT_analyzer_disable_checker),
|
||||
ie = Args.filtered_end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
for (const Arg *A :
|
||||
Args.filtered(OPT_analyzer_checker, OPT_analyzer_disable_checker)) {
|
||||
A->claim();
|
||||
bool enable = (A->getOption().getID() == OPT_analyzer_checker);
|
||||
// We can have a list of comma separated checker names, e.g:
|
||||
@ -250,14 +248,12 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
|
||||
StringRef checkerList = A->getValue();
|
||||
SmallVector<StringRef, 4> checkers;
|
||||
checkerList.split(checkers, ",");
|
||||
for (unsigned i = 0, e = checkers.size(); i != e; ++i)
|
||||
Opts.CheckersControlList.push_back(std::make_pair(checkers[i], enable));
|
||||
for (StringRef checker : checkers)
|
||||
Opts.CheckersControlList.emplace_back(checker, enable);
|
||||
}
|
||||
|
||||
// Go through the analyzer configuration options.
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_analyzer_config),
|
||||
ie = Args.filtered_end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
for (const Arg *A : Args.filtered(OPT_analyzer_config)) {
|
||||
A->claim();
|
||||
// We can have a list of comma separated config names, e.g:
|
||||
// '-analyzer-config key1=val1,key2=val2'
|
||||
@ -429,7 +425,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
|
||||
Opts.Autolink = !Args.hasArg(OPT_fno_autolink);
|
||||
Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ);
|
||||
Opts.ProfileInstrGenerate = Args.hasArg(OPT_fprofile_instr_generate) ||
|
||||
Args.hasArg(OPT_fprofile_instr_generate_EQ);;
|
||||
Args.hasArg(OPT_fprofile_instr_generate_EQ);
|
||||
Opts.InstrProfileOutput = Args.getLastArgValue(OPT_fprofile_instr_generate_EQ);
|
||||
Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ);
|
||||
Opts.CoverageMapping = Args.hasArg(OPT_fcoverage_mapping);
|
||||
@ -867,26 +863,21 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
|
||||
}
|
||||
|
||||
if (const Arg* A = Args.getLastArg(OPT_plugin)) {
|
||||
Opts.Plugins.push_back(A->getValue(0));
|
||||
Opts.Plugins.emplace_back(A->getValue(0));
|
||||
Opts.ProgramAction = frontend::PluginAction;
|
||||
Opts.ActionName = A->getValue();
|
||||
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_plugin_arg),
|
||||
end = Args.filtered_end(); it != end; ++it) {
|
||||
if ((*it)->getValue(0) == Opts.ActionName)
|
||||
Opts.PluginArgs.push_back((*it)->getValue(1));
|
||||
}
|
||||
for (const Arg *AA : Args.filtered(OPT_plugin_arg))
|
||||
if (AA->getValue(0) == Opts.ActionName)
|
||||
Opts.PluginArgs.emplace_back(AA->getValue(1));
|
||||
}
|
||||
|
||||
Opts.AddPluginActions = Args.getAllArgValues(OPT_add_plugin);
|
||||
Opts.AddPluginArgs.resize(Opts.AddPluginActions.size());
|
||||
for (int i = 0, e = Opts.AddPluginActions.size(); i != e; ++i) {
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_plugin_arg),
|
||||
end = Args.filtered_end(); it != end; ++it) {
|
||||
if ((*it)->getValue(0) == Opts.AddPluginActions[i])
|
||||
Opts.AddPluginArgs[i].push_back((*it)->getValue(1));
|
||||
}
|
||||
}
|
||||
for (int i = 0, e = Opts.AddPluginActions.size(); i != e; ++i)
|
||||
for (const Arg *A : Args.filtered(OPT_plugin_arg))
|
||||
if (A->getValue(0) == Opts.AddPluginActions[i])
|
||||
Opts.AddPluginArgs[i].emplace_back(A->getValue(1));
|
||||
|
||||
if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
|
||||
Opts.CodeCompletionAt =
|
||||
@ -1035,7 +1026,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
|
||||
if (i == 0)
|
||||
DashX = IK;
|
||||
}
|
||||
Opts.Inputs.push_back(FrontendInputFile(Inputs[i], IK));
|
||||
Opts.Inputs.emplace_back(std::move(Inputs[i]), IK);
|
||||
}
|
||||
|
||||
return DashX;
|
||||
@ -1088,98 +1079,77 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
|
||||
Opts.ModulesValidateSystemHeaders =
|
||||
Args.hasArg(OPT_fmodules_validate_system_headers);
|
||||
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_fmodules_ignore_macro),
|
||||
ie = Args.filtered_end();
|
||||
it != ie; ++it) {
|
||||
StringRef MacroDef = (*it)->getValue();
|
||||
for (const Arg *A : Args.filtered(OPT_fmodules_ignore_macro)) {
|
||||
StringRef MacroDef = A->getValue();
|
||||
Opts.ModulesIgnoreMacros.insert(MacroDef.split('=').first);
|
||||
}
|
||||
|
||||
// Add -I..., -F..., and -index-header-map options in order.
|
||||
bool IsIndexHeaderMap = false;
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_I, OPT_F,
|
||||
OPT_index_header_map),
|
||||
ie = Args.filtered_end(); it != ie; ++it) {
|
||||
if ((*it)->getOption().matches(OPT_index_header_map)) {
|
||||
for (const Arg *A : Args.filtered(OPT_I, OPT_F, OPT_index_header_map)) {
|
||||
if (A->getOption().matches(OPT_index_header_map)) {
|
||||
// -index-header-map applies to the next -I or -F.
|
||||
IsIndexHeaderMap = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
frontend::IncludeDirGroup Group
|
||||
= IsIndexHeaderMap? frontend::IndexHeaderMap : frontend::Angled;
|
||||
|
||||
Opts.AddPath((*it)->getValue(), Group,
|
||||
/*IsFramework=*/ (*it)->getOption().matches(OPT_F), true);
|
||||
|
||||
frontend::IncludeDirGroup Group =
|
||||
IsIndexHeaderMap ? frontend::IndexHeaderMap : frontend::Angled;
|
||||
|
||||
Opts.AddPath(A->getValue(), Group,
|
||||
/*IsFramework=*/A->getOption().matches(OPT_F), true);
|
||||
IsIndexHeaderMap = false;
|
||||
}
|
||||
|
||||
// Add -iprefix/-iwithprefix/-iwithprefixbefore options.
|
||||
StringRef Prefix = ""; // FIXME: This isn't the correct default prefix.
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_iprefix, OPT_iwithprefix,
|
||||
OPT_iwithprefixbefore),
|
||||
ie = Args.filtered_end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
for (const Arg *A :
|
||||
Args.filtered(OPT_iprefix, OPT_iwithprefix, OPT_iwithprefixbefore)) {
|
||||
if (A->getOption().matches(OPT_iprefix))
|
||||
Prefix = A->getValue();
|
||||
else if (A->getOption().matches(OPT_iwithprefix))
|
||||
Opts.AddPath(Prefix.str() + A->getValue(),
|
||||
frontend::After, false, true);
|
||||
Opts.AddPath(Prefix.str() + A->getValue(), frontend::After, false, true);
|
||||
else
|
||||
Opts.AddPath(Prefix.str() + A->getValue(),
|
||||
frontend::Angled, false, true);
|
||||
Opts.AddPath(Prefix.str() + A->getValue(), frontend::Angled, false, true);
|
||||
}
|
||||
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_idirafter),
|
||||
ie = Args.filtered_end(); it != ie; ++it)
|
||||
Opts.AddPath((*it)->getValue(), frontend::After, false, true);
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_iquote),
|
||||
ie = Args.filtered_end(); it != ie; ++it)
|
||||
Opts.AddPath((*it)->getValue(), frontend::Quoted, false, true);
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_isystem,
|
||||
OPT_iwithsysroot), ie = Args.filtered_end(); it != ie; ++it)
|
||||
Opts.AddPath((*it)->getValue(), frontend::System, false,
|
||||
!(*it)->getOption().matches(OPT_iwithsysroot));
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_iframework),
|
||||
ie = Args.filtered_end(); it != ie; ++it)
|
||||
Opts.AddPath((*it)->getValue(), frontend::System, true, true);
|
||||
for (const Arg *A : Args.filtered(OPT_idirafter))
|
||||
Opts.AddPath(A->getValue(), frontend::After, false, true);
|
||||
for (const Arg *A : Args.filtered(OPT_iquote))
|
||||
Opts.AddPath(A->getValue(), frontend::Quoted, false, true);
|
||||
for (const Arg *A : Args.filtered(OPT_isystem, OPT_iwithsysroot))
|
||||
Opts.AddPath(A->getValue(), frontend::System, false,
|
||||
!A->getOption().matches(OPT_iwithsysroot));
|
||||
for (const Arg *A : Args.filtered(OPT_iframework))
|
||||
Opts.AddPath(A->getValue(), frontend::System, true, true);
|
||||
|
||||
// Add the paths for the various language specific isystem flags.
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_c_isystem),
|
||||
ie = Args.filtered_end(); it != ie; ++it)
|
||||
Opts.AddPath((*it)->getValue(), frontend::CSystem, false, true);
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_cxx_isystem),
|
||||
ie = Args.filtered_end(); it != ie; ++it)
|
||||
Opts.AddPath((*it)->getValue(), frontend::CXXSystem, false, true);
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_objc_isystem),
|
||||
ie = Args.filtered_end(); it != ie; ++it)
|
||||
Opts.AddPath((*it)->getValue(), frontend::ObjCSystem, false,true);
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_objcxx_isystem),
|
||||
ie = Args.filtered_end(); it != ie; ++it)
|
||||
Opts.AddPath((*it)->getValue(), frontend::ObjCXXSystem, false, true);
|
||||
for (const Arg *A : Args.filtered(OPT_c_isystem))
|
||||
Opts.AddPath(A->getValue(), frontend::CSystem, false, true);
|
||||
for (const Arg *A : Args.filtered(OPT_cxx_isystem))
|
||||
Opts.AddPath(A->getValue(), frontend::CXXSystem, false, true);
|
||||
for (const Arg *A : Args.filtered(OPT_objc_isystem))
|
||||
Opts.AddPath(A->getValue(), frontend::ObjCSystem, false,true);
|
||||
for (const Arg *A : Args.filtered(OPT_objcxx_isystem))
|
||||
Opts.AddPath(A->getValue(), frontend::ObjCXXSystem, false, true);
|
||||
|
||||
// Add the internal paths from a driver that detects standard include paths.
|
||||
for (arg_iterator I = Args.filtered_begin(OPT_internal_isystem,
|
||||
OPT_internal_externc_isystem),
|
||||
E = Args.filtered_end();
|
||||
I != E; ++I) {
|
||||
for (const Arg *A :
|
||||
Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
|
||||
frontend::IncludeDirGroup Group = frontend::System;
|
||||
if ((*I)->getOption().matches(OPT_internal_externc_isystem))
|
||||
if (A->getOption().matches(OPT_internal_externc_isystem))
|
||||
Group = frontend::ExternCSystem;
|
||||
Opts.AddPath((*I)->getValue(), Group, false, true);
|
||||
Opts.AddPath(A->getValue(), Group, false, true);
|
||||
}
|
||||
|
||||
// Add the path prefixes which are implicitly treated as being system headers.
|
||||
for (arg_iterator I = Args.filtered_begin(OPT_system_header_prefix,
|
||||
OPT_no_system_header_prefix),
|
||||
E = Args.filtered_end();
|
||||
I != E; ++I)
|
||||
for (const Arg *A :
|
||||
Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix))
|
||||
Opts.AddSystemHeaderPrefix(
|
||||
(*I)->getValue(), (*I)->getOption().matches(OPT_system_header_prefix));
|
||||
A->getValue(), A->getOption().matches(OPT_system_header_prefix));
|
||||
|
||||
for (arg_iterator I = Args.filtered_begin(OPT_ivfsoverlay),
|
||||
E = Args.filtered_end(); I != E; ++I)
|
||||
Opts.AddVFSOverlayFile((*I)->getValue());
|
||||
for (const Arg *A : Args.filtered(OPT_ivfsoverlay))
|
||||
Opts.AddVFSOverlayFile(A->getValue());
|
||||
}
|
||||
|
||||
void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
|
||||
@ -1708,11 +1678,8 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
|
||||
Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch);
|
||||
|
||||
Opts.DumpDeserializedPCHDecls = Args.hasArg(OPT_dump_deserialized_pch_decls);
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_error_on_deserialized_pch_decl),
|
||||
ie = Args.filtered_end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
for (const Arg *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
|
||||
Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue());
|
||||
}
|
||||
|
||||
if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
|
||||
StringRef Value(A->getValue());
|
||||
@ -1731,38 +1698,28 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
|
||||
}
|
||||
|
||||
// Add macros from the command line.
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_D, OPT_U),
|
||||
ie = Args.filtered_end(); it != ie; ++it) {
|
||||
if ((*it)->getOption().matches(OPT_D))
|
||||
Opts.addMacroDef((*it)->getValue());
|
||||
for (const Arg *A : Args.filtered(OPT_D, OPT_U)) {
|
||||
if (A->getOption().matches(OPT_D))
|
||||
Opts.addMacroDef(A->getValue());
|
||||
else
|
||||
Opts.addMacroUndef((*it)->getValue());
|
||||
Opts.addMacroUndef(A->getValue());
|
||||
}
|
||||
|
||||
Opts.MacroIncludes = Args.getAllArgValues(OPT_imacros);
|
||||
|
||||
// Add the ordered list of -includes.
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_include),
|
||||
ie = Args.filtered_end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
Opts.Includes.push_back(A->getValue());
|
||||
}
|
||||
for (const Arg *A : Args.filtered(OPT_include))
|
||||
Opts.Includes.emplace_back(A->getValue());
|
||||
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_chain_include),
|
||||
ie = Args.filtered_end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
Opts.ChainedIncludes.push_back(A->getValue());
|
||||
}
|
||||
for (const Arg *A : Args.filtered(OPT_chain_include))
|
||||
Opts.ChainedIncludes.emplace_back(A->getValue());
|
||||
|
||||
// Include 'altivec.h' if -faltivec option present
|
||||
if (Args.hasArg(OPT_faltivec))
|
||||
Opts.Includes.push_back("altivec.h");
|
||||
Opts.Includes.emplace_back("altivec.h");
|
||||
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_remap_file),
|
||||
ie = Args.filtered_end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
std::pair<StringRef,StringRef> Split =
|
||||
StringRef(A->getValue()).split(';');
|
||||
for (const Arg *A : Args.filtered(OPT_remap_file)) {
|
||||
std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';');
|
||||
|
||||
if (Split.second.empty()) {
|
||||
Diags.Report(diag::err_drv_invalid_remap_file) << A->getAsString(Args);
|
||||
@ -1771,7 +1728,7 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
|
||||
|
||||
Opts.addRemappedFile(Split.first, Split.second);
|
||||
}
|
||||
|
||||
|
||||
if (Arg *A = Args.getLastArg(OPT_fobjc_arc_cxxlib_EQ)) {
|
||||
StringRef Name = A->getValue();
|
||||
unsigned Library = llvm::StringSwitch<unsigned>(Name)
|
||||
@ -1874,24 +1831,22 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
|
||||
}
|
||||
|
||||
// Issue errors on unknown arguments.
|
||||
for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
|
||||
ie = Args->filtered_end(); it != ie; ++it) {
|
||||
Diags.Report(diag::err_drv_unknown_argument) << (*it)->getAsString(*Args);
|
||||
for (const Arg *A : Args->filtered(OPT_UNKNOWN)) {
|
||||
Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(*Args);
|
||||
Success = false;
|
||||
}
|
||||
|
||||
Success = ParseAnalyzerArgs(*Res.getAnalyzerOpts(), *Args, Diags) && Success;
|
||||
Success = ParseMigratorArgs(Res.getMigratorOpts(), *Args) && Success;
|
||||
Success &= ParseAnalyzerArgs(*Res.getAnalyzerOpts(), *Args, Diags);
|
||||
Success &= ParseMigratorArgs(Res.getMigratorOpts(), *Args);
|
||||
ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *Args);
|
||||
Success = ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, &Diags)
|
||||
&& Success;
|
||||
Success &= ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, &Diags);
|
||||
ParseCommentArgs(Res.getLangOpts()->CommentOpts, *Args);
|
||||
ParseFileSystemArgs(Res.getFileSystemOpts(), *Args);
|
||||
// FIXME: We shouldn't have to pass the DashX option around here
|
||||
InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags);
|
||||
ParseTargetArgs(Res.getTargetOpts(), *Args);
|
||||
Success = ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, DashX, Diags,
|
||||
Res.getTargetOpts()) && Success;
|
||||
Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, DashX, Diags,
|
||||
Res.getTargetOpts());
|
||||
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args);
|
||||
if (DashX != IK_AST && DashX != IK_LLVM_IR) {
|
||||
ParseLangArgs(*Res.getLangOpts(), *Args, DashX, Diags);
|
||||
|
@ -65,7 +65,7 @@ class InitHeaderSearch {
|
||||
/// AddSystemHeaderPrefix - Add the specified prefix to the system header
|
||||
/// prefix list.
|
||||
void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
|
||||
SystemHeaderPrefixes.push_back(std::make_pair(Prefix, IsSystemHeader));
|
||||
SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
|
||||
}
|
||||
|
||||
/// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu
|
||||
|
@ -128,7 +128,7 @@ class PrintPPOutputPPCallbacks : public PPCallbacks {
|
||||
CharSourceRange FilenameRange, const FileEntry *File,
|
||||
StringRef SearchPath, StringRef RelativePath,
|
||||
const Module *Imported) override;
|
||||
void Ident(SourceLocation Loc, const std::string &str) override;
|
||||
void Ident(SourceLocation Loc, StringRef str) override;
|
||||
void PragmaMessage(SourceLocation Loc, StringRef Namespace,
|
||||
PragmaMessageKind Kind, StringRef Str) override;
|
||||
void PragmaDebug(SourceLocation Loc, StringRef DebugType) override;
|
||||
@ -337,11 +337,11 @@ void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc,
|
||||
|
||||
/// Ident - Handle #ident directives when read by the preprocessor.
|
||||
///
|
||||
void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, const std::string &S) {
|
||||
void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, StringRef S) {
|
||||
MoveToLine(Loc);
|
||||
|
||||
OS.write("#ident ", strlen("#ident "));
|
||||
OS.write(&S[0], S.size());
|
||||
OS.write(S.begin(), S.size());
|
||||
EmittedTokensOnThisLine = true;
|
||||
}
|
||||
|
||||
|
@ -30,17 +30,17 @@ void TextDiagnosticBuffer::HandleDiagnostic(DiagnosticsEngine::Level Level,
|
||||
default: llvm_unreachable(
|
||||
"Diagnostic not handled during diagnostic buffering!");
|
||||
case DiagnosticsEngine::Note:
|
||||
Notes.push_back(std::make_pair(Info.getLocation(), Buf.str()));
|
||||
Notes.emplace_back(Info.getLocation(), Buf.str());
|
||||
break;
|
||||
case DiagnosticsEngine::Warning:
|
||||
Warnings.push_back(std::make_pair(Info.getLocation(), Buf.str()));
|
||||
Warnings.emplace_back(Info.getLocation(), Buf.str());
|
||||
break;
|
||||
case DiagnosticsEngine::Remark:
|
||||
Remarks.push_back(std::make_pair(Info.getLocation(), Buf.str()));
|
||||
Remarks.emplace_back(Info.getLocation(), Buf.str());
|
||||
break;
|
||||
case DiagnosticsEngine::Error:
|
||||
case DiagnosticsEngine::Fatal:
|
||||
Errors.push_back(std::make_pair(Info.getLocation(), Buf.str()));
|
||||
Errors.emplace_back(Info.getLocation(), Buf.str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
12235
lib/Headers/altivec.h
12235
lib/Headers/altivec.h
File diff suppressed because it is too large
Load Diff
@ -30,33 +30,175 @@
|
||||
|
||||
#include <pmmintrin.h>
|
||||
|
||||
/// \brief Extracts the specified bits from the lower 64 bits of the 128-bit
|
||||
/// integer vector operand at the index idx and of the length len.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
/// \code
|
||||
/// __m128i _mm_extracti_si64(__m128i x, const int len, const int idx);
|
||||
/// \endcode
|
||||
///
|
||||
/// \code
|
||||
/// This intrinsic corresponds to the \c EXTRQ instruction.
|
||||
/// \endcode
|
||||
///
|
||||
/// \param x
|
||||
/// The value from which bits are extracted.
|
||||
/// \param len
|
||||
/// Bits [5:0] specify the length; the other bits are ignored. If bits [5:0]
|
||||
/// are zero, the length is interpreted as 64.
|
||||
/// \param idx
|
||||
/// Bits [5:0] specify the index of the least significant bit; the other
|
||||
/// bits are ignored. If the sum of the index and length is greater than
|
||||
/// 64, the result is undefined. If the length and index are both zero,
|
||||
/// bits [63:0] of parameter x are extracted. If the length is zero
|
||||
/// but the index is non-zero, the result is undefined.
|
||||
/// \returns A 128-bit integer vector whose lower 64 bits contain the bits
|
||||
/// extracted from the source operand.
|
||||
#define _mm_extracti_si64(x, len, idx) \
|
||||
((__m128i)__builtin_ia32_extrqi((__v2di)(__m128i)(x), \
|
||||
(char)(len), (char)(idx)))
|
||||
|
||||
/// \brief Extracts the specified bits from the lower 64 bits of the 128-bit
|
||||
/// integer vector operand at the index and of the length specified by __y.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
/// \code
|
||||
/// This intrinsic corresponds to the \c EXTRQ instruction.
|
||||
/// \endcode
|
||||
///
|
||||
/// \param __x
|
||||
/// The value from which bits are extracted.
|
||||
/// \param __y
|
||||
/// Specifies the index of the least significant bit at [13:8]
|
||||
/// and the length at [5:0]; all other bits are ignored.
|
||||
/// If bits [5:0] are zero, the length is interpreted as 64.
|
||||
/// If the sum of the index and length is greater than 64, the result is
|
||||
/// undefined. If the length and index are both zero, bits [63:0] of
|
||||
/// parameter __x are extracted. If the length is zero but the index is
|
||||
/// non-zero, the result is undefined.
|
||||
/// \returns A 128-bit vector whose lower 64 bits contain the bits extracted
|
||||
/// from the source operand.
|
||||
static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
|
||||
_mm_extract_si64(__m128i __x, __m128i __y)
|
||||
{
|
||||
return (__m128i)__builtin_ia32_extrq((__v2di)__x, (__v16qi)__y);
|
||||
}
|
||||
|
||||
/// \brief Inserts bits of a specified length from the source integer vector
|
||||
/// y into the lower 64 bits of the destination integer vector x at the
|
||||
/// index idx and of the length len.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
/// \code
|
||||
/// __m128i _mm_inserti_si64(__m128i x, __m128i y, const int len,
|
||||
/// const int idx);
|
||||
/// \endcode
|
||||
///
|
||||
/// \code
|
||||
/// This intrinsic corresponds to the \c INSERTQ instruction.
|
||||
/// \endcode
|
||||
///
|
||||
/// \param x
|
||||
/// The destination operand where bits will be inserted. The inserted bits
|
||||
/// are defined by the length len and by the index idx specifying the least
|
||||
/// significant bit.
|
||||
/// \param y
|
||||
/// The source operand containing the bits to be extracted. The extracted
|
||||
/// bits are the least significant bits of operand y of length len.
|
||||
/// \param len
|
||||
/// Bits [5:0] specify the length; the other bits are ignored. If bits [5:0]
|
||||
/// are zero, the length is interpreted as 64.
|
||||
/// \param idx
|
||||
/// Bits [5:0] specify the index of the least significant bit; the other
|
||||
/// bits are ignored. If the sum of the index and length is greater than
|
||||
/// 64, the result is undefined. If the length and index are both zero,
|
||||
/// bits [63:0] of parameter y are inserted into parameter x. If the
|
||||
/// length is zero but the index is non-zero, the result is undefined.
|
||||
/// \returns A 128-bit integer vector containing the original lower 64-bits
|
||||
/// of destination operand x with the specified bitfields replaced by the
|
||||
/// lower bits of source operand y. The upper 64 bits of the return value
|
||||
/// are undefined.
|
||||
|
||||
#define _mm_inserti_si64(x, y, len, idx) \
|
||||
((__m128i)__builtin_ia32_insertqi((__v2di)(__m128i)(x), \
|
||||
(__v2di)(__m128i)(y), \
|
||||
(char)(len), (char)(idx)))
|
||||
|
||||
/// \brief Inserts bits of a specified length from the source integer vector
|
||||
/// __y into the lower 64 bits of the destination integer vector __x at
|
||||
/// the index and of the length specified by __y.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
/// \code
|
||||
/// This intrinsic corresponds to the \c INSERTQ instruction.
|
||||
/// \endcode
|
||||
///
|
||||
/// \param __x
|
||||
/// The destination operand where bits will be inserted. The inserted bits
|
||||
/// are defined by the length and by the index of the least significant bit
|
||||
/// specified by operand __y.
|
||||
/// \param __y
|
||||
/// The source operand containing the bits to be extracted. The extracted
|
||||
/// bits are the least significant bits of operand __y with length specified
|
||||
/// by bits [69:64]. These are inserted into the destination at the index
|
||||
/// specified by bits [77:72]; all other bits are ignored.
|
||||
/// If bits [69:64] are zero, the length is interpreted as 64.
|
||||
/// If the sum of the index and length is greater than 64, the result is
|
||||
/// undefined. If the length and index are both zero, bits [63:0] of
|
||||
/// parameter __y are inserted into parameter __x. If the length
|
||||
/// is zero but the index is non-zero, the result is undefined.
|
||||
/// \returns A 128-bit integer vector containing the original lower 64-bits
|
||||
/// of destination operand __x with the specified bitfields replaced by the
|
||||
/// lower bits of source operand __y. The upper 64 bits of the return value
|
||||
/// are undefined.
|
||||
|
||||
static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
|
||||
_mm_insert_si64(__m128i __x, __m128i __y)
|
||||
{
|
||||
return (__m128i)__builtin_ia32_insertq((__v2di)__x, (__v2di)__y);
|
||||
}
|
||||
|
||||
/// \brief Stores a 64-bit double-precision value in a 64-bit memory location.
|
||||
/// To minimize caching, the data is flagged as non-temporal (unlikely to be
|
||||
/// used again soon).
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
/// \code
|
||||
/// This intrinsic corresponds to the \c MOVNTSD instruction.
|
||||
/// \endcode
|
||||
///
|
||||
/// \param __p
|
||||
/// The 64-bit memory location used to store the register value.
|
||||
/// \param __a
|
||||
/// The 64-bit double-precision floating-point register value to
|
||||
/// be stored.
|
||||
static __inline__ void __attribute__((__always_inline__, __nodebug__))
|
||||
_mm_stream_sd(double *__p, __m128d __a)
|
||||
{
|
||||
__builtin_ia32_movntsd(__p, (__v2df)__a);
|
||||
}
|
||||
|
||||
/// \brief Stores a 32-bit single-precision floating-point value in a 32-bit
|
||||
/// memory location. To minimize caching, the data is flagged as
|
||||
/// non-temporal (unlikely to be used again soon).
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
/// \code
|
||||
/// This intrinsic corresponds to the \c MOVNTSS instruction.
|
||||
/// \endcode
|
||||
///
|
||||
/// \param __p
|
||||
/// The 32-bit memory location used to store the register value.
|
||||
/// \param __a
|
||||
/// The 32-bit single-precision floating-point register value to
|
||||
/// be stored.
|
||||
static __inline__ void __attribute__((__always_inline__, __nodebug__))
|
||||
_mm_stream_ss(float *__p, __m128 __a)
|
||||
{
|
||||
|
@ -157,6 +157,8 @@ module _Builtin_intrinsics [system] [extern_c] {
|
||||
explicit module aes_pclmul {
|
||||
requires aes, pclmul
|
||||
header "wmmintrin.h"
|
||||
export aes
|
||||
export pclmul
|
||||
}
|
||||
|
||||
explicit module aes {
|
||||
|
@ -199,7 +199,7 @@ Lexer *Lexer::Create_PragmaLexer(SourceLocation SpellingLoc,
|
||||
|
||||
/// Stringify - Convert the specified string into a C string, with surrounding
|
||||
/// ""'s, and with escaped \ and " characters.
|
||||
std::string Lexer::Stringify(const std::string &Str, bool Charify) {
|
||||
std::string Lexer::Stringify(StringRef Str, bool Charify) {
|
||||
std::string Result = Str;
|
||||
char Quote = Charify ? '\'' : '"';
|
||||
for (unsigned i = 0, e = Result.size(); i != e; ++i) {
|
||||
|
@ -332,12 +332,11 @@ static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
|
||||
|
||||
ModuleMap::KnownHeader
|
||||
ModuleMap::findModuleForHeader(const FileEntry *File,
|
||||
Module *RequestingModule,
|
||||
bool IncludeTextualHeaders) {
|
||||
Module *RequestingModule) {
|
||||
HeadersMap::iterator Known = findKnownHeader(File);
|
||||
|
||||
auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
|
||||
if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader))
|
||||
if (R.getRole() & ModuleMap::TextualHeader)
|
||||
return ModuleMap::KnownHeader();
|
||||
return R;
|
||||
};
|
||||
|
@ -362,12 +362,8 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
|
||||
|
||||
// If this is a function-like macro invocation, it's safe to trivially expand
|
||||
// as long as the identifier is not a macro argument.
|
||||
for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
|
||||
I != E; ++I)
|
||||
if (*I == II)
|
||||
return false; // Identifier is a macro argument.
|
||||
return std::find(MI->arg_begin(), MI->arg_end(), II) == MI->arg_end();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -431,8 +431,7 @@ static void InvalidPTH(DiagnosticsEngine &Diags, const char *Msg) {
|
||||
Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0")) << Msg;
|
||||
}
|
||||
|
||||
PTHManager *PTHManager::Create(const std::string &file,
|
||||
DiagnosticsEngine &Diags) {
|
||||
PTHManager *PTHManager::Create(StringRef file, DiagnosticsEngine &Diags) {
|
||||
// Memory map the PTH file.
|
||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileOrErr =
|
||||
llvm::MemoryBuffer::getFile(file);
|
||||
|
@ -799,8 +799,10 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
|
||||
"PragmaLoopHintInfo::Toks must contain at least one token.");
|
||||
|
||||
// If no option is specified the argument is assumed to be a constant expr.
|
||||
bool OptionUnroll = false;
|
||||
bool StateOption = false;
|
||||
if (OptionInfo) { // Pragma unroll does not specify an option.
|
||||
if (OptionInfo) { // Pragma Unroll does not specify an option.
|
||||
OptionUnroll = OptionInfo->isStr("unroll");
|
||||
StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
|
||||
.Case("vectorize", true)
|
||||
.Case("interleave", true)
|
||||
@ -812,14 +814,13 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
|
||||
if (Toks[0].is(tok::eof)) {
|
||||
ConsumeToken(); // The annotation token.
|
||||
Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
|
||||
<< /*StateArgument=*/StateOption << /*FullKeyword=*/PragmaUnroll;
|
||||
<< /*StateArgument=*/StateOption << /*FullKeyword=*/OptionUnroll;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate the argument.
|
||||
if (StateOption) {
|
||||
ConsumeToken(); // The annotation token.
|
||||
bool OptionUnroll = OptionInfo->isStr("unroll");
|
||||
SourceLocation StateLoc = Toks[0].getLocation();
|
||||
IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
|
||||
if (!StateInfo || ((OptionUnroll ? !StateInfo->isStr("full")
|
||||
|
@ -1463,7 +1463,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
|
||||
PartialDiagnosticAt FNote(CurrentFunction->getBody()->getLocStart(),
|
||||
S.PDiag(diag::note_thread_warning_in_fun)
|
||||
<< CurrentFunction->getNameAsString());
|
||||
ONS.push_back(FNote);
|
||||
ONS.push_back(std::move(FNote));
|
||||
}
|
||||
return ONS;
|
||||
}
|
||||
@ -1477,7 +1477,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
|
||||
PartialDiagnosticAt FNote(CurrentFunction->getBody()->getLocStart(),
|
||||
S.PDiag(diag::note_thread_warning_in_fun)
|
||||
<< CurrentFunction->getNameAsString());
|
||||
ONS.push_back(FNote);
|
||||
ONS.push_back(std::move(FNote));
|
||||
}
|
||||
return ONS;
|
||||
}
|
||||
@ -1490,7 +1490,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
|
||||
if (!Loc.isValid())
|
||||
Loc = FunLocation;
|
||||
PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << LockName);
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes()));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes());
|
||||
}
|
||||
|
||||
public:
|
||||
@ -1516,7 +1516,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
|
||||
void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) override {
|
||||
PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_cannot_resolve_lock)
|
||||
<< Loc);
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes()));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes());
|
||||
}
|
||||
|
||||
void handleUnmatchedUnlock(StringRef Kind, Name LockName,
|
||||
@ -1532,7 +1532,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
|
||||
PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_kind_mismatch)
|
||||
<< Kind << LockName << Received
|
||||
<< Expected);
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes()));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes());
|
||||
}
|
||||
|
||||
void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation Loc) override {
|
||||
@ -1566,10 +1566,10 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
|
||||
if (LocLocked.isValid()) {
|
||||
PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here)
|
||||
<< Kind);
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes(Note));
|
||||
return;
|
||||
}
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes()));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes());
|
||||
}
|
||||
|
||||
void handleExclusiveAndShared(StringRef Kind, Name LockName,
|
||||
@ -1580,7 +1580,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
|
||||
<< Kind << LockName);
|
||||
PartialDiagnosticAt Note(Loc2, S.PDiag(diag::note_lock_exclusive_and_shared)
|
||||
<< Kind << LockName);
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes(Note));
|
||||
}
|
||||
|
||||
void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
|
||||
@ -1593,7 +1593,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
|
||||
diag::warn_var_deref_requires_any_lock;
|
||||
PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
|
||||
<< D->getNameAsString() << getLockKindFromAccessKind(AK));
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes()));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes());
|
||||
}
|
||||
|
||||
void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
|
||||
@ -1628,9 +1628,9 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
|
||||
PartialDiagnosticAt VNote(D->getLocation(),
|
||||
S.PDiag(diag::note_guarded_by_declared_here)
|
||||
<< D->getNameAsString());
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes(Note, VNote)));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes(Note, VNote));
|
||||
} else
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes(Note));
|
||||
} else {
|
||||
switch (POK) {
|
||||
case POK_VarAccess:
|
||||
@ -1656,9 +1656,9 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
|
||||
PartialDiagnosticAt Note(D->getLocation(),
|
||||
S.PDiag(diag::note_guarded_by_declared_here)
|
||||
<< D->getNameAsString());
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes(Note));
|
||||
} else
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes()));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1667,7 +1667,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
|
||||
PartialDiagnosticAt Warning(Loc,
|
||||
S.PDiag(diag::warn_acquire_requires_negative_cap)
|
||||
<< Kind << LockName << Neg);
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes()));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes());
|
||||
}
|
||||
|
||||
|
||||
@ -1675,20 +1675,20 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
|
||||
SourceLocation Loc) override {
|
||||
PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_fun_excludes_mutex)
|
||||
<< Kind << FunName << LockName);
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes()));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes());
|
||||
}
|
||||
|
||||
void handleLockAcquiredBefore(StringRef Kind, Name L1Name, Name L2Name,
|
||||
SourceLocation Loc) override {
|
||||
PartialDiagnosticAt Warning(Loc,
|
||||
S.PDiag(diag::warn_acquired_before) << Kind << L1Name << L2Name);
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes()));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes());
|
||||
}
|
||||
|
||||
void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc) override {
|
||||
PartialDiagnosticAt Warning(Loc,
|
||||
S.PDiag(diag::warn_acquired_before_after_cycle) << L1Name);
|
||||
Warnings.push_back(DelayedDiag(Warning, getNotes()));
|
||||
Warnings.emplace_back(std::move(Warning), getNotes());
|
||||
}
|
||||
|
||||
void enterFunction(const FunctionDecl* FD) override {
|
||||
@ -1732,8 +1732,8 @@ class ConsumedWarningsHandler : public ConsumedWarningsHandlerBase {
|
||||
StringRef VariableName) override {
|
||||
PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_loop_state_mismatch) <<
|
||||
VariableName);
|
||||
|
||||
Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
|
||||
|
||||
Warnings.emplace_back(std::move(Warning), OptionalNotes());
|
||||
}
|
||||
|
||||
void warnParamReturnTypestateMismatch(SourceLocation Loc,
|
||||
@ -1744,8 +1744,8 @@ class ConsumedWarningsHandler : public ConsumedWarningsHandlerBase {
|
||||
PartialDiagnosticAt Warning(Loc, S.PDiag(
|
||||
diag::warn_param_return_typestate_mismatch) << VariableName <<
|
||||
ExpectedState << ObservedState);
|
||||
|
||||
Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
|
||||
|
||||
Warnings.emplace_back(std::move(Warning), OptionalNotes());
|
||||
}
|
||||
|
||||
void warnParamTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
|
||||
@ -1753,16 +1753,16 @@ class ConsumedWarningsHandler : public ConsumedWarningsHandlerBase {
|
||||
|
||||
PartialDiagnosticAt Warning(Loc, S.PDiag(
|
||||
diag::warn_param_typestate_mismatch) << ExpectedState << ObservedState);
|
||||
|
||||
Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
|
||||
|
||||
Warnings.emplace_back(std::move(Warning), OptionalNotes());
|
||||
}
|
||||
|
||||
void warnReturnTypestateForUnconsumableType(SourceLocation Loc,
|
||||
StringRef TypeName) override {
|
||||
PartialDiagnosticAt Warning(Loc, S.PDiag(
|
||||
diag::warn_return_typestate_for_unconsumable_type) << TypeName);
|
||||
|
||||
Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
|
||||
|
||||
Warnings.emplace_back(std::move(Warning), OptionalNotes());
|
||||
}
|
||||
|
||||
void warnReturnTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
|
||||
@ -1770,8 +1770,8 @@ class ConsumedWarningsHandler : public ConsumedWarningsHandlerBase {
|
||||
|
||||
PartialDiagnosticAt Warning(Loc, S.PDiag(
|
||||
diag::warn_return_typestate_mismatch) << ExpectedState << ObservedState);
|
||||
|
||||
Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
|
||||
|
||||
Warnings.emplace_back(std::move(Warning), OptionalNotes());
|
||||
}
|
||||
|
||||
void warnUseOfTempInInvalidState(StringRef MethodName, StringRef State,
|
||||
@ -1779,8 +1779,8 @@ class ConsumedWarningsHandler : public ConsumedWarningsHandlerBase {
|
||||
|
||||
PartialDiagnosticAt Warning(Loc, S.PDiag(
|
||||
diag::warn_use_of_temp_in_invalid_state) << MethodName << State);
|
||||
|
||||
Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
|
||||
|
||||
Warnings.emplace_back(std::move(Warning), OptionalNotes());
|
||||
}
|
||||
|
||||
void warnUseInInvalidState(StringRef MethodName, StringRef VariableName,
|
||||
@ -1788,8 +1788,8 @@ class ConsumedWarningsHandler : public ConsumedWarningsHandlerBase {
|
||||
|
||||
PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_invalid_state) <<
|
||||
MethodName << VariableName << State);
|
||||
|
||||
Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
|
||||
|
||||
Warnings.emplace_back(std::move(Warning), OptionalNotes());
|
||||
}
|
||||
};
|
||||
}}}
|
||||
@ -1886,6 +1886,7 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
|
||||
AC.getCFGBuildOptions().AddImplicitDtors = true;
|
||||
AC.getCFGBuildOptions().AddTemporaryDtors = true;
|
||||
AC.getCFGBuildOptions().AddCXXNewAllocator = false;
|
||||
AC.getCFGBuildOptions().AddCXXDefaultInitExprInCtors = true;
|
||||
|
||||
// Force that certain expressions appear as CFGElements in the CFG. This
|
||||
// is used to speed up various analyses.
|
||||
|
@ -72,10 +72,10 @@ class JumpScopeChecker {
|
||||
JumpScopeChecker(Stmt *Body, Sema &S);
|
||||
private:
|
||||
void BuildScopeInformation(Decl *D, unsigned &ParentScope);
|
||||
void BuildScopeInformation(VarDecl *D, const BlockDecl *BDecl,
|
||||
void BuildScopeInformation(VarDecl *D, const BlockDecl *BDecl,
|
||||
unsigned &ParentScope);
|
||||
void BuildScopeInformation(Stmt *S, unsigned &origParentScope);
|
||||
|
||||
|
||||
void VerifyJumps();
|
||||
void VerifyIndirectJumps();
|
||||
void NoteJumpIntoScopes(ArrayRef<unsigned> ToScopes);
|
||||
@ -166,7 +166,7 @@ static ScopePair GetDiagForGotoScopeDecl(Sema &S, const Decl *D) {
|
||||
// A program that jumps from a point where a variable with automatic
|
||||
// storage duration is not in scope to a point where it is in scope
|
||||
// is ill-formed unless the variable has scalar type, class type with
|
||||
// a trivial default constructor and a trivial destructor, a
|
||||
// a trivial default constructor and a trivial destructor, a
|
||||
// cv-qualified version of one of these types, or an array of one of
|
||||
// the preceding types and is declared without an initializer.
|
||||
|
||||
@ -218,7 +218,7 @@ void JumpScopeChecker::BuildScopeInformation(Decl *D, unsigned &ParentScope) {
|
||||
D->getLocation()));
|
||||
ParentScope = Scopes.size()-1;
|
||||
}
|
||||
|
||||
|
||||
// If the decl has an initializer, walk it with the potentially new
|
||||
// scope we just installed.
|
||||
if (VarDecl *VD = dyn_cast<VarDecl>(D))
|
||||
@ -227,8 +227,8 @@ void JumpScopeChecker::BuildScopeInformation(Decl *D, unsigned &ParentScope) {
|
||||
}
|
||||
|
||||
/// \brief Build scope information for a captured block literal variables.
|
||||
void JumpScopeChecker::BuildScopeInformation(VarDecl *D,
|
||||
const BlockDecl *BDecl,
|
||||
void JumpScopeChecker::BuildScopeInformation(VarDecl *D,
|
||||
const BlockDecl *BDecl,
|
||||
unsigned &ParentScope) {
|
||||
// exclude captured __block variables; there's no destructor
|
||||
// associated with the block literal for them.
|
||||
@ -257,7 +257,7 @@ void JumpScopeChecker::BuildScopeInformation(VarDecl *D,
|
||||
SourceLocation Loc = D->getLocation();
|
||||
if (Loc.isInvalid())
|
||||
Loc = BDecl->getLocation();
|
||||
Scopes.push_back(GotoScope(ParentScope,
|
||||
Scopes.push_back(GotoScope(ParentScope,
|
||||
Diags.first, Diags.second, Loc));
|
||||
ParentScope = Scopes.size()-1;
|
||||
}
|
||||
@ -272,11 +272,11 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope)
|
||||
// propagate out into the enclosing scope. Otherwise we have to worry
|
||||
// about block literals, which have the lifetime of their enclosing statement.
|
||||
unsigned independentParentScope = origParentScope;
|
||||
unsigned &ParentScope = ((isa<Expr>(S) && !isa<StmtExpr>(S))
|
||||
unsigned &ParentScope = ((isa<Expr>(S) && !isa<StmtExpr>(S))
|
||||
? origParentScope : independentParentScope);
|
||||
|
||||
bool SkipFirstSubStmt = false;
|
||||
|
||||
|
||||
// If we found a label, remember that it is in ParentScope scope.
|
||||
switch (S->getStmtClass()) {
|
||||
case Stmt::AddrLabelExprClass:
|
||||
@ -307,7 +307,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope)
|
||||
SkipFirstSubStmt = true;
|
||||
}
|
||||
// Fall through
|
||||
|
||||
|
||||
case Stmt::GotoStmtClass:
|
||||
// Remember both what scope a goto is in as well as the fact that we have
|
||||
// it. This makes the second scan not have to walk the AST again.
|
||||
@ -332,7 +332,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope)
|
||||
diag::note_protected_by_cxx_catch,
|
||||
diag::note_exits_cxx_catch,
|
||||
CS->getSourceRange().getBegin()));
|
||||
BuildScopeInformation(CS->getHandlerBlock(),
|
||||
BuildScopeInformation(CS->getHandlerBlock(),
|
||||
(newParentScope = Scopes.size()-1));
|
||||
}
|
||||
return;
|
||||
@ -354,14 +354,14 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope)
|
||||
diag::note_protected_by_seh_except,
|
||||
diag::note_exits_seh_except,
|
||||
Except->getSourceRange().getBegin()));
|
||||
BuildScopeInformation(Except->getBlock(),
|
||||
BuildScopeInformation(Except->getBlock(),
|
||||
(newParentScope = Scopes.size()-1));
|
||||
} else if (SEHFinallyStmt *Finally = TS->getFinallyHandler()) {
|
||||
Scopes.push_back(GotoScope(ParentScope,
|
||||
diag::note_protected_by_seh_finally,
|
||||
diag::note_exits_seh_finally,
|
||||
Finally->getSourceRange().getBegin()));
|
||||
BuildScopeInformation(Finally->getBlock(),
|
||||
BuildScopeInformation(Finally->getBlock(),
|
||||
(newParentScope = Scopes.size()-1));
|
||||
}
|
||||
|
||||
@ -377,7 +377,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope)
|
||||
SkipFirstSubStmt = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Stmt *SubStmt = *CI;
|
||||
if (!SubStmt) continue;
|
||||
|
||||
@ -428,7 +428,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope)
|
||||
diag::note_exits_objc_catch,
|
||||
AC->getAtCatchLoc()));
|
||||
// @catches are nested and it isn't
|
||||
BuildScopeInformation(AC->getCatchBody(),
|
||||
BuildScopeInformation(AC->getCatchBody(),
|
||||
(newParentScope = Scopes.size()-1));
|
||||
}
|
||||
|
||||
@ -443,7 +443,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope)
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
unsigned newParentScope;
|
||||
// Disallow jumps into the protected statement of an @synchronized, but
|
||||
// allow jumps into the object expression it protects.
|
||||
@ -459,7 +459,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope)
|
||||
diag::note_protected_by_objc_synchronized,
|
||||
diag::note_exits_objc_synchronized,
|
||||
AS->getAtSynchronizedLoc()));
|
||||
BuildScopeInformation(AS->getSynchBody(),
|
||||
BuildScopeInformation(AS->getSynchBody(),
|
||||
(newParentScope = Scopes.size()-1));
|
||||
continue;
|
||||
}
|
||||
|
@ -1081,6 +1081,15 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
|
||||
Kind = CK_BitCast;
|
||||
return TC_Success;
|
||||
}
|
||||
|
||||
// Microsoft permits static_cast from 'pointer-to-void' to
|
||||
// 'pointer-to-function'.
|
||||
if (!CStyle && Self.getLangOpts().MSVCCompat &&
|
||||
DestPointee->isFunctionType()) {
|
||||
Self.Diag(OpRange.getBegin(), diag::ext_ms_cast_fn_obj) << OpRange;
|
||||
Kind = CK_BitCast;
|
||||
return TC_Success;
|
||||
}
|
||||
}
|
||||
else if (DestType->isObjCObjectPointerType()) {
|
||||
// allow both c-style cast and static_cast of objective-c pointers as
|
||||
|
@ -1604,6 +1604,10 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
// atomic_fetch_or takes a pointer to a volatile 'A'. We shouldn't let the
|
||||
// volatile-ness of the pointee-type inject itself into the result or the
|
||||
// other operands.
|
||||
ValType.removeLocalVolatile();
|
||||
QualType ResultType = ValType;
|
||||
if (Form == Copy || Form == GNUXchg || Form == Init)
|
||||
ResultType = Context.VoidTy;
|
||||
|
@ -1018,9 +1018,7 @@ void ResultBuilder::AddResult(Result R) {
|
||||
}
|
||||
|
||||
/// \brief Enter into a new scope.
|
||||
void ResultBuilder::EnterNewScope() {
|
||||
ShadowMaps.push_back(ShadowMap());
|
||||
}
|
||||
void ResultBuilder::EnterNewScope() { ShadowMaps.emplace_back(); }
|
||||
|
||||
/// \brief Exit from the current scope.
|
||||
void ResultBuilder::ExitScope() {
|
||||
|
@ -3302,11 +3302,10 @@ static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
|
||||
static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
|
||||
if (hasDeclarator(D)) return;
|
||||
|
||||
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
|
||||
// Diagnostic is emitted elsewhere: here we store the (valid) Attr
|
||||
// in the Decl node for syntactic reasoning, e.g., pretty-printing.
|
||||
CallingConv CC;
|
||||
if (S.CheckCallingConvAttr(Attr, CC, FD))
|
||||
if (S.CheckCallingConvAttr(Attr, CC, /*FD*/nullptr))
|
||||
return;
|
||||
|
||||
if (!isa<ObjCMethodDecl>(D)) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user