Vendor import of clang trunk r306956:

https://llvm.org/svn/llvm-project/cfe/trunk@306956
This commit is contained in:
Dimitry Andric 2017-07-01 13:24:05 +00:00
parent ef915aab0a
commit cf1b401909
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/clang/dist/; revision=320535
svn path=/vendor/clang/clang-trunk-r306956/; revision=320536; tag=vendor/clang/clang-trunk-r306956
278 changed files with 9536 additions and 2793 deletions

View File

@ -1367,6 +1367,30 @@ class TemplateArgumentKind(BaseEnumeration):
TemplateArgumentKind.NULLPTR = TemplateArgumentKind(3)
TemplateArgumentKind.INTEGRAL = TemplateArgumentKind(4)
### Exception Specification Kinds ###
class ExceptionSpecificationKind(BaseEnumeration):
"""
An ExceptionSpecificationKind describes the kind of exception specification
that a function has.
"""
# The required BaseEnumeration declarations.
_kinds = []
_name_map = None
def __repr__(self):
return 'ExceptionSpecificationKind.{}'.format(self.name)
ExceptionSpecificationKind.NONE = ExceptionSpecificationKind(0)
ExceptionSpecificationKind.DYNAMIC_NONE = ExceptionSpecificationKind(1)
ExceptionSpecificationKind.DYNAMIC = ExceptionSpecificationKind(2)
ExceptionSpecificationKind.MS_ANY = ExceptionSpecificationKind(3)
ExceptionSpecificationKind.BASIC_NOEXCEPT = ExceptionSpecificationKind(4)
ExceptionSpecificationKind.COMPUTED_NOEXCEPT = ExceptionSpecificationKind(5)
ExceptionSpecificationKind.UNEVALUATED = ExceptionSpecificationKind(6)
ExceptionSpecificationKind.UNINSTANTIATED = ExceptionSpecificationKind(7)
ExceptionSpecificationKind.UNPARSED = ExceptionSpecificationKind(8)
### Cursors ###
class Cursor(Structure):
@ -1586,6 +1610,18 @@ def result_type(self):
return self._result_type
@property
def exception_specification_kind(self):
'''
Retrieve the exception specification kind, which is one of the values
from the ExceptionSpecificationKind enumeration.
'''
if not hasattr(self, '_exception_specification_kind'):
exc_kind = conf.lib.clang_getCursorExceptionSpecificationType(self)
self._exception_specification_kind = ExceptionSpecificationKind.from_id(exc_kind)
return self._exception_specification_kind
@property
def underlying_typedef_type(self):
"""Return the underlying type of a typedef declaration.
@ -2254,6 +2290,14 @@ def visitor(field, children):
callbacks['fields_visit'](visitor), fields)
return iter(fields)
def get_exception_specification_kind(self):
"""
Return the kind of the exception specification; a value from
the ExceptionSpecificationKind enumeration.
"""
return ExceptionSpecificationKind.from_id(
conf.lib.clang.getExceptionSpecificationType(self))
@property
def spelling(self):
"""Retrieve the spelling of this Type."""

View File

@ -0,0 +1,27 @@
import clang.cindex
from clang.cindex import ExceptionSpecificationKind
from .util import get_tu
def find_function_declarations(node, declarations=[]):
if node.kind == clang.cindex.CursorKind.FUNCTION_DECL:
declarations.append((node.spelling, node.exception_specification_kind))
for child in node.get_children():
declarations = find_function_declarations(child, declarations)
return declarations
def test_exception_specification_kind():
source = """int square1(int x);
int square2(int x) noexcept;
int square3(int x) noexcept(noexcept(x * x));"""
tu = get_tu(source, lang='cpp', flags=['-std=c++14'])
declarations = find_function_declarations(tu.cursor)
expected = [
('square1', ExceptionSpecificationKind.NONE),
('square2', ExceptionSpecificationKind.BASIC_NOEXCEPT),
('square3', ExceptionSpecificationKind.COMPUTED_NOEXCEPT)
]
assert declarations == expected

View File

@ -322,18 +322,27 @@ output format of the diagnostics that it generates.
by category, so it should be a high level category. We want dozens
of these, not hundreds or thousands of them.
.. _opt_fsave-optimization-record:
**-fsave-optimization-record**
Write optimization remarks to a YAML file.
This option, which defaults to off, controls whether Clang writes
optimization reports to a YAML file. By recording diagnostics in a file,
using a structured YAML format, users can parse or sort the remarks in a
convenient way.
.. _opt_fdiagnostics-show-hotness:
**-f[no-]diagnostics-show-hotness**
Enable profile hotness information in diagnostic line.
This option, which defaults to off, controls whether Clang prints the
profile hotness associated with a diagnostics in the presence of
profile-guided optimization information. This is currently supported with
optimization remarks (see :ref:`Options to Emit Optimization Reports
<rpass>`). The hotness information allows users to focus on the hot
optimization remarks that are likely to be more relevant for run-time
performance.
This option controls whether Clang prints the profile hotness associated
with diagnostics in the presence of profile-guided optimization information.
This is currently supported with optimization remarks (see
:ref:`Options to Emit Optimization Reports <rpass>`). The hotness information
allows users to focus on the hot optimization remarks that are likely to be
more relevant for run-time performance.
For example, in this output, the block containing the callsite of `foo` was
executed 3000 times according to the profile data:
@ -344,6 +353,23 @@ output format of the diagnostics that it generates.
sum += foo(x, x - 2);
^
This option is implied when
:ref:`-fsave-optimization-record <opt_fsave-optimization-record>` is used.
Otherwise, it defaults to off.
.. _opt_fdiagnostics-hotness-threshold:
**-fdiagnostics-hotness-threshold**
Prevent optimization remarks from being output if they do not have at least
this hotness value.
This option, which defaults to zero, controls the minimum hotness an
optimization remark would need in order to be output by Clang. This is
currently supported with optimization remarks (see :ref:`Options to Emit
Optimization Reports <rpass>`) when profile hotness information in
diagnostics is enabled (see
:ref:`-fdiagnostics-show-hotness <opt_fdiagnostics-show-hotness>`).
.. _opt_fdiagnostics-fixit-info:
**-f[no-]diagnostics-fixit-info**

View File

@ -171,7 +171,60 @@ typedef struct CXVersion {
*/
int Subminor;
} CXVersion;
/**
* \brief Describes the exception specification of a cursor.
*
* A negative value indicates that the cursor is not a function declaration.
*/
enum CXCursor_ExceptionSpecificationKind {
/**
* \brief The cursor has no exception specification.
*/
CXCursor_ExceptionSpecificationKind_None,
/**
* \brief The cursor has exception specification throw()
*/
CXCursor_ExceptionSpecificationKind_DynamicNone,
/**
* \brief The cursor has exception specification throw(T1, T2)
*/
CXCursor_ExceptionSpecificationKind_Dynamic,
/**
* \brief The cursor has exception specification throw(...).
*/
CXCursor_ExceptionSpecificationKind_MSAny,
/**
* \brief The cursor has exception specification basic noexcept.
*/
CXCursor_ExceptionSpecificationKind_BasicNoexcept,
/**
* \brief The cursor has exception specification computed noexcept.
*/
CXCursor_ExceptionSpecificationKind_ComputedNoexcept,
/**
* \brief The exception specification has not yet been evaluated.
*/
CXCursor_ExceptionSpecificationKind_Unevaluated,
/**
* \brief The exception specification has not yet been instantiated.
*/
CXCursor_ExceptionSpecificationKind_Uninstantiated,
/**
* \brief The exception specification has not been parsed yet.
*/
CXCursor_ExceptionSpecificationKind_Unparsed
};
/**
* \brief Provides a shared context for creating translation units.
*
@ -3470,6 +3523,13 @@ CINDEX_LINKAGE enum CXCallingConv clang_getFunctionTypeCallingConv(CXType T);
*/
CINDEX_LINKAGE CXType clang_getResultType(CXType T);
/**
* \brief Retrieve the exception specification type associated with a function type.
*
* If a non-function type is passed in, an error code of -1 is returned.
*/
CINDEX_LINKAGE int clang_getExceptionSpecificationType(CXType T);
/**
* \brief Retrieve the number of non-variadic parameters associated with a
* function type.
@ -3498,6 +3558,13 @@ CINDEX_LINKAGE unsigned clang_isFunctionTypeVariadic(CXType T);
*/
CINDEX_LINKAGE CXType clang_getCursorResultType(CXCursor C);
/**
* \brief Retrieve the exception specification type associated with a given cursor.
*
* This only returns a valid result if the cursor refers to a function or method.
*/
CINDEX_LINKAGE int clang_getCursorExceptionSpecificationType(CXCursor C);
/**
* \brief Return 1 if the CXType is a POD (plain old data) type, and 0
* otherwise.

View File

@ -2050,6 +2050,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
uint64_t getFieldOffset(const ValueDecl *FD) const;
/// Get the offset of an ObjCIvarDecl in bits.
uint64_t lookupFieldBitOffset(const ObjCInterfaceDecl *OID,
const ObjCImplementationDecl *ID,
const ObjCIvarDecl *Ivar) const;
bool isNearlyEmpty(const CXXRecordDecl *RD) const;
VTableContextBase *getVTableContext();

View File

@ -62,9 +62,11 @@ struct StructuralEquivalenceContext {
StructuralEquivalenceContext(
ASTContext &FromCtx, ASTContext &ToCtx,
llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
bool StrictTypeSpelling = false, bool Complain = true)
bool StrictTypeSpelling = false, bool Complain = true,
bool ErrorOnTagTypeMismatch = false)
: FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
StrictTypeSpelling(StrictTypeSpelling), Complain(Complain),
StrictTypeSpelling(StrictTypeSpelling),
ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain),
LastDiagFromC2(false) {}
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);

View File

@ -2019,7 +2019,10 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
/// These functions have special behavior under C++1y [expr.new]:
/// An implementation is allowed to omit a call to a replaceable global
/// allocation function. [...]
bool isReplaceableGlobalAllocationFunction() const;
///
/// If this function is an aligned allocation/deallocation function, return
/// true through IsAligned.
bool isReplaceableGlobalAllocationFunction(bool *IsAligned = nullptr) const;
/// Compute the language linkage.
LanguageLinkage getLanguageLinkage() const;

View File

@ -49,7 +49,7 @@ class NSAPI {
NSStr_initWithString,
NSStr_initWithUTF8String
};
static const unsigned NumNSStringMethods = 5;
static const unsigned NumNSStringMethods = 6;
IdentifierInfo *getNSClassId(NSClassIdKindKind K) const;
@ -112,7 +112,7 @@ class NSAPI {
NSMutableDict_setObjectForKeyedSubscript,
NSMutableDict_setValueForKey
};
static const unsigned NumNSDictionaryMethods = 14;
static const unsigned NumNSDictionaryMethods = 13;
/// \brief The Objective-C NSDictionary selectors.
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;

View File

@ -20,6 +20,7 @@
#include "clang/AST/Stmt.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/MapVector.h"
namespace clang {
@ -3001,7 +3002,7 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
// Organize the components by declaration and retrieve the original
// expression. Original expressions are always the first component of the
// mappable component list.
llvm::DenseMap<ValueDecl *, SmallVector<MappableExprComponentListRef, 8>>
llvm::MapVector<ValueDecl *, SmallVector<MappableExprComponentListRef, 8>>
ComponentListMap;
{
auto CI = ComponentLists.begin();

View File

@ -593,6 +593,16 @@ bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
#define STMT(CLASS, PARENT) \
case Stmt::CLASS##Class: \
TRY_TO(WalkUpFrom##CLASS(static_cast<CLASS *>(S))); break;
#define INITLISTEXPR(CLASS, PARENT) \
case Stmt::CLASS##Class: \
{ \
auto ILE = static_cast<CLASS *>(S); \
if (auto Syn = ILE->isSemanticForm() ? ILE->getSyntacticForm() : ILE) \
TRY_TO(WalkUpFrom##CLASS(Syn)); \
if (auto Sem = ILE->isSemanticForm() ? ILE : ILE->getSemanticForm()) \
TRY_TO(WalkUpFrom##CLASS(Sem)); \
break; \
}
#include "clang/AST/StmtNodes.inc"
}
@ -2220,13 +2230,15 @@ bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
// the syntactic and the semantic form.
//
// There is no guarantee about which form \p S takes when this method is called.
DEF_TRAVERSE_STMT(InitListExpr, {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(
InitListExpr *S, DataRecursionQueue *Queue) {
TRY_TO(TraverseSynOrSemInitListExpr(
S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
TRY_TO(TraverseSynOrSemInitListExpr(
S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
ShouldVisitChildren = false;
})
return true;
}
// GenericSelectionExpr is a special case because the types and expressions
// are interleaved. We also need to watch out for null types (default

View File

@ -21,6 +21,60 @@
namespace clang {
class ASTContext;
// Some notes on redeclarables:
//
// - Every redeclarable is on a circular linked list.
//
// - Every decl has a pointer to the first element of the chain _and_ a
// DeclLink that may point to one of 3 possible states:
// - the "previous" (temporal) element in the chain
// - the "latest" (temporal) element in the chain
// - the an "uninitialized-latest" value (when newly-constructed)
//
// - The first element is also often called the canonical element. Every
// element has a pointer to it so that "getCanonical" can be fast.
//
// - Most links in the chain point to previous, except the link out of
// the first; it points to latest.
//
// - Elements are called "first", "previous", "latest" or
// "most-recent" when referring to temporal order: order of addition
// to the chain.
//
// - To make matters confusing, the DeclLink type uses the term "next"
// for its pointer-storage internally (thus functions like
// NextIsPrevious). It's easiest to just ignore the implementation of
// DeclLink when making sense of the redeclaration chain.
//
// - There's also a "definition" link for several types of
// redeclarable, where only one definition should exist at any given
// time (and the defn pointer is stored in the decl's "data" which
// is copied to every element on the chain when it's changed).
//
// Here is some ASCII art:
//
// "first" "latest"
// "canonical" "most recent"
// +------------+ first +--------------+
// | | <--------------------------- | |
// | | | |
// | | | |
// | | +--------------+ | |
// | | first | | | |
// | | <---- | | | |
// | | | | | |
// | @class A | link | @interface A | link | @class A |
// | seen first | <---- | seen second | <---- | seen third |
// | | | | | |
// +------------+ +--------------+ +--------------+
// | data | defn | data | defn | data |
// | | ----> | | <---- | |
// +------------+ +--------------+ +--------------+
// | | ^ ^
// | |defn | |
// | link +-----+ |
// +-->-------------------------------------------+
/// \brief Provides common interface for the Decls that can be redeclared.
template<typename decl_type>
class Redeclarable {

View File

@ -605,20 +605,27 @@ semantics:
for ``T`` and ``U`` to be incompatible.
The declaration of ``overloadable`` functions is restricted to function
declarations and definitions. Most importantly, if any function with a given
name is given the ``overloadable`` attribute, then all function declarations
and definitions with that name (and in that scope) must have the
``overloadable`` attribute. This rule even applies to redeclarations of
functions whose original declaration had the ``overloadable`` attribute, e.g.,
declarations and definitions. If a function is marked with the ``overloadable``
attribute, then all declarations and definitions of functions with that name,
except for at most one (see the note below about unmarked overloads), must have
the ``overloadable`` attribute. In addition, redeclarations of a function with
the ``overloadable`` attribute must have the ``overloadable`` attribute, and
redeclarations of a function without the ``overloadable`` attribute must *not*
have the ``overloadable`` attribute. e.g.,
.. code-block:: c
int f(int) __attribute__((overloadable));
float f(float); // error: declaration of "f" must have the "overloadable" attribute
int f(int); // error: redeclaration of "f" must have the "overloadable" attribute
int g(int) __attribute__((overloadable));
int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute
int h(int);
int h(int) __attribute__((overloadable)); // error: declaration of "h" must not
// have the "overloadable" attribute
Functions marked ``overloadable`` must have prototypes. Therefore, the
following code is ill-formed:
@ -651,7 +658,28 @@ caveats to this use of name mangling:
linkage specification, it's name *will* be mangled in the same way as it
would in C.
Query for this feature with ``__has_extension(attribute_overloadable)``.
For the purpose of backwards compatibility, at most one function with the same
name as other ``overloadable`` functions may omit the ``overloadable``
attribute. In this case, the function without the ``overloadable`` attribute
will not have its name mangled.
For example:
.. code-block:: c
// Notes with mangled names assume Itanium mangling.
int f(int);
int f(double) __attribute__((overloadable));
void foo() {
f(5); // Emits a call to f (not _Z1fi, as it would with an overload that
// was marked with overloadable).
f(1.0); // Emits a call to _Z1fd.
}
Support for unmarked overloads is not present in some versions of clang. You may
query for it using ``__has_extension(overloadable_unmarked)``.
Query for this attribute with ``__has_attribute(overloadable)``.
}];
}

View File

@ -0,0 +1,70 @@
//===-- BuiltinsNios2.def - Nios2 Builtin function database --------*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the Nios2-specific builtin function database. Users of
// this file must define the BUILTIN macro to make use of this information.
//
//===----------------------------------------------------------------------===//
// The format of this database matches clang/Basic/Builtins.def.
#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
// Nios2 R1 builtins:
//int __builtin_ldbio(volatile const void *);
BUILTIN(__builtin_ldbio, "ivDC*", "")
//int __builtin_ldbuio(volatile const void *);
BUILTIN(__builtin_ldbuio, "ivDC*", "")
//int __builtin_ldhio(volatile const void *);
BUILTIN(__builtin_ldhio, "ivDC*", "")
//int __builtin_ldhuio(volatile const void *);
BUILTIN(__builtin_ldhuio, "ivDC*", "")
//int __builtin_ldwio(volatile const void *);
BUILTIN(__builtin_ldwio, "ivDC*", "")
//int __builtin_ldwuio(int);
BUILTIN(__builtin_ldwuio, "ii", "")
// int __builtin_rdctl(int);
BUILTIN(__builtin_rdctl, "iIi", "")
// void __builtin_wrctl(int, int);
BUILTIN(__builtin_wrctl, "vIii", "")
// int __builtin_rdprs(int, int);
BUILTIN(__builtin_rdprs, "iii", "")
//void __builtin_stbio(volatile void *, int);
BUILTIN(__builtin_stbio, "vvD*i", "")
//void __builtin_sthio(volatile void *, int);
BUILTIN(__builtin_sthio, "vvD*i", "")
//void __builtin_stwio(volatile void *, int);
BUILTIN(__builtin_stwio, "vvD*i", "")
//void __builtin_sync(void);
BUILTIN(__builtin_sync, "v", "")
// void __builtin_flushd(volatile void *);
BUILTIN(__builtin_flushd, "vvD*", "")
// void __builtin_flushda(volatile void *);
BUILTIN(__builtin_flushda, "vvD*", "")
// Nios2 R2 builtins:
// int __builtin_wrpie(int);
TARGET_BUILTIN(__builtin_wrpie, "ii", "", "nios2r2mandatory")
// void __builtin_eni(int);
TARGET_BUILTIN(__builtin_eni, "vi", "", "nios2r2mandatory")
// int __builtin_ldex(volatile const void *);
TARGET_BUILTIN(__builtin_ldex, "ivDC*", "", "nios2r2mandatory")
// int __builtin_stex(volatile void *, int);
TARGET_BUILTIN(__builtin_stex, "ivD*i", "", "nios2r2mandatory")
// int __builtin_ldsex(volatile const void *);
TARGET_BUILTIN(__builtin_ldsex, "ivDC*", "", "nios2r2mpx")
// int __builtin_stsex(volatile void *, int);
TARGET_BUILTIN(__builtin_stsex, "ivDC*i", "", "nios2r2mpx")
#undef BUILTIN
#undef TARGET_BUILTIN

View File

@ -21,4 +21,8 @@
BUILTIN(__builtin_wasm_current_memory, "z", "n")
BUILTIN(__builtin_wasm_grow_memory, "zz", "n")
// Exception handling builtins.
BUILTIN(__builtin_wasm_throw, "vUiv*", "r")
BUILTIN(__builtin_wasm_rethrow, "v", "r")
#undef BUILTIN

View File

@ -200,12 +200,17 @@ def note_odr_defined_here : Note<"also defined here">;
def err_odr_function_type_inconsistent : Error<
"external function %0 declared with incompatible types in different "
"translation units (%1 vs. %2)">;
def warn_odr_tag_type_inconsistent : Warning<
"type %0 has incompatible definitions in different translation units">,
InGroup<DiagGroup<"odr">>;
def warn_odr_tag_type_inconsistent
: Warning<"type %0 has incompatible definitions in different translation "
"units">,
InGroup<DiagGroup<"odr">>;
def err_odr_tag_type_inconsistent
: Error<"type %0 has incompatible definitions in different translation "
"units">;
def note_odr_tag_kind_here: Note<
"%0 is a %select{struct|interface|union|class|enum}1 here">;
def note_odr_field : Note<"field %0 has type %1 here">;
def note_odr_field_name : Note<"field has name %0 here">;
def note_odr_missing_field : Note<"no corresponding field here">;
def note_odr_bit_field : Note<"bit-field %0 with type %1 and length %2 here">;
def note_odr_not_bit_field : Note<"field %0 is not a bit-field">;

View File

@ -138,6 +138,9 @@ def err_drv_cc_print_options_failure : Error<
def err_drv_lto_without_lld : Error<"LTO requires -fuse-ld=lld">;
def err_drv_preamble_format : Error<
"incorrect format for -preamble-bytes=N,END">;
def err_invalid_ios_deployment_target : Error<
"invalid iOS deployment version '%0', iOS 10 is the maximum deployment "
"target for 32-bit targets">;
def err_drv_conflicting_deployment_targets : Error<
"conflicting deployment targets, both '%0' and '%1' are present in environment">;
def err_arc_unsupported_on_runtime : Error<
@ -195,8 +198,8 @@ def warn_drv_unused_argument : Warning<
def warn_drv_empty_joined_argument : Warning<
"joined argument expects additional value: '%0'">,
InGroup<UnusedCommandLineArgument>;
def warn_drv_fdiagnostics_show_hotness_requires_pgo : Warning<
"argument '-fdiagnostics-show-hotness' requires profile-guided optimization information">,
def warn_drv_diagnostics_hotness_requires_pgo : Warning<
"argument '%0' requires profile-guided optimization information">,
InGroup<UnusedCommandLineArgument>;
def warn_drv_clang_unsupported : Warning<
"the clang compiler does not support '%0'">;

View File

@ -311,6 +311,7 @@ def : DiagGroup<"nonportable-cfstrings">;
def NonVirtualDtor : DiagGroup<"non-virtual-dtor">;
def : DiagGroup<"effc++", [NonVirtualDtor]>;
def OveralignedType : DiagGroup<"over-aligned">;
def AlignedAllocationUnavailable : DiagGroup<"aligned-allocation-unavailable">;
def OldStyleCast : DiagGroup<"old-style-cast">;
def : DiagGroup<"old-style-definition">;
def OutOfLineDeclaration : DiagGroup<"out-of-line-declaration">;

View File

@ -3294,13 +3294,15 @@ def warn_iboutletcollection_property_assign : Warning<
"IBOutletCollection properties should be copy/strong and not assign">,
InGroup<ObjCInvalidIBOutletProperty>;
def err_attribute_overloadable_missing : Error<
"%select{overloaded function|redeclaration of}0 %1 must have the "
"'overloadable' attribute">;
def err_attribute_overloadable_mismatch : Error<
"redeclaration of %0 must %select{not |}1have the 'overloadable' attribute">;
def note_attribute_overloadable_prev_overload : Note<
"previous overload of function is here">;
"previous %select{unmarked |}0overload of function is here">;
def err_attribute_overloadable_no_prototype : Error<
"'overloadable' function %0 must have a prototype">;
def err_attribute_overloadable_multiple_unmarked_overloads : Error<
"at most one overload for a given name may lack the 'overloadable' "
"attribute">;
def warn_ns_attribute_wrong_return_type : Warning<
"%0 attribute only applies to %select{functions|methods|properties}1 that "
"return %select{an Objective-C object|a pointer|a non-retainable pointer}2">,
@ -6405,6 +6407,12 @@ def warn_overaligned_type : Warning<
"type %0 requires %1 bytes of alignment and the default allocator only "
"guarantees %2 bytes">,
InGroup<OveralignedType>, DefaultIgnore;
def warn_aligned_allocation_unavailable :Warning<
"aligned %select{allocation|deallocation}0 function of type '%1' possibly "
"unavailable on %2">, InGroup<AlignedAllocationUnavailable>, DefaultError;
def note_silence_unligned_allocation_unavailable : Note<
"if you supply your own aligned allocation functions, use "
"-Wno-aligned-allocation-unavailable to silence this diagnostic">;
def err_conditional_void_nonvoid : Error<
"%select{left|right}1 operand to ? is void, but %select{right|left}1 operand "
@ -8402,7 +8410,7 @@ def warn_opencl_attr_deprecated_ignored : Warning <
def err_opencl_variadic_function : Error<
"invalid prototype, variadic arguments are not allowed in OpenCL">;
def err_opencl_requires_extension : Error<
"use of %select{type |declaration}0%1 requires %2 extension to be enabled">;
"use of %select{type|declaration}0 %1 requires %2 extension to be enabled">;
// OpenCL v2.0 s6.13.6 -- Builtin Pipe Functions
def err_opencl_builtin_pipe_first_arg : Error<

View File

@ -199,6 +199,7 @@ LANGOPT(CUDADeviceApproxTranscendentals, 1, 0, "using approximate transcendental
LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable")
LANGOPT(NewAlignOverride , 32, 0, "maximum alignment guaranteed by '::operator new(size_t)'")
LANGOPT(ConceptsTS , 1, 0, "enable C++ Extensions for Concepts")
BENIGN_LANGOPT(ModulesCodegen , 1, 0, "Modules code generation")

View File

@ -552,6 +552,7 @@ OPENMP_TASKLOOP_CLAUSE(priority)
OPENMP_TASKLOOP_CLAUSE(grainsize)
OPENMP_TASKLOOP_CLAUSE(nogroup)
OPENMP_TASKLOOP_CLAUSE(num_tasks)
OPENMP_TASKLOOP_CLAUSE(reduction)
// Clauses allowed for OpenMP directive 'taskloop simd'.
OPENMP_TASKLOOP_SIMD_CLAUSE(if)
@ -572,6 +573,7 @@ OPENMP_TASKLOOP_SIMD_CLAUSE(simdlen)
OPENMP_TASKLOOP_SIMD_CLAUSE(grainsize)
OPENMP_TASKLOOP_SIMD_CLAUSE(nogroup)
OPENMP_TASKLOOP_SIMD_CLAUSE(num_tasks)
OPENMP_TASKLOOP_SIMD_CLAUSE(reduction)
// Clauses allowed for OpenMP directive 'critical'.
OPENMP_CRITICAL_CLAUSE(hint)

View File

@ -262,6 +262,65 @@ class CharSourceRange {
bool isInvalid() const { return !isValid(); }
};
/// \brief Represents an unpacked "presumed" location which can be presented
/// to the user.
///
/// A 'presumed' location can be modified by \#line and GNU line marker
/// directives and is always the expansion point of a normal location.
///
/// You can get a PresumedLoc from a SourceLocation with SourceManager.
class PresumedLoc {
const char *Filename;
unsigned Line, Col;
SourceLocation IncludeLoc;
public:
PresumedLoc() : Filename(nullptr) {}
PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
: Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {}
/// \brief Return true if this object is invalid or uninitialized.
///
/// This occurs when created with invalid source locations or when walking
/// off the top of a \#include stack.
bool isInvalid() const { return Filename == nullptr; }
bool isValid() const { return Filename != nullptr; }
/// \brief Return the presumed filename of this location.
///
/// This can be affected by \#line etc.
const char *getFilename() const {
assert(isValid());
return Filename;
}
/// \brief Return the presumed line number of this location.
///
/// This can be affected by \#line etc.
unsigned getLine() const {
assert(isValid());
return Line;
}
/// \brief Return the presumed column number of this location.
///
/// This cannot be affected by \#line, but is packaged here for convenience.
unsigned getColumn() const {
assert(isValid());
return Col;
}
/// \brief Return the presumed include location of this location.
///
/// This can be affected by GNU linemarker directives.
SourceLocation getIncludeLoc() const {
assert(isValid());
return IncludeLoc;
}
};
class FileEntry;
/// \brief A SourceLocation and its associated SourceManager.
///
/// This is useful for argument passing to functions that expect both objects.
@ -274,6 +333,12 @@ class FullSourceLoc : public SourceLocation {
explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
: SourceLocation(Loc), SrcMgr(&SM) {}
bool hasManager() const {
bool hasSrcMgr = SrcMgr != nullptr;
assert(hasSrcMgr == isValid() && "FullSourceLoc has location but no manager");
return hasSrcMgr;
}
/// \pre This FullSourceLoc has an associated SourceManager.
const SourceManager &getManager() const {
assert(SrcMgr && "SourceManager is NULL.");
@ -284,6 +349,13 @@ class FullSourceLoc : public SourceLocation {
FullSourceLoc getExpansionLoc() const;
FullSourceLoc getSpellingLoc() const;
FullSourceLoc getFileLoc() const;
std::pair<FullSourceLoc, FullSourceLoc> getImmediateExpansionRange() const;
PresumedLoc getPresumedLoc(bool UseLineDirectives = true) const;
bool isMacroArgExpansion(FullSourceLoc *StartLoc = nullptr) const;
FullSourceLoc getImmediateMacroCallerLoc() const;
std::pair<FullSourceLoc, StringRef> getModuleImportLoc() const;
unsigned getFileOffset() const;
unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
@ -293,6 +365,12 @@ class FullSourceLoc : public SourceLocation {
const char *getCharacterData(bool *Invalid = nullptr) const;
unsigned getLineNumber(bool *Invalid = nullptr) const;
unsigned getColumnNumber(bool *Invalid = nullptr) const;
std::pair<FullSourceLoc, FullSourceLoc> getExpansionRange() const;
const FileEntry *getFileEntry() const;
/// \brief Return a StringRef to the source buffer data for the
/// specified FileID.
@ -345,50 +423,6 @@ class FullSourceLoc : public SourceLocation {
};
/// \brief Represents an unpacked "presumed" location which can be presented
/// to the user.
///
/// A 'presumed' location can be modified by \#line and GNU line marker
/// directives and is always the expansion point of a normal location.
///
/// You can get a PresumedLoc from a SourceLocation with SourceManager.
class PresumedLoc {
const char *Filename;
unsigned Line, Col;
SourceLocation IncludeLoc;
public:
PresumedLoc() : Filename(nullptr) {}
PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
: Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
}
/// \brief Return true if this object is invalid or uninitialized.
///
/// This occurs when created with invalid source locations or when walking
/// off the top of a \#include stack.
bool isInvalid() const { return Filename == nullptr; }
bool isValid() const { return Filename != nullptr; }
/// \brief Return the presumed filename of this location.
///
/// This can be affected by \#line etc.
const char *getFilename() const { assert(isValid()); return Filename; }
/// \brief Return the presumed line number of this location.
///
/// This can be affected by \#line etc.
unsigned getLine() const { assert(isValid()); return Line; }
/// \brief Return the presumed column number of this location.
///
/// This cannot be affected by \#line, but is packaged here for convenience.
unsigned getColumn() const { assert(isValid()); return Col; }
/// \brief Return the presumed include location of this location.
///
/// This can be affected by GNU linemarker directives.
SourceLocation getIncludeLoc() const { assert(isValid()); return IncludeLoc; }
};
} // end namespace clang

View File

@ -80,9 +80,19 @@ namespace SrcMgr {
/// system_header is seen or in various other cases.
///
enum CharacteristicKind {
C_User, C_System, C_ExternCSystem
C_User, C_System, C_ExternCSystem, C_User_ModuleMap, C_System_ModuleMap
};
/// Determine whether a file / directory characteristic is for system code.
inline bool isSystem(CharacteristicKind CK) {
return CK != C_User && CK != C_User_ModuleMap;
}
/// Determine whether a file characteristic is for a module map.
inline bool isModuleMap(CharacteristicKind CK) {
return CK == C_User_ModuleMap || CK == C_System_ModuleMap;
}
/// \brief One instance of this struct is kept for every file loaded or used.
///
/// This object owns the MemoryBuffer object.
@ -251,12 +261,14 @@ namespace SrcMgr {
/// preprocessing of this \#include, including this SLocEntry.
///
/// Zero means the preprocessor didn't provide such info for this SLocEntry.
unsigned NumCreatedFIDs;
unsigned NumCreatedFIDs : 31;
/// \brief Contains the ContentCache* and the bits indicating the
/// characteristic of the file and whether it has \#line info, all
/// bitmangled together.
uintptr_t Data;
/// \brief Whether this FileInfo has any \#line directives.
unsigned HasLineDirectives : 1;
/// \brief The content cache and the characteristic of the file.
llvm::PointerIntPair<const ContentCache*, 3, CharacteristicKind>
ContentAndKind;
friend class clang::SourceManager;
friend class clang::ASTWriter;
@ -269,10 +281,9 @@ namespace SrcMgr {
FileInfo X;
X.IncludeLoc = IL.getRawEncoding();
X.NumCreatedFIDs = 0;
X.Data = (uintptr_t)Con;
assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned");
assert((unsigned)FileCharacter < 4 && "invalid file character");
X.Data |= (unsigned)FileCharacter;
X.HasLineDirectives = false;
X.ContentAndKind.setPointer(Con);
X.ContentAndKind.setInt(FileCharacter);
return X;
}
@ -280,22 +291,22 @@ namespace SrcMgr {
return SourceLocation::getFromRawEncoding(IncludeLoc);
}
const ContentCache* getContentCache() const {
return reinterpret_cast<const ContentCache*>(Data & ~uintptr_t(7));
const ContentCache *getContentCache() const {
return ContentAndKind.getPointer();
}
/// \brief Return whether this is a system header or not.
CharacteristicKind getFileCharacteristic() const {
return (CharacteristicKind)(Data & 3);
return ContentAndKind.getInt();
}
/// \brief Return true if this FileID has \#line directives in it.
bool hasLineDirectives() const { return (Data & 4) != 0; }
bool hasLineDirectives() const { return HasLineDirectives; }
/// \brief Set the flag that indicates that this FileID has
/// line table entries associated with it.
void setHasLineDirectives() {
Data |= 4;
HasLineDirectives = true;
}
};
@ -407,6 +418,8 @@ namespace SrcMgr {
};
public:
SLocEntry() : Offset(), IsExpansion(), File() {}
unsigned getOffset() const { return Offset; }
bool isExpansion() const { return IsExpansion; }
@ -789,9 +802,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
SrcMgr::CharacteristicKind FileCharacter,
int LoadedID = 0, unsigned LoadedOffset = 0) {
const SrcMgr::ContentCache *
IR = getOrCreateContentCache(SourceFile,
/*isSystemFile=*/FileCharacter != SrcMgr::C_User);
const SrcMgr::ContentCache *IR =
getOrCreateContentCache(SourceFile, isSystem(FileCharacter));
assert(IR && "getOrCreateContentCache() cannot return NULL");
return createFileID(IR, IncludePos, FileCharacter, LoadedID, LoadedOffset);
}
@ -1360,7 +1372,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// \brief Returns if a SourceLocation is in a system header.
bool isInSystemHeader(SourceLocation Loc) const {
return getFileCharacteristic(Loc) != SrcMgr::C_User;
return isSystem(getFileCharacteristic(Loc));
}
/// \brief Returns if a SourceLocation is in an "extern C" system header.
@ -1477,6 +1489,17 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// \returns true if LHS source location comes before RHS, false otherwise.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const;
/// \brief Determines whether the two decomposed source location is in the
/// same translation unit. As a byproduct, it also calculates the order
/// of the source locations in case they are in the same TU.
///
/// \returns Pair of bools the first component is true if the two locations
/// are in the same TU. The second bool is true if the first is true
/// and \p LOffs is before \p ROffs.
std::pair<bool, bool>
isInTheSameTranslationUnit(std::pair<FileID, unsigned> &LOffs,
std::pair<FileID, unsigned> &ROffs) const;
/// \brief Determines the order of 2 source locations in the "source location
/// address space".
bool isBeforeInSLocAddrSpace(SourceLocation LHS, SourceLocation RHS) const {

View File

@ -150,6 +150,16 @@ namespace clang {
};
}
/// \brief Nios2 builtins
namespace Nios2 {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsNios2.def"
LastTSBuiltin
};
}
/// \brief MIPS builtins
namespace Mips {
enum {

View File

@ -18,6 +18,7 @@
#include <string>
#include <vector>
#include "clang/Basic/OpenCLOptions.h"
#include "llvm/Target/TargetOptions.h"
namespace clang {
@ -41,7 +42,7 @@ class TargetOptions {
std::string ABI;
/// The EABI version to use
std::string EABIVersion;
llvm::EABI EABIVersion;
/// If given, the version string of the linker in use.
std::string LinkerVersion;

View File

@ -75,6 +75,9 @@ class LinkageInfo {
static LinkageInfo none() {
return LinkageInfo(NoLinkage, DefaultVisibility, false);
}
static LinkageInfo visible_none() {
return LinkageInfo(VisibleNoLinkage, DefaultVisibility, false);
}
Linkage getLinkage() const { return (Linkage)linkage_; }
Visibility getVisibility() const { return (Visibility)visibility_; }

View File

@ -145,7 +145,7 @@ def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
HelpText<"The string to embed in the Dwarf debug flags record.">;
def compress_debug_sections : Flag<["-", "--"], "compress-debug-sections">,
HelpText<"DWARF debug sections compression">;
def compress_debug_sections_EQ : Flag<["-"], "compress-debug-sections=">,
def compress_debug_sections_EQ : Joined<["-"], "compress-debug-sections=">,
HelpText<"DWARF debug sections compression type">;
def mno_exec_stack : Flag<["-"], "mnoexecstack">,
HelpText<"Mark the file as not needing an executable stack">;
@ -268,8 +268,6 @@ def vectorize_loops : Flag<["-"], "vectorize-loops">,
HelpText<"Run the Loop vectorization passes">;
def vectorize_slp : Flag<["-"], "vectorize-slp">,
HelpText<"Run the SLP vectorization passes">;
def vectorize_slp_aggressive : Flag<["-"], "vectorize-slp-aggressive">,
HelpText<"Run the BB vectorization passes">;
def dependent_lib : Joined<["--"], "dependent-lib=">,
HelpText<"Add dependent library">;
def linker_option : Joined<["--"], "linker-option=">,
@ -323,6 +321,10 @@ def flto_unit: Flag<["-"], "flto-unit">,
def fno_lto_unit: Flag<["-"], "fno-lto-unit">;
def fthin_link_bitcode_EQ : Joined<["-"], "fthin-link-bitcode=">,
HelpText<"Write minimized bitcode to <file> for the ThinLTO thin link only">;
def fdebug_pass_manager : Flag<["-"], "fdebug-pass-manager">,
HelpText<"Prints debug information for the new pass manager">;
def fno_debug_pass_manager : Flag<["-"], "fno-debug-pass-manager">,
HelpText<"Disables debug printing for the new pass manager">;
//===----------------------------------------------------------------------===//
// Dependency Output Options
@ -568,6 +570,9 @@ def find_pch_source_EQ : Joined<["-"], "find-pch-source=">,
def fno_pch_timestamp : Flag<["-"], "fno-pch-timestamp">,
HelpText<"Disable inclusion of timestamp in precompiled headers">;
def aligned_alloc_unavailable : Flag<["-"], "faligned-alloc-unavailable">,
HelpText<"Aligned allocation/deallocation functions are unavailable">;
//===----------------------------------------------------------------------===//
// Language Options
//===----------------------------------------------------------------------===//

View File

@ -105,10 +105,13 @@ class Compilation {
/// Whether we're compiling for diagnostic purposes.
bool ForDiagnostics;
/// Whether an error during the parsing of the input args.
bool ContainsError;
public:
Compilation(const Driver &D, const ToolChain &DefaultToolChain,
llvm::opt::InputArgList *Args,
llvm::opt::DerivedArgList *TranslatedArgs);
llvm::opt::DerivedArgList *TranslatedArgs, bool ContainsError);
~Compilation();
const Driver &getDriver() const { return TheDriver; }
@ -275,6 +278,9 @@ class Compilation {
/// Return true if we're compiling for diagnostics.
bool isForDiagnostics() const { return ForDiagnostics; }
/// Return whether an error during the parsing of the input args.
bool containsError() const { return ContainsError; }
/// Redirect - Redirect output of this compilation. Can only be done once.
///
/// \param Redirects - array of pointers to paths. The array

View File

@ -341,7 +341,8 @@ class Driver {
/// ParseArgStrings - Parse the given list of strings into an
/// ArgList.
llvm::opt::InputArgList ParseArgStrings(ArrayRef<const char *> Args);
llvm::opt::InputArgList ParseArgStrings(ArrayRef<const char *> Args,
bool &ContainsError);
/// BuildInputs - Construct the list of inputs and their types from
/// the given arguments.

View File

@ -723,6 +723,9 @@ def fdiagnostics_print_source_range_info : Flag<["-"], "fdiagnostics-print-sourc
HelpText<"Print source range spans in numeric form">;
def fdiagnostics_show_hotness : Flag<["-"], "fdiagnostics-show-hotness">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Enable profile hotness information in diagnostic line">;
def fdiagnostics_hotness_threshold_EQ : Joined<["-"], "fdiagnostics-hotness-threshold=">,
Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<number>">,
HelpText<"Prevent optimization remarks from being output if they do not have at least this profile count">;
def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Print option name with mappable diagnostics">;
def fdiagnostics_show_note_include_stack : Flag<["-"], "fdiagnostics-show-note-include-stack">,
@ -1405,9 +1408,6 @@ def : Flag<["-"], "fno-tree-vectorize">, Alias<fno_vectorize>;
def fslp_vectorize : Flag<["-"], "fslp-vectorize">, Group<f_Group>,
HelpText<"Enable the superword-level parallelism vectorization passes">;
def fno_slp_vectorize : Flag<["-"], "fno-slp-vectorize">, Group<f_Group>;
def fslp_vectorize_aggressive : Flag<["-"], "fslp-vectorize-aggressive">, Group<f_Group>,
HelpText<"Enable the BB vectorization passes">;
def fno_slp_vectorize_aggressive : Flag<["-"], "fno-slp-vectorize-aggressive">, Group<f_Group>;
def : Flag<["-"], "ftree-slp-vectorize">, Alias<fslp_vectorize>;
def : Flag<["-"], "fno-tree-slp-vectorize">, Alias<fno_slp_vectorize>;
def Wlarge_by_value_copy_def : Flag<["-"], "Wlarge-by-value-copy">,

View File

@ -717,7 +717,29 @@ struct FormatStyle {
/// }
/// \endcode
///
bool SplitEmptyFunctionBody;
bool SplitEmptyFunction;
/// \brief If ``false``, empty record (e.g. class, struct or union) body
/// can be put on a single line. This option is used only if the opening
/// brace of the record has already been wrapped, i.e. the `AfterClass`
/// (for classes) brace wrapping mode is set.
/// \code
/// class Foo vs. class Foo
/// {} {
/// }
/// \endcode
///
bool SplitEmptyRecord;
/// \brief If ``false``, empty namespace body can be put on a single line.
/// This option is used only if the opening brace of the namespace has
/// already been wrapped, i.e. the `AfterNamespace` brace wrapping mode is
/// set.
/// \code
/// namespace Foo vs. namespace Foo
/// {} {
/// }
/// \endcode
///
bool SplitEmptyNamespace;
};
/// \brief Control of individual brace wrapping cases.
@ -966,7 +988,7 @@ struct FormatStyle {
/// IncludeCategories:
/// - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
/// Priority: 2
/// - Regex: '^(<|"(gtest|isl|json)/)'
/// - Regex: '^(<|"(gtest|gmock|isl|json)/)'
/// Priority: 3
/// - Regex: '.*'
/// Priority: 1

View File

@ -628,6 +628,15 @@ class ASTUnit {
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool CaptureDiagnostics,
bool UserFilesAreVolatile);
enum WhatToLoad {
/// Load options and the preprocessor state.
LoadPreprocessorOnly,
/// Load the AST, but do not restore Sema state.
LoadASTOnly,
/// Load everything, including Sema.
LoadEverything
};
/// \brief Create a ASTUnit from an AST file.
///
/// \param Filename - The AST file to load.
@ -640,7 +649,7 @@ class ASTUnit {
/// \returns - The initialized ASTUnit or null if the AST failed to load.
static std::unique_ptr<ASTUnit> LoadFromASTFile(
const std::string &Filename, const PCHContainerReader &PCHContainerRdr,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
const FileSystemOptions &FileSystemOpts, bool UseDebugInfo = false,
bool OnlyLocalDecls = false, ArrayRef<RemappedFile> RemappedFiles = None,
bool CaptureDiagnostics = false, bool AllowPCHWithCompilerErrors = false,

View File

@ -57,6 +57,8 @@ CODEGENOPT(DisableLifetimeMarkers, 1, 0) ///< Don't emit any lifetime markers
CODEGENOPT(DisableO0ImplyOptNone , 1, 0) ///< Don't annonate function with optnone at O0
CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental
///< pass manager.
CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new
///< pass manager.
CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled.
CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls.
CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what
@ -177,7 +179,6 @@ CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled.
CODEGENOPT(NoUseJumpTables , 1, 0) ///< Set when -fno-jump-tables is enabled.
CODEGENOPT(UnsafeFPMath , 1, 0) ///< Allow unsafe floating point optzns.
CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables.
CODEGENOPT(VectorizeBB , 1, 0) ///< Run basic block vectorizer.
CODEGENOPT(VectorizeLoop , 1, 0) ///< Run loop vectorizer.
CODEGENOPT(VectorizeSLP , 1, 0) ///< Run SLP vectorizer.
@ -260,6 +261,10 @@ VALUE_CODEGENOPT(EmitCheckPathComponentsToStrip, 32, 0)
/// Whether to report the hotness of the code region for optimization remarks.
CODEGENOPT(DiagnosticsWithHotness, 1, 0)
/// The minimum hotness value a diagnostic needs in order to be included in
/// optimization diagnostics.
VALUE_CODEGENOPT(DiagnosticsHotnessThreshold, 32, 0)
/// Whether copy relocations support is available when building as PIE.
CODEGENOPT(PIECopyRelocations, 1, 0)

View File

@ -70,33 +70,27 @@ class DiagnosticRenderer {
DiagnosticOptions *DiagOpts);
virtual ~DiagnosticRenderer();
virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
virtual void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
ArrayRef<CharSourceRange> Ranges,
const SourceManager *SM,
DiagOrStoredDiag Info) = 0;
virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) = 0;
virtual void emitCodeContext(SourceLocation Loc,
virtual void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges) = 0;
virtual void emitCodeContext(FullSourceLoc Loc,
DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) = 0;
virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
const SourceManager &SM) = 0;
virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) = 0;
virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) = 0;
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints) = 0;
virtual void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) = 0;
virtual void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) = 0;
virtual void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) = 0;
virtual void beginDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) {}
@ -106,25 +100,21 @@ class DiagnosticRenderer {
private:
void emitBasicNote(StringRef Message);
void emitIncludeStack(SourceLocation Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, const SourceManager &SM);
void emitIncludeStackRecursively(SourceLocation Loc, const SourceManager &SM);
void emitImportStack(SourceLocation Loc, const SourceManager &SM);
void emitImportStackRecursively(SourceLocation Loc, StringRef ModuleName,
const SourceManager &SM);
void emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level);
void emitIncludeStackRecursively(FullSourceLoc Loc);
void emitImportStack(FullSourceLoc Loc);
void emitImportStackRecursively(FullSourceLoc Loc, StringRef ModuleName);
void emitModuleBuildStack(const SourceManager &SM);
void emitCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints,
const SourceManager &SM);
void emitSingleMacroExpansion(SourceLocation Loc,
void emitCaret(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints);
void emitSingleMacroExpansion(FullSourceLoc Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM);
void emitMacroExpansions(SourceLocation Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges);
void emitMacroExpansions(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM);
ArrayRef<FixItHint> Hints);
public:
/// \brief Emit a diagnostic.
///
@ -138,12 +128,9 @@ class DiagnosticRenderer {
/// \param Message The diagnostic message to emit.
/// \param Ranges The underlined ranges for this code snippet.
/// \param FixItHints The FixIt hints active for this diagnostic.
/// \param SM The SourceManager; will be null if the diagnostic came from the
/// frontend, thus \p Loc will be invalid.
void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
void emitDiagnostic(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
StringRef Message, ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> FixItHints,
const SourceManager *SM,
DiagOrStoredDiag D = (Diagnostic *)nullptr);
void emitStoredDiagnostic(StoredDiagnostic &Diag);
@ -159,19 +146,15 @@ class DiagnosticNoteRenderer : public DiagnosticRenderer {
~DiagnosticNoteRenderer() override;
void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
const SourceManager &SM) override;
void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) override;
void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) override;
void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) override;
void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) override;
void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) override;
virtual void emitNote(SourceLocation Loc, StringRef Message,
const SourceManager *SM) = 0;
virtual void emitNote(FullSourceLoc Loc, StringRef Message) = 0;
};
} // end clang namespace
#endif

View File

@ -75,44 +75,35 @@ class TextDiagnostic : public DiagnosticRenderer {
unsigned Columns, bool ShowColors);
protected:
void emitDiagnosticMessage(SourceLocation Loc,PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, StringRef Message,
ArrayRef<CharSourceRange> Ranges,
const SourceManager *SM,
DiagOrStoredDiag D) override;
void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) override;
ArrayRef<CharSourceRange> Ranges) override;
void emitCodeContext(SourceLocation Loc,
DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) override {
emitSnippetAndCaret(Loc, Level, Ranges, Hints, SM);
void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints) override {
emitSnippetAndCaret(Loc, Level, Ranges, Hints);
}
void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
const SourceManager &SM) override;
void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) override;
void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) override;
void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) override;
void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) override;
void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) override;
private:
void emitFilename(StringRef Filename, const SourceManager &SM);
void emitSnippetAndCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM);
void emitSnippetAndCaret(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints);
void emitSnippet(StringRef SourceLine);

View File

@ -184,10 +184,11 @@ createChainedIncludesSource(CompilerInstance &CI,
///
/// \return A CompilerInvocation, or 0 if none was built for the given
/// argument vector.
std::unique_ptr<CompilerInvocation>
createInvocationFromCommandLine(ArrayRef<const char *> Args,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
IntrusiveRefCntPtr<DiagnosticsEngine>());
std::unique_ptr<CompilerInvocation> createInvocationFromCommandLine(
ArrayRef<const char *> Args,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
IntrusiveRefCntPtr<DiagnosticsEngine>(),
IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);
/// Return the value of the last argument as an integer, or a default. If Diags
/// is non-null, emits an error if the argument is given, but non-integral.

View File

@ -47,7 +47,7 @@ struct HeaderFileInfo {
/// whether it is C++ clean or not. This can be set by the include paths or
/// by \#pragma gcc system_header. This is an instance of
/// SrcMgr::CharacteristicKind.
unsigned DirInfo : 2;
unsigned DirInfo : 3;
/// \brief Whether this header file info was supplied by an external source,
/// and has not changed since.

View File

@ -36,7 +36,7 @@ class PTHLexer : public PreprocessorLexer {
const unsigned char* LastHashTokPtr;
/// PPCond - Pointer to a side table in the PTH file that provides a
/// a consise summary of the preproccessor conditional block structure.
/// a concise summary of the preprocessor conditional block structure.
/// This is used to perform quick skipping of conditional blocks.
const unsigned char* PPCond;

View File

@ -18,6 +18,8 @@
#include "clang/AST/DeclCXX.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/Optional.h"
namespace clang {
/// @brief Represents the results of name lookup.
@ -273,7 +275,7 @@ class LookupResult {
/// declarations, such as those in modules that have not yet been imported.
bool isHiddenDeclarationVisible(NamedDecl *ND) const {
return AllowHidden ||
(isForRedeclaration() && ND->isExternallyVisible());
(isForRedeclaration() && ND->hasExternalFormalLinkage());
}
/// Sets whether tag declarations should be hidden by non-tag
@ -465,7 +467,7 @@ class LookupResult {
Paths = nullptr;
}
} else {
AmbiguityKind SavedAK;
llvm::Optional<AmbiguityKind> SavedAK;
bool WasAmbiguous = false;
if (ResultKind == Ambiguous) {
SavedAK = Ambiguity;
@ -479,7 +481,7 @@ class LookupResult {
if (ResultKind == Ambiguous) {
(void)WasAmbiguous;
assert(WasAmbiguous);
Ambiguity = SavedAK;
Ambiguity = SavedAK.getValue();
} else if (Paths) {
deletePaths(Paths);
Paths = nullptr;

View File

@ -1542,6 +1542,10 @@ class Sema {
bool hasVisibleMergedDefinition(NamedDecl *Def);
/// Determine if \p D and \p Suggested have a structurally compatible
/// layout as described in C11 6.2.7/1.
bool hasStructuralCompatLayout(Decl *D, Decl *Suggested);
/// Determine if \p D has a visible definition. If not, suggest a declaration
/// that should be made visible to expose the definition.
bool hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested,
@ -1629,9 +1633,13 @@ class Sema {
//
struct SkipBodyInfo {
SkipBodyInfo() : ShouldSkip(false), Previous(nullptr) {}
SkipBodyInfo()
: ShouldSkip(false), CheckSameAsPrevious(false), Previous(nullptr),
New(nullptr) {}
bool ShouldSkip;
bool CheckSameAsPrevious;
NamedDecl *Previous;
NamedDecl *New;
};
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr);
@ -2145,13 +2153,11 @@ class Sema {
};
Decl *ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
SourceLocation KWLoc, CXXScopeSpec &SS,
IdentifierInfo *Name, SourceLocation NameLoc,
AttributeList *Attr, AccessSpecifier AS,
SourceLocation ModulePrivateLoc,
MultiTemplateParamsArg TemplateParameterLists,
bool &OwnedDecl, bool &IsDependent,
SourceLocation ScopedEnumKWLoc,
SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name,
SourceLocation NameLoc, AttributeList *Attr,
AccessSpecifier AS, SourceLocation ModulePrivateLoc,
MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl,
bool &IsDependent, SourceLocation ScopedEnumKWLoc,
bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
bool IsTypeSpecifier, bool IsTemplateParamOrArg,
SkipBodyInfo *SkipBody = nullptr);
@ -2219,6 +2225,12 @@ class Sema {
/// struct, or union).
void ActOnTagStartDefinition(Scope *S, Decl *TagDecl);
/// Perform ODR-like check for C/ObjC when merging tag types from modules.
/// Differently from C++, actually parse the body and reject / error out
/// in case of a structural mismatch.
bool ActOnDuplicateDefinition(DeclSpec &DS, Decl *Prev,
SkipBodyInfo &SkipBody);
typedef void *SkippedDefinitionContext;
/// \brief Invoked when we enter a tag definition that we're skipping.
@ -2272,8 +2284,8 @@ class Sema {
Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant,
SourceLocation IdLoc, IdentifierInfo *Id,
AttributeList *Attrs,
SourceLocation EqualLoc, Expr *Val);
AttributeList *Attrs, SourceLocation EqualLoc,
Expr *Val);
void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,
Decl *EnumDecl,
ArrayRef<Decl *> Elements,
@ -3233,7 +3245,7 @@ class Sema {
void ProcessPragmaWeak(Scope *S, Decl *D);
// Decl attributes - this routine is the top level dispatcher.
void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
// Helper for delayed proccessing of attributes.
// Helper for delayed processing of attributes.
void ProcessDeclAttributeDelayed(Decl *D, const AttributeList *AttrList);
void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL,
bool IncludeCXX11Attributes = true);
@ -8432,7 +8444,7 @@ class Sema {
/// is disabled due to required OpenCL extensions being disabled. If so,
/// emit diagnostics.
/// \return true if type is disabled.
bool checkOpenCLDisabledDecl(const Decl &D, const Expr &E);
bool checkOpenCLDisabledDecl(const NamedDecl &D, const Expr &E);
//===--------------------------------------------------------------------===//
// OpenMP directives and clauses.
@ -10276,6 +10288,7 @@ class Sema {
void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
void CheckBoolLikeConversion(Expr *E, SourceLocation CC);
void CheckForIntOverflow(Expr *E);
void CheckUnsequencedOperations(Expr *E);
/// \brief Perform semantic checks on a completed expression. This will either

View File

@ -400,7 +400,7 @@ class ASTReader
Preprocessor &PP;
/// \brief The AST context into which we'll read the AST files.
ASTContext &Context;
ASTContext *ContextObj = nullptr;
/// \brief The AST consumer.
ASTConsumer *Consumer = nullptr;
@ -1146,6 +1146,7 @@ class ASTReader
time_t StoredTime;
bool Overridden;
bool Transient;
bool TopLevelModuleMap;
};
/// \brief Reads the stored information about an input file.
@ -1386,7 +1387,7 @@ class ASTReader
/// precompiled header will be loaded.
///
/// \param Context the AST context that this precompiled header will be
/// loaded into.
/// loaded into, if any.
///
/// \param PCHContainerRdr the PCHContainerOperations to use for loading and
/// creating modules.
@ -1418,7 +1419,7 @@ class ASTReader
///
/// \param ReadTimer If non-null, a timer used to track the time spent
/// deserializing.
ASTReader(Preprocessor &PP, ASTContext &Context,
ASTReader(Preprocessor &PP, ASTContext *Context,
const PCHContainerReader &PCHContainerRdr,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
StringRef isysroot = "", bool DisableValidation = false,
@ -2207,7 +2208,10 @@ class ASTReader
void completeVisibleDeclsMap(const DeclContext *DC) override;
/// \brief Retrieve the AST context that this AST reader supplements.
ASTContext &getContext() { return Context; }
ASTContext &getContext() {
assert(ContextObj && "requested AST context when not loading AST");
return *ContextObj;
}
// \brief Contains the IDs for declarations that were requested before we have
// access to a Sema object.
@ -2249,6 +2253,12 @@ class ASTReader
llvm::function_ref<void(const serialization::InputFile &IF,
bool isSystem)> Visitor);
/// Visit all the top-level module maps loaded when building the given module
/// file.
void visitTopLevelModuleMaps(serialization::ModuleFile &MF,
llvm::function_ref<
void(const FileEntry *)> Visitor);
bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
};

View File

@ -38,6 +38,11 @@ def CoreAlpha : Package<"core">, InPackage<Alpha>, Hidden;
// default. Such checkers belong in the alpha package.
def OptIn : Package<"optin">;
// In the Portability package reside checkers for finding code that relies on
// implementation-defined behavior. Such checks are wanted for cross-platform
// development, but unwanted for developers who target only a single platform.
def PortabilityOptIn : Package<"portability">, InPackage<OptIn>;
def Nullability : Package<"nullability">;
def Cplusplus : Package<"cplusplus">;
@ -416,7 +421,7 @@ def GenericTaintChecker : Checker<"TaintPropagation">,
let ParentPackage = Unix in {
def UnixAPIChecker : Checker<"API">,
def UnixAPIMisuseChecker : Checker<"API">,
HelpText<"Check calls to various UNIX/Posix functions">,
DescFile<"UnixAPIChecker.cpp">;
@ -754,3 +759,14 @@ def CloneChecker : Checker<"CloneChecker">,
} // end "clone"
//===----------------------------------------------------------------------===//
// Portability checkers.
//===----------------------------------------------------------------------===//
let ParentPackage = PortabilityOptIn in {
def UnixAPIPortabilityChecker : Checker<"UnixAPI">,
HelpText<"Finds implementation-defined behavior in UNIX/Posix functions">,
DescFile<"UnixAPIChecker.cpp">;
} // end optin.portability

View File

@ -0,0 +1,70 @@
//===--- RenamingAction.h - Clang refactoring library ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides an action to rename every symbol at a point.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_RENAMING_ACTION_H
#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_RENAMING_ACTION_H
#include "clang/Tooling/Refactoring.h"
namespace clang {
class ASTConsumer;
class CompilerInstance;
namespace tooling {
class RenamingAction {
public:
RenamingAction(const std::vector<std::string> &NewNames,
const std::vector<std::string> &PrevNames,
const std::vector<std::vector<std::string>> &USRList,
std::map<std::string, tooling::Replacements> &FileToReplaces,
bool PrintLocations = false)
: NewNames(NewNames), PrevNames(PrevNames), USRList(USRList),
FileToReplaces(FileToReplaces), PrintLocations(PrintLocations) {}
std::unique_ptr<ASTConsumer> newASTConsumer();
private:
const std::vector<std::string> &NewNames, &PrevNames;
const std::vector<std::vector<std::string>> &USRList;
std::map<std::string, tooling::Replacements> &FileToReplaces;
bool PrintLocations;
};
/// Rename all symbols identified by the given USRs.
class QualifiedRenamingAction {
public:
QualifiedRenamingAction(
const std::vector<std::string> &NewNames,
const std::vector<std::vector<std::string>> &USRList,
std::map<std::string, tooling::Replacements> &FileToReplaces)
: NewNames(NewNames), USRList(USRList), FileToReplaces(FileToReplaces) {}
std::unique_ptr<ASTConsumer> newASTConsumer();
private:
/// New symbol names.
const std::vector<std::string> &NewNames;
/// A list of USRs. Each element represents USRs of a symbol being renamed.
const std::vector<std::vector<std::string>> &USRList;
/// A file path to replacements map.
std::map<std::string, tooling::Replacements> &FileToReplaces;
};
} // end namespace tooling
} // end namespace clang
#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_RENAMING_ACTION_H

View File

@ -0,0 +1,84 @@
//===--- USRFinder.h - Clang refactoring library --------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Methods for determining the USR of a symbol at a location in source
/// code.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_FINDER_H
#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_FINDER_H
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include <string>
#include <vector>
using namespace llvm;
using namespace clang::ast_matchers;
namespace clang {
class ASTContext;
class Decl;
class SourceLocation;
class NamedDecl;
namespace tooling {
// Given an AST context and a point, returns a NamedDecl identifying the symbol
// at the point. Returns null if nothing is found at the point.
const NamedDecl *getNamedDeclAt(const ASTContext &Context,
const SourceLocation Point);
// Given an AST context and a fully qualified name, returns a NamedDecl
// identifying the symbol with a matching name. Returns null if nothing is
// found for the name.
const NamedDecl *getNamedDeclFor(const ASTContext &Context,
const std::string &Name);
// Converts a Decl into a USR.
std::string getUSRForDecl(const Decl *Decl);
// FIXME: Implement RecursiveASTVisitor<T>::VisitNestedNameSpecifier instead.
class NestedNameSpecifierLocFinder : public MatchFinder::MatchCallback {
public:
explicit NestedNameSpecifierLocFinder(ASTContext &Context)
: Context(Context) {}
std::vector<NestedNameSpecifierLoc> getNestedNameSpecifierLocations() {
addMatchers();
Finder.matchAST(Context);
return Locations;
}
private:
void addMatchers() {
const auto NestedNameSpecifierLocMatcher =
nestedNameSpecifierLoc().bind("nestedNameSpecifierLoc");
Finder.addMatcher(NestedNameSpecifierLocMatcher, this);
}
void run(const MatchFinder::MatchResult &Result) override {
const auto *NNS = Result.Nodes.getNodeAs<NestedNameSpecifierLoc>(
"nestedNameSpecifierLoc");
Locations.push_back(*NNS);
}
ASTContext &Context;
std::vector<NestedNameSpecifierLoc> Locations;
MatchFinder Finder;
};
} // end namespace tooling
} // end namespace clang
#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_FINDER_H

View File

@ -0,0 +1,54 @@
//===--- USRFindingAction.h - Clang refactoring library -------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides an action to find all relevant USRs at a point.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_FINDING_ACTION_H
#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_FINDING_ACTION_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include <string>
#include <vector>
namespace clang {
class ASTConsumer;
class CompilerInstance;
class NamedDecl;
namespace tooling {
struct USRFindingAction {
USRFindingAction(ArrayRef<unsigned> SymbolOffsets,
ArrayRef<std::string> QualifiedNames, bool Force)
: SymbolOffsets(SymbolOffsets), QualifiedNames(QualifiedNames),
ErrorOccurred(false), Force(Force) {}
std::unique_ptr<ASTConsumer> newASTConsumer();
ArrayRef<std::string> getUSRSpellings() { return SpellingNames; }
ArrayRef<std::vector<std::string>> getUSRList() { return USRList; }
bool errorOccurred() { return ErrorOccurred; }
private:
std::vector<unsigned> SymbolOffsets;
std::vector<std::string> QualifiedNames;
std::vector<std::string> SpellingNames;
std::vector<std::vector<std::string>> USRList;
bool ErrorOccurred;
bool Force;
};
} // end namespace tooling
} // end namespace clang
#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_FINDING_ACTION_H

View File

@ -0,0 +1,49 @@
//===--- USRLocFinder.h - Clang refactoring library -----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides functionality for finding all instances of a USR in a given
/// AST.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_LOC_FINDER_H
#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_LOC_FINDER_H
#include "clang/AST/AST.h"
#include "clang/Tooling/Core/Replacement.h"
#include "clang/Tooling/Refactoring/AtomicChange.h"
#include "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
namespace clang {
namespace tooling {
/// Create atomic changes for renaming all symbol references which are
/// identified by the USRs set to a given new name.
///
/// \param USRs The set containing USRs of a particular old symbol.
/// \param NewName The new name to replace old symbol name.
/// \param TranslationUnitDecl The translation unit declaration.
///
/// \return Atomic changes for renaming.
std::vector<tooling::AtomicChange>
createRenameAtomicChanges(llvm::ArrayRef<std::string> USRs,
llvm::StringRef NewName, Decl *TranslationUnitDecl);
// FIXME: make this an AST matcher. Wouldn't that be awesome??? I agree!
std::vector<SourceLocation>
getLocationsOfUSRs(const std::vector<std::string> &USRs,
llvm::StringRef PrevName, Decl *Decl);
} // end namespace tooling
} // end namespace clang
#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_USR_LOC_FINDER_H

View File

@ -33,6 +33,7 @@ module Clang_Basic {
textual header "Basic/BuiltinsLe64.def"
textual header "Basic/BuiltinsMips.def"
textual header "Basic/BuiltinsNEON.def"
textual header "Basic/BuiltinsNios2.def"
textual header "Basic/BuiltinsNVPTX.def"
textual header "Basic/BuiltinsPPC.def"
textual header "Basic/BuiltinsSystemZ.def"
@ -132,9 +133,10 @@ module Clang_StaticAnalyzer_Frontend {
module Clang_Tooling {
requires cplusplus umbrella "Tooling" module * { export * }
// FIXME: Exclude this header to avoid pulling all of the AST matchers
// FIXME: Exclude these headers to avoid pulling all of the AST matchers
// library into clang-format. Due to inline key functions in the headers,
// importing the AST matchers library gives a link dependency on the AST
// matchers (and thus the AST), which clang-format should not have.
exclude header "Tooling/RefactoringCallbacks.h"
exclude header "Tooling/Refactoring/Rename/USRFinder.h"
}

View File

@ -5990,9 +5990,19 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S,
// compatibility with GCC, although providing it breaks anything that
// actually uses runtime introspection and wants to work on both runtimes...
if (Ctx->getLangOpts().ObjCRuntime.isGNUFamily()) {
const RecordDecl *RD = FD->getParent();
const ASTRecordLayout &RL = Ctx->getASTRecordLayout(RD);
S += llvm::utostr(RL.getFieldOffset(FD->getFieldIndex()));
uint64_t Offset;
if (const auto *IVD = dyn_cast<ObjCIvarDecl>(FD)) {
Offset = Ctx->lookupFieldBitOffset(IVD->getContainingInterface(), nullptr,
IVD);
} else {
const RecordDecl *RD = FD->getParent();
const ASTRecordLayout &RL = Ctx->getASTRecordLayout(RD);
Offset = RL.getFieldOffset(FD->getFieldIndex());
}
S += llvm::utostr(Offset);
if (const EnumType *ET = T->getAs<EnumType>())
S += ObjCEncodingForEnumType(Ctx, ET);
else {

View File

@ -735,13 +735,28 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
// Check for equivalent field names.
IdentifierInfo *Name1 = Field1->getIdentifier();
IdentifierInfo *Name2 = Field2->getIdentifier();
if (!::IsStructurallyEquivalent(Name1, Name2))
if (!::IsStructurallyEquivalent(Name1, Name2)) {
if (Context.Complain) {
Context.Diag2(Owner2->getLocation(),
Context.ErrorOnTagTypeMismatch
? diag::err_odr_tag_type_inconsistent
: diag::warn_odr_tag_type_inconsistent)
<< Context.ToCtx.getTypeDeclType(Owner2);
Context.Diag2(Field2->getLocation(), diag::note_odr_field_name)
<< Field2->getDeclName();
Context.Diag1(Field1->getLocation(), diag::note_odr_field_name)
<< Field1->getDeclName();
}
return false;
}
if (!IsStructurallyEquivalent(Context, Field1->getType(),
Field2->getType())) {
if (Context.Complain) {
Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
Context.Diag2(Owner2->getLocation(),
Context.ErrorOnTagTypeMismatch
? diag::err_odr_tag_type_inconsistent
: diag::warn_odr_tag_type_inconsistent)
<< Context.ToCtx.getTypeDeclType(Owner2);
Context.Diag2(Field2->getLocation(), diag::note_odr_field)
<< Field2->getDeclName() << Field2->getType();
@ -753,7 +768,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Field1->isBitField() != Field2->isBitField()) {
if (Context.Complain) {
Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
Context.Diag2(Owner2->getLocation(),
Context.ErrorOnTagTypeMismatch
? diag::err_odr_tag_type_inconsistent
: diag::warn_odr_tag_type_inconsistent)
<< Context.ToCtx.getTypeDeclType(Owner2);
if (Field1->isBitField()) {
Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
@ -780,7 +798,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Bits1 != Bits2) {
if (Context.Complain) {
Context.Diag2(Owner2->getLocation(),
diag::warn_odr_tag_type_inconsistent)
Context.ErrorOnTagTypeMismatch
? diag::err_odr_tag_type_inconsistent
: diag::warn_odr_tag_type_inconsistent)
<< Context.ToCtx.getTypeDeclType(Owner2);
Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
<< Field2->getDeclName() << Field2->getType() << Bits2;
@ -799,7 +819,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
RecordDecl *D1, RecordDecl *D2) {
if (D1->isUnion() != D2->isUnion()) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
Context.Diag2(D2->getLocation(),
Context.ErrorOnTagTypeMismatch
? diag::err_odr_tag_type_inconsistent
: diag::warn_odr_tag_type_inconsistent)
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
<< D1->getDeclName() << (unsigned)D1->getTagKind();
@ -927,7 +950,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Field1 != Field1End; ++Field1, ++Field2) {
if (Field2 == Field2End) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
Context.Diag2(D2->getLocation(),
Context.ErrorOnTagTypeMismatch
? diag::err_odr_tag_type_inconsistent
: diag::warn_odr_tag_type_inconsistent)
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag1(Field1->getLocation(), diag::note_odr_field)
<< Field1->getDeclName() << Field1->getType();
@ -942,7 +968,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Field2 != Field2End) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
Context.Diag2(D2->getLocation(),
Context.ErrorOnTagTypeMismatch
? diag::err_odr_tag_type_inconsistent
: diag::warn_odr_tag_type_inconsistent)
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(Field2->getLocation(), diag::note_odr_field)
<< Field2->getDeclName() << Field2->getType();
@ -964,7 +993,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
EC1 != EC1End; ++EC1, ++EC2) {
if (EC2 == EC2End) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
Context.Diag2(D2->getLocation(),
Context.ErrorOnTagTypeMismatch
? diag::err_odr_tag_type_inconsistent
: diag::warn_odr_tag_type_inconsistent)
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
<< EC1->getDeclName() << EC1->getInitVal().toString(10);
@ -978,7 +1010,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!llvm::APSInt::isSameValue(Val1, Val2) ||
!IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
Context.Diag2(D2->getLocation(),
Context.ErrorOnTagTypeMismatch
? diag::err_odr_tag_type_inconsistent
: diag::warn_odr_tag_type_inconsistent)
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
<< EC2->getDeclName() << EC2->getInitVal().toString(10);
@ -991,7 +1026,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (EC2 != EC2End) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
Context.Diag2(D2->getLocation(),
Context.ErrorOnTagTypeMismatch
? diag::err_odr_tag_type_inconsistent
: diag::warn_odr_tag_type_inconsistent)
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
<< EC2->getDeclName() << EC2->getInitVal().toString(10);

View File

@ -1251,7 +1251,9 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D,
case Decl::EnumConstant:
// C++ [basic.link]p4: an enumerator has the linkage of its enumeration.
return getLVForDecl(cast<EnumDecl>(D->getDeclContext()), computation);
if (D->getASTContext().getLangOpts().CPlusPlus)
return getLVForDecl(cast<EnumDecl>(D->getDeclContext()), computation);
return LinkageInfo::visible_none();
case Decl::Typedef:
case Decl::TypeAlias:
@ -2630,7 +2632,7 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const {
return (proto->getParamType(1).getCanonicalType() == Context.VoidPtrTy);
}
bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
bool FunctionDecl::isReplaceableGlobalAllocationFunction(bool *IsAligned) const {
if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName)
return false;
if (getDeclName().getCXXOverloadedOperator() != OO_New &&
@ -2676,8 +2678,11 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
// In C++17, the next parameter can be a 'std::align_val_t' for aligned
// new/delete.
if (Ctx.getLangOpts().AlignedAllocation && !Ty.isNull() && Ty->isAlignValT())
if (Ctx.getLangOpts().AlignedAllocation && !Ty.isNull() && Ty->isAlignValT()) {
if (IsAligned)
*IsAligned = true;
Consume();
}
// Finally, if this is not a sized delete, the final parameter can
// be a 'const std::nothrow_t&'.

View File

@ -1417,11 +1417,8 @@ CXXDestructorDecl *CXXRecordDecl::getDestructor() const {
Context.getCanonicalType(ClassType));
DeclContext::lookup_result R = lookup(Name);
if (R.empty())
return nullptr;
CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(R.front());
return Dtor;
return R.empty() ? nullptr : dyn_cast<CXXDestructorDecl>(R.front());
}
bool CXXRecordDecl::isAnyDestructorNoReturn() const {

View File

@ -1641,25 +1641,32 @@ const char *CastExpr::getCastKindName() const {
llvm_unreachable("Unhandled cast kind!");
}
namespace {
Expr *skipImplicitTemporary(Expr *expr) {
// Skip through reference binding to temporary.
if (MaterializeTemporaryExpr *Materialize
= dyn_cast<MaterializeTemporaryExpr>(expr))
expr = Materialize->GetTemporaryExpr();
// Skip any temporary bindings; they're implicit.
if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(expr))
expr = Binder->getSubExpr();
return expr;
}
}
Expr *CastExpr::getSubExprAsWritten() {
Expr *SubExpr = nullptr;
CastExpr *E = this;
do {
SubExpr = E->getSubExpr();
SubExpr = skipImplicitTemporary(E->getSubExpr());
// Skip through reference binding to temporary.
if (MaterializeTemporaryExpr *Materialize
= dyn_cast<MaterializeTemporaryExpr>(SubExpr))
SubExpr = Materialize->GetTemporaryExpr();
// Skip any temporary bindings; they're implicit.
if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(SubExpr))
SubExpr = Binder->getSubExpr();
// Conversions by constructor and conversion functions have a
// subexpression describing the call; strip it off.
if (E->getCastKind() == CK_ConstructorConversion)
SubExpr = cast<CXXConstructExpr>(SubExpr)->getArg(0);
SubExpr =
skipImplicitTemporary(cast<CXXConstructExpr>(SubExpr)->getArg(0));
else if (E->getCastKind() == CK_UserDefinedConversion) {
assert((isa<CXXMemberCallExpr>(SubExpr) ||
isa<BlockExpr>(SubExpr)) &&

View File

@ -6226,10 +6226,6 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
// the initializer list.
ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy : Field->getType());
const Expr *Init = HaveInit ? E->getInit(ElementNo++) : &VIE;
if (Init->isValueDependent()) {
Success = false;
continue;
}
// Temporarily override This, in case there's a CXXDefaultInitExpr in here.
ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
@ -9940,8 +9936,7 @@ static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) {
}
static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
const ASTContext &Ctx, bool &IsConst,
bool IsCheckingForOverflow) {
const ASTContext &Ctx, bool &IsConst) {
// Fast-path evaluations of integer literals, since we sometimes see files
// containing vast quantities of these.
if (const IntegerLiteral *L = dyn_cast<IntegerLiteral>(Exp)) {
@ -9962,7 +9957,7 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
// performance problems. Only do so in C++11 for now.
if (Exp->isRValue() && (Exp->getType()->isArrayType() ||
Exp->getType()->isRecordType()) &&
!Ctx.getLangOpts().CPlusPlus11 && !IsCheckingForOverflow) {
!Ctx.getLangOpts().CPlusPlus11) {
IsConst = false;
return true;
}
@ -9977,7 +9972,7 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
/// will be applied to the result.
bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const {
bool IsConst;
if (FastEvaluateAsRValue(this, Result, Ctx, IsConst, false))
if (FastEvaluateAsRValue(this, Result, Ctx, IsConst))
return IsConst;
EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
@ -10102,7 +10097,7 @@ APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx,
void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
bool IsConst;
EvalResult EvalResult;
if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst, true)) {
if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst)) {
EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow);
(void)::EvaluateAsRValue(Info, this, EvalResult.Val);
}

View File

@ -966,16 +966,71 @@ void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) {
}
if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID =
Diags.getCustomDiagID(DiagnosticsEngine::Error,
"cannot mangle a local inside this block yet");
Diags.Report(BD->getLocation(), DiagID);
auto Discriminate =
[](StringRef Name, const unsigned Discriminator,
const unsigned ParameterDiscriminator) -> std::string {
std::string Buffer;
llvm::raw_string_ostream Stream(Buffer);
Stream << Name;
if (Discriminator)
Stream << '_' << Discriminator;
if (ParameterDiscriminator)
Stream << '_' << ParameterDiscriminator;
return Stream.str();
};
// FIXME: This is completely, utterly, wrong; see ItaniumMangle
// for how this should be done.
Out << "__block_invoke" << Context.getBlockId(BD, false);
Out << '@';
unsigned Discriminator = BD->getBlockManglingNumber();
if (!Discriminator)
Discriminator = Context.getBlockId(BD, /*Local=*/false);
// Mangle the parameter position as a discriminator to deal with unnamed
// parameters. Rather than mangling the unqualified parameter name,
// always use the position to give a uniform mangling.
unsigned ParameterDiscriminator = 0;
if (const auto *MC = BD->getBlockManglingContextDecl())
if (const auto *P = dyn_cast<ParmVarDecl>(MC))
if (const auto *F = dyn_cast<FunctionDecl>(P->getDeclContext()))
ParameterDiscriminator =
F->getNumParams() - P->getFunctionScopeIndex();
DC = getEffectiveDeclContext(BD);
Out << '?';
mangleSourceName(Discriminate("_block_invoke", Discriminator,
ParameterDiscriminator));
// If we have a block mangling context, encode that now. This allows us
// to discriminate between named static data initializers in the same
// scope. This is handled differently from parameters, which use
// positions to discriminate between multiple instances.
if (const auto *MC = BD->getBlockManglingContextDecl())
if (!isa<ParmVarDecl>(MC))
if (const auto *ND = dyn_cast<NamedDecl>(MC))
mangleUnqualifiedName(ND);
// MS ABI and Itanium manglings are in inverted scopes. In the case of a
// RecordDecl, mangle the entire scope hierachy at this point rather than
// just the unqualified name to get the ordering correct.
if (const auto *RD = dyn_cast<RecordDecl>(DC))
mangleName(RD);
else
Out << '@';
// void __cdecl
Out << "YAX";
// struct __block_literal *
Out << 'P';
// __ptr64
if (PointersAre64Bit)
Out << 'E';
Out << 'A';
mangleArtificalTagType(TTK_Struct,
Discriminate("__block_literal", Discriminator,
ParameterDiscriminator));
Out << "@Z";
// If the effective context was a Record, we have fully mangled the
// qualified name and do not need to continue.
if (isa<RecordDecl>(DC))
break;
continue;
} else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
mangleObjCMethodName(Method);
} else if (isa<NamedDecl>(DC)) {

View File

@ -82,25 +82,13 @@ void ODRHash::AddDeclarationName(DeclarationName Name) {
}
void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
// Unlike the other pointer handling functions, allow null pointers here.
if (!NNS) {
AddBoolean(false);
return;
assert(NNS && "Expecting non-null pointer.");
const auto *Prefix = NNS->getPrefix();
AddBoolean(Prefix);
if (Prefix) {
AddNestedNameSpecifier(Prefix);
}
// Skip inlined namespaces.
auto Kind = NNS->getKind();
if (Kind == NestedNameSpecifier::Namespace) {
if (NNS->getAsNamespace()->isInline()) {
return AddNestedNameSpecifier(NNS->getPrefix());
}
}
AddBoolean(true);
// Process prefix
AddNestedNameSpecifier(NNS->getPrefix());
ID.AddInteger(Kind);
switch (Kind) {
case NestedNameSpecifier::Identifier:
@ -146,7 +134,10 @@ void ODRHash::AddTemplateArgument(TemplateArgument TA) {
switch (Kind) {
case TemplateArgument::Null:
llvm_unreachable("Expected valid TemplateArgument");
case TemplateArgument::Type:
AddQualType(TA.getAsType());
break;
case TemplateArgument::Declaration:
case TemplateArgument::NullPtr:
case TemplateArgument::Integral:
@ -430,8 +421,18 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
Hash.AddQualType(T);
}
void AddType(const Type *T) {
Hash.AddBoolean(T);
if (T) {
Hash.AddType(T);
}
}
void AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
Hash.AddNestedNameSpecifier(NNS);
Hash.AddBoolean(NNS);
if (NNS) {
Hash.AddNestedNameSpecifier(NNS);
}
}
void AddIdentifierInfo(const IdentifierInfo *II) {
@ -517,7 +518,13 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
void VisitTypedefType(const TypedefType *T) {
AddDecl(T->getDecl());
AddQualType(T->getDecl()->getUnderlyingType().getCanonicalType());
QualType UnderlyingType = T->getDecl()->getUnderlyingType();
VisitQualifiers(UnderlyingType.getQualifiers());
while (const TypedefType *Underlying =
dyn_cast<TypedefType>(UnderlyingType.getTypePtr())) {
UnderlyingType = Underlying->getDecl()->getUnderlyingType();
}
AddType(UnderlyingType.getTypePtr());
VisitType(T);
}

View File

@ -3073,6 +3073,41 @@ uint64_t ASTContext::getFieldOffset(const ValueDecl *VD) const {
return OffsetInBits;
}
uint64_t ASTContext::lookupFieldBitOffset(const ObjCInterfaceDecl *OID,
const ObjCImplementationDecl *ID,
const ObjCIvarDecl *Ivar) const {
const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
// FIXME: We should eliminate the need to have ObjCImplementationDecl passed
// in here; it should never be necessary because that should be the lexical
// decl context for the ivar.
// If we know have an implementation (and the ivar is in it) then
// look up in the implementation layout.
const ASTRecordLayout *RL;
if (ID && declaresSameEntity(ID->getClassInterface(), Container))
RL = &getASTObjCImplementationLayout(ID);
else
RL = &getASTObjCInterfaceLayout(Container);
// Compute field index.
//
// FIXME: The index here is closely tied to how ASTContext::getObjCLayout is
// implemented. This should be fixed to get the information from the layout
// directly.
unsigned Index = 0;
for (const ObjCIvarDecl *IVD = Container->all_declared_ivar_begin();
IVD; IVD = IVD->getNextIvar()) {
if (Ivar == IVD)
break;
++Index;
}
assert(Index < RL->getFieldCount() && "Ivar is not inside record layout!");
return RL->getFieldOffset(Index);
}
/// getObjCLayout - Get or compute information about the layout of the
/// given interface.
///

View File

@ -186,7 +186,10 @@ namespace {
Hash.AddTemplateName(Name);
}
void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) override {
Hash.AddNestedNameSpecifier(NNS);
ID.AddBoolean(NNS);
if (NNS) {
Hash.AddNestedNameSpecifier(NNS);
}
}
};
}

View File

@ -92,6 +92,76 @@ FullSourceLoc FullSourceLoc::getSpellingLoc() const {
return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr);
}
FullSourceLoc FullSourceLoc::getFileLoc() const {
assert(isValid());
return FullSourceLoc(SrcMgr->getFileLoc(*this), *SrcMgr);
}
std::pair<FullSourceLoc, FullSourceLoc>
FullSourceLoc::getImmediateExpansionRange() const {
assert(isValid());
std::pair<SourceLocation, SourceLocation> Range =
SrcMgr->getImmediateExpansionRange(*this);
return std::make_pair(FullSourceLoc(Range.first, *SrcMgr),
FullSourceLoc(Range.second, *SrcMgr));
}
PresumedLoc FullSourceLoc::getPresumedLoc(bool UseLineDirectives) const {
if (!isValid())
return PresumedLoc();
return SrcMgr->getPresumedLoc(*this, UseLineDirectives);
}
bool FullSourceLoc::isMacroArgExpansion(FullSourceLoc *StartLoc) const {
assert(isValid());
return SrcMgr->isMacroArgExpansion(*this, StartLoc);
}
FullSourceLoc FullSourceLoc::getImmediateMacroCallerLoc() const {
assert(isValid());
return FullSourceLoc(SrcMgr->getImmediateMacroCallerLoc(*this), *SrcMgr);
}
std::pair<FullSourceLoc, StringRef> FullSourceLoc::getModuleImportLoc() const {
if (!isValid())
return std::make_pair(FullSourceLoc(), StringRef());
std::pair<SourceLocation, StringRef> ImportLoc =
SrcMgr->getModuleImportLoc(*this);
return std::make_pair(FullSourceLoc(ImportLoc.first, *SrcMgr),
ImportLoc.second);
}
unsigned FullSourceLoc::getFileOffset() const {
assert(isValid());
return SrcMgr->getFileOffset(*this);
}
unsigned FullSourceLoc::getLineNumber(bool *Invalid) const {
assert(isValid());
return SrcMgr->getLineNumber(getFileID(), getFileOffset(), Invalid);
}
unsigned FullSourceLoc::getColumnNumber(bool *Invalid) const {
assert(isValid());
return SrcMgr->getColumnNumber(getFileID(), getFileOffset(), Invalid);
}
std::pair<FullSourceLoc, FullSourceLoc>
FullSourceLoc::getExpansionRange() const {
assert(isValid());
std::pair<SourceLocation, SourceLocation> Range =
SrcMgr->getExpansionRange(*this);
return std::make_pair(FullSourceLoc(Range.first, *SrcMgr),
FullSourceLoc(Range.second, *SrcMgr));
}
const FileEntry *FullSourceLoc::getFileEntry() const {
assert(isValid());
return SrcMgr->getFileEntryForID(getFileID());
}
unsigned FullSourceLoc::getExpansionLineNumber(bool *Invalid) const {
assert(isValid());
return SrcMgr->getExpansionLineNumber(*this, Invalid);

View File

@ -2018,56 +2018,13 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
if (LOffs.first.isInvalid() || ROffs.first.isInvalid())
return LOffs.first.isInvalid() && !ROffs.first.isInvalid();
// If the source locations are in the same file, just compare offsets.
if (LOffs.first == ROffs.first)
return LOffs.second < ROffs.second;
// If we are comparing a source location with multiple locations in the same
// file, we get a big win by caching the result.
InBeforeInTUCacheEntry &IsBeforeInTUCache =
getInBeforeInTUCache(LOffs.first, ROffs.first);
// If we are comparing a source location with multiple locations in the same
// file, we get a big win by caching the result.
if (IsBeforeInTUCache.isCacheValid(LOffs.first, ROffs.first))
return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second);
// Okay, we missed in the cache, start updating the cache for this query.
IsBeforeInTUCache.setQueryFIDs(LOffs.first, ROffs.first,
/*isLFIDBeforeRFID=*/LOffs.first.ID < ROffs.first.ID);
// We need to find the common ancestor. The only way of doing this is to
// build the complete include chain for one and then walking up the chain
// of the other looking for a match.
// We use a map from FileID to Offset to store the chain. Easier than writing
// a custom set hash info that only depends on the first part of a pair.
typedef llvm::SmallDenseMap<FileID, unsigned, 16> LocSet;
LocSet LChain;
do {
LChain.insert(LOffs);
// We catch the case where LOffs is in a file included by ROffs and
// quit early. The other way round unfortunately remains suboptimal.
} while (LOffs.first != ROffs.first && !MoveUpIncludeHierarchy(LOffs, *this));
LocSet::iterator I;
while((I = LChain.find(ROffs.first)) == LChain.end()) {
if (MoveUpIncludeHierarchy(ROffs, *this))
break; // Met at topmost file.
}
if (I != LChain.end())
LOffs = *I;
// If we exited because we found a nearest common ancestor, compare the
// locations within the common file and cache them.
if (LOffs.first == ROffs.first) {
IsBeforeInTUCache.setCommonLoc(LOffs.first, LOffs.second, ROffs.second);
return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second);
}
std::pair<bool, bool> InSameTU = isInTheSameTranslationUnit(LOffs, ROffs);
if (InSameTU.first)
return InSameTU.second;
// If we arrived here, the location is either in a built-ins buffer or
// associated with global inline asm. PR5662 and PR22576 are examples.
// Clear the lookup cache, it depends on a common location.
IsBeforeInTUCache.clear();
StringRef LB = getBuffer(LOffs.first)->getBufferIdentifier();
StringRef RB = getBuffer(ROffs.first)->getBufferIdentifier();
bool LIsBuiltins = LB == "<built-in>";
@ -2100,6 +2057,60 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
llvm_unreachable("Unsortable locations found");
}
std::pair<bool, bool> SourceManager::isInTheSameTranslationUnit(
std::pair<FileID, unsigned> &LOffs,
std::pair<FileID, unsigned> &ROffs) const {
// If the source locations are in the same file, just compare offsets.
if (LOffs.first == ROffs.first)
return std::make_pair(true, LOffs.second < ROffs.second);
// If we are comparing a source location with multiple locations in the same
// file, we get a big win by caching the result.
InBeforeInTUCacheEntry &IsBeforeInTUCache =
getInBeforeInTUCache(LOffs.first, ROffs.first);
// If we are comparing a source location with multiple locations in the same
// file, we get a big win by caching the result.
if (IsBeforeInTUCache.isCacheValid(LOffs.first, ROffs.first))
return std::make_pair(
true, IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second));
// Okay, we missed in the cache, start updating the cache for this query.
IsBeforeInTUCache.setQueryFIDs(LOffs.first, ROffs.first,
/*isLFIDBeforeRFID=*/LOffs.first.ID < ROffs.first.ID);
// We need to find the common ancestor. The only way of doing this is to
// build the complete include chain for one and then walking up the chain
// of the other looking for a match.
// We use a map from FileID to Offset to store the chain. Easier than writing
// a custom set hash info that only depends on the first part of a pair.
typedef llvm::SmallDenseMap<FileID, unsigned, 16> LocSet;
LocSet LChain;
do {
LChain.insert(LOffs);
// We catch the case where LOffs is in a file included by ROffs and
// quit early. The other way round unfortunately remains suboptimal.
} while (LOffs.first != ROffs.first && !MoveUpIncludeHierarchy(LOffs, *this));
LocSet::iterator I;
while((I = LChain.find(ROffs.first)) == LChain.end()) {
if (MoveUpIncludeHierarchy(ROffs, *this))
break; // Met at topmost file.
}
if (I != LChain.end())
LOffs = *I;
// If we exited because we found a nearest common ancestor, compare the
// locations within the common file and cache them.
if (LOffs.first == ROffs.first) {
IsBeforeInTUCache.setCommonLoc(LOffs.first, LOffs.second, ROffs.second);
return std::make_pair(
true, IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second));
}
// Clear the lookup cache, it depends on a common location.
IsBeforeInTUCache.clear();
return std::make_pair(false, false);
}
void SourceManager::PrintStats() const {
llvm::errs() << "\n*** Source Manager Stats:\n";
llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size()

View File

@ -2706,7 +2706,7 @@ class X86TargetInfo : public TargetInfo {
CK_C3_2,
/// This enumerator is a bit odd, as GCC no longer accepts -march=yonah.
/// Clang however has some logic to suport this.
/// Clang however has some logic to support this.
// FIXME: Warn, deprecate, and potentially remove this.
CK_Yonah,
//@}
@ -2737,6 +2737,7 @@ class X86TargetInfo : public TargetInfo {
//@{
CK_Bonnell,
CK_Silvermont,
CK_Goldmont,
//@}
/// \name Nehalem
@ -2878,6 +2879,7 @@ class X86TargetInfo : public TargetInfo {
.Case("atom", CK_Bonnell) // Legacy name.
.Case("silvermont", CK_Silvermont)
.Case("slm", CK_Silvermont) // Legacy name.
.Case("goldmont", CK_Goldmont)
.Case("nehalem", CK_Nehalem)
.Case("corei7", CK_Nehalem) // Legacy name.
.Case("westmere", CK_Westmere)
@ -3093,6 +3095,7 @@ class X86TargetInfo : public TargetInfo {
case CK_Penryn:
case CK_Bonnell:
case CK_Silvermont:
case CK_Goldmont:
case CK_Nehalem:
case CK_Westmere:
case CK_SandyBridge:
@ -3221,7 +3224,6 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_Core2:
case CK_Bonnell:
setFeatureEnabledImpl(Features, "ssse3", true);
setFeatureEnabledImpl(Features, "fxsr", true);
setFeatureEnabledImpl(Features, "cx16", true);
@ -3276,7 +3278,6 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "xsaveopt", true);
LLVM_FALLTHROUGH;
case CK_Westmere:
case CK_Silvermont:
setFeatureEnabledImpl(Features, "aes", true);
setFeatureEnabledImpl(Features, "pclmul", true);
LLVM_FALLTHROUGH;
@ -3285,6 +3286,28 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "fxsr", true);
setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_Goldmont:
setFeatureEnabledImpl(Features, "sha", true);
setFeatureEnabledImpl(Features, "rdrnd", true);
setFeatureEnabledImpl(Features, "rdseed", true);
setFeatureEnabledImpl(Features, "xsave", true);
setFeatureEnabledImpl(Features, "xsaveopt", true);
setFeatureEnabledImpl(Features, "xsavec", true);
setFeatureEnabledImpl(Features, "xsaves", true);
setFeatureEnabledImpl(Features, "clflushopt", true);
setFeatureEnabledImpl(Features, "mpx", true);
LLVM_FALLTHROUGH;
case CK_Silvermont:
setFeatureEnabledImpl(Features, "aes", true);
setFeatureEnabledImpl(Features, "pclmul", true);
setFeatureEnabledImpl(Features, "sse4.2", true);
LLVM_FALLTHROUGH;
case CK_Bonnell:
setFeatureEnabledImpl(Features, "movbe", true);
setFeatureEnabledImpl(Features, "ssse3", true);
setFeatureEnabledImpl(Features, "fxsr", true);
setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_KNL:
setFeatureEnabledImpl(Features, "avx512f", true);
setFeatureEnabledImpl(Features, "avx512cd", true);
@ -3524,6 +3547,7 @@ void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features,
Features["avx512pf"] = Features["avx512dq"] = Features["avx512bw"] =
Features["avx512vl"] = Features["avx512vbmi"] =
Features["avx512ifma"] = Features["avx512vpopcntdq"] = false;
break;
}
}
@ -3556,6 +3580,7 @@ void X86TargetInfo::setMMXLevel(llvm::StringMap<bool> &Features,
LLVM_FALLTHROUGH;
case AMD3DNowAthlon:
Features["3dnowa"] = false;
break;
}
}
@ -3590,6 +3615,7 @@ void X86TargetInfo::setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
LLVM_FALLTHROUGH;
case XOP:
Features["xop"] = false;
break;
}
}
@ -3893,6 +3919,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_Silvermont:
defineCPUMacros(Builder, "slm");
break;
case CK_Goldmont:
defineCPUMacros(Builder, "goldmont");
break;
case CK_Nehalem:
case CK_Westmere:
case CK_SandyBridge:
@ -4156,6 +4185,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
break;
default:
Builder.defineMacro("_M_IX86_FP", Twine(0));
break;
}
}
@ -5413,7 +5443,7 @@ class ARMTargetInfo : public TargetInfo {
if (Triple.getOS() == llvm::Triple::Linux ||
Triple.getOS() == llvm::Triple::UnknownOS)
this->MCountName =
Opts.EABIVersion == "gnu" ? "\01__gnu_mcount_nc" : "\01mcount";
Opts.EABIVersion == llvm::EABI::GNU ? "\01__gnu_mcount_nc" : "\01mcount";
}
StringRef getABI() const override { return ABI; }
@ -5594,6 +5624,17 @@ class ARMTargetInfo : public TargetInfo {
bool setFPMath(StringRef Name) override;
void getTargetDefinesARMV81A(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
}
void getTargetDefinesARMV82A(const LangOptions &Opts,
MacroBuilder &Builder) const {
// Also include the ARMv8.1-A defines
getTargetDefinesARMV81A(Opts, Builder);
}
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
// Target identification.
@ -5792,8 +5833,15 @@ class ARMTargetInfo : public TargetInfo {
if (Opts.UnsafeFPMath)
Builder.defineMacro("__ARM_FP_FAST", "1");
if (ArchKind == llvm::ARM::AK_ARMV8_1A)
Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
switch(ArchKind) {
default: break;
case llvm::ARM::AK_ARMV8_1A:
getTargetDefinesARMV81A(Opts, Builder);
break;
case llvm::ARM::AK_ARMV8_2A:
getTargetDefinesARMV82A(Opts, Builder);
break;
}
}
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
@ -6186,9 +6234,8 @@ class AArch64TargetInfo : public TargetInfo {
unsigned CRC;
unsigned Crypto;
unsigned Unaligned;
unsigned V8_1A;
unsigned V8_2A;
unsigned HasFullFP16;
llvm::AArch64::ArchKind ArchKind;
static const Builtin::Info BuiltinInfo[];
@ -6236,7 +6283,7 @@ class AArch64TargetInfo : public TargetInfo {
if (Triple.getOS() == llvm::Triple::Linux)
this->MCountName = "\01_mcount";
else if (Triple.getOS() == llvm::Triple::UnknownOS)
this->MCountName = Opts.EABIVersion == "gnu" ? "\01_mcount" : "mcount";
this->MCountName = Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
}
StringRef getABI() const override { return ABI; }
@ -6254,6 +6301,20 @@ class AArch64TargetInfo : public TargetInfo {
static_cast<unsigned>(llvm::AArch64::ArchKind::AK_INVALID);
}
void getTargetDefinesARMV81A(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
}
void getTargetDefinesARMV82A(const LangOptions &Opts,
MacroBuilder &Builder) const {
// Also include the ARMv8.1 defines
getTargetDefinesARMV81A(Opts, Builder);
if (FPU == NeonMode && HasFullFP16)
Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
}
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
// Target identification.
@ -6318,10 +6379,15 @@ class AArch64TargetInfo : public TargetInfo {
if (Unaligned)
Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
if (V8_1A)
Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
if (V8_2A && FPU == NeonMode && HasFullFP16)
Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
switch(ArchKind) {
default: break;
case llvm::AArch64::ArchKind::AK_ARMV8_1A:
getTargetDefinesARMV81A(Opts, Builder);
break;
case llvm::AArch64::ArchKind::AK_ARMV8_2A:
getTargetDefinesARMV82A(Opts, Builder);
break;
}
// All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
@ -6348,9 +6414,8 @@ class AArch64TargetInfo : public TargetInfo {
CRC = 0;
Crypto = 0;
Unaligned = 1;
V8_1A = 0;
V8_2A = 0;
HasFullFP16 = 0;
ArchKind = llvm::AArch64::ArchKind::AK_ARMV8A;
for (const auto &Feature : Features) {
if (Feature == "+neon")
@ -6362,9 +6427,9 @@ class AArch64TargetInfo : public TargetInfo {
if (Feature == "+strict-align")
Unaligned = 0;
if (Feature == "+v8.1a")
V8_1A = 1;
ArchKind = llvm::AArch64::ArchKind::AK_ARMV8_1A;
if (Feature == "+v8.2a")
V8_2A = 1;
ArchKind = llvm::AArch64::ArchKind::AK_ARMV8_2A;
if (Feature == "+fullfp16")
HasFullFP16 = 1;
}
@ -6550,6 +6615,43 @@ class AArch64leTargetInfo : public AArch64TargetInfo {
}
};
class MicrosoftARM64TargetInfo
: public WindowsTargetInfo<AArch64leTargetInfo> {
const llvm::Triple Triple;
public:
MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
WCharType = UnsignedShort;
SizeType = UnsignedLongLong;
TheCXXABI.set(TargetCXXABI::Microsoft);
}
void setDataLayout() override {
resetDataLayout("e-m:w-i64:64-i128:128-n32:64-S128");
}
void getVisualStudioDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
WindowsTargetInfo<AArch64leTargetInfo>::getVisualStudioDefines(Opts,
Builder);
Builder.defineMacro("_WIN32", "1");
Builder.defineMacro("_WIN64", "1");
Builder.defineMacro("_M_ARM64", "1");
}
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
WindowsTargetInfo::getTargetDefines(Opts, Builder);
getVisualStudioDefines(Opts, Builder);
}
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::CharPtrBuiltinVaList;
}
};
class AArch64beTargetInfo : public AArch64TargetInfo {
void setDataLayout() override {
assert(!getTriple().isOSBinFormatMachO());
@ -7727,6 +7829,148 @@ class BPFTargetInfo : public TargetInfo {
}
};
class Nios2TargetInfo : public TargetInfo {
void setDataLayout() {
if (BigEndian)
resetDataLayout("E-p:32:32:32-i8:8:32-i16:16:32-n32");
else
resetDataLayout("e-p:32:32:32-i8:8:32-i16:16:32-n32");
}
static const Builtin::Info BuiltinInfo[];
std::string CPU;
std::string ABI;
public:
Nios2TargetInfo(const llvm::Triple &triple, const TargetOptions &opts)
: TargetInfo(triple), CPU(opts.CPU), ABI(opts.ABI) {
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
setDataLayout();
}
StringRef getABI() const override { return ABI; }
bool setABI(const std::string &Name) override {
if (Name == "o32" || Name == "eabi") {
ABI = Name;
return true;
}
return false;
}
bool setCPU(const std::string &Name) override {
if (Name == "nios2r1" || Name == "nios2r2") {
CPU = Name;
return true;
}
return false;
}
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
DefineStd(Builder, "nios2", Opts);
DefineStd(Builder, "NIOS2", Opts);
Builder.defineMacro("__nios2");
Builder.defineMacro("__NIOS2");
Builder.defineMacro("__nios2__");
Builder.defineMacro("__NIOS2__");
}
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
return llvm::makeArrayRef(BuiltinInfo, clang::Nios2::LastTSBuiltin -
Builtin::FirstTSBuiltin);
}
bool isFeatureSupportedByCPU(StringRef Feature, StringRef CPU) const {
const bool isR2 = CPU == "nios2r2";
return llvm::StringSwitch<bool>(Feature)
.Case("nios2r2mandatory", isR2)
.Case("nios2r2bmx", isR2)
.Case("nios2r2mpx", isR2)
.Case("nios2r2cdx", isR2)
.Default(false);
}
bool initFeatureMap(llvm::StringMap<bool> &Features,
DiagnosticsEngine &Diags, StringRef CPU,
const std::vector<std::string> &FeatureVec) const override {
static const char *allFeatures[] = {
"nios2r2mandatory", "nios2r2bmx", "nios2r2mpx", "nios2r2cdx"
};
for (const char *feature : allFeatures) {
Features[feature] = isFeatureSupportedByCPU(feature, CPU);
}
return true;
}
bool hasFeature(StringRef Feature) const override {
return isFeatureSupportedByCPU(Feature, CPU);
}
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
}
ArrayRef<const char *> getGCCRegNames() const override {
static const char *const GCCRegNames[] = {
// CPU register names
// Must match second column of GCCRegAliases
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
"r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20",
"r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30",
"r31",
// Floating point register names
"ctl0", "ctl1", "ctl2", "ctl3", "ctl4", "ctl5", "ctl6", "ctl7", "ctl8",
"ctl9", "ctl10", "ctl11", "ctl12", "ctl13", "ctl14", "ctl15"
};
return llvm::makeArrayRef(GCCRegNames);
}
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const override {
switch (*Name) {
default:
return false;
case 'r': // CPU registers.
case 'd': // Equivalent to "r" unless generating MIPS16 code.
case 'y': // Equivalent to "r", backwards compatibility only.
case 'f': // floating-point registers.
case 'c': // $25 for indirect jumps
case 'l': // lo register
case 'x': // hilo register pair
Info.setAllowsRegister();
return true;
}
}
const char *getClobbers() const override { return ""; }
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
static const TargetInfo::GCCRegAlias aliases[] = {
{{"zero"}, "r0"}, {{"at"}, "r1"}, {{"et"}, "r24"},
{{"bt"}, "r25"}, {{"gp"}, "r26"}, {{"sp"}, "r27"},
{{"fp"}, "r28"}, {{"ea"}, "r29"}, {{"ba"}, "r30"},
{{"ra"}, "r31"}, {{"status"}, "ctl0"}, {{"estatus"}, "ctl1"},
{{"bstatus"}, "ctl2"}, {{"ienable"}, "ctl3"}, {{"ipending"}, "ctl4"},
{{"cpuid"}, "ctl5"}, {{"exception"}, "ctl7"}, {{"pteaddr"}, "ctl8"},
{{"tlbacc"}, "ctl9"}, {{"tlbmisc"}, "ctl10"}, {{"badaddr"}, "ctl12"},
{{"config"}, "ctl13"}, {{"mpubase"}, "ctl14"}, {{"mpuacc"}, "ctl15"},
};
return llvm::makeArrayRef(aliases);
}
};
const Builtin::Info Nios2TargetInfo::BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
{#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
{#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
#include "clang/Basic/BuiltinsNios2.def"
};
class MipsTargetInfo : public TargetInfo {
void setDataLayout() {
StringRef Layout;
@ -9264,6 +9508,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
case llvm::Triple::OpenBSD:
return new OpenBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
case llvm::Triple::Win32:
return new MicrosoftARM64TargetInfo(Triple, Opts);
default:
return new AArch64leTargetInfo(Triple, Opts);
}
@ -9353,6 +9599,9 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple,
case llvm::Triple::msp430:
return new MSP430TargetInfo(Triple, Opts);
case llvm::Triple::nios2:
return new LinuxTargetInfo<Nios2TargetInfo>(Triple, Opts);
case llvm::Triple::mips:
switch (os) {
case llvm::Triple::Linux:

View File

@ -54,6 +54,7 @@
#include "llvm/Transforms/ObjCARC.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/GVN.h"
#include "llvm/Transforms/Utils/NameAnonGlobals.h"
#include "llvm/Transforms/Utils/SymbolRewriter.h"
#include <memory>
using namespace clang;
@ -414,11 +415,7 @@ static void initTargetOptions(llvm::TargetOptions &Options,
Options.RelaxELFRelocations = CodeGenOpts.RelaxELFRelocations;
// Set EABI version.
Options.EABIVersion = llvm::StringSwitch<llvm::EABI>(TargetOpts.EABIVersion)
.Case("4", llvm::EABI::EABI4)
.Case("5", llvm::EABI::EABI5)
.Case("gnu", llvm::EABI::GNU)
.Default(llvm::EABI::Default);
Options.EABIVersion = TargetOpts.EABIVersion;
if (LangOpts.SjLjExceptions)
Options.ExceptionModel = llvm::ExceptionHandling::SjLj;
@ -491,7 +488,6 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
PMBuilder.OptLevel = CodeGenOpts.OptimizationLevel;
PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB;
PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;
@ -856,11 +852,15 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
if (CodeGenOpts.hasProfileIRUse())
PGOOpt.ProfileUseFile = CodeGenOpts.ProfileInstrumentUsePath;
if (!CodeGenOpts.SampleProfileFile.empty())
PGOOpt.SampleProfileFile = CodeGenOpts.SampleProfileFile;
// Only pass a PGO options struct if -fprofile-generate or
// -fprofile-use were passed on the cmdline.
PassBuilder PB(TM.get(),
(PGOOpt.RunProfileGen ||
!PGOOpt.ProfileUseFile.empty()) ?
!PGOOpt.ProfileUseFile.empty() ||
!PGOOpt.SampleProfileFile.empty()) ?
Optional<PGOOptions>(PGOOpt) : None);
LoopAnalysisManager LAM;
@ -878,20 +878,34 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
PB.registerLoopAnalyses(LAM);
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
ModulePassManager MPM;
ModulePassManager MPM(CodeGenOpts.DebugPassManager);
if (!CodeGenOpts.DisableLLVMPasses) {
bool IsThinLTO = CodeGenOpts.EmitSummaryIndex;
bool IsLTO = CodeGenOpts.PrepareForLTO;
if (CodeGenOpts.OptimizationLevel == 0) {
// Build a minimal pipeline based on the semantics required by Clang,
// which is just that always inlining occurs.
MPM.addPass(AlwaysInlinerPass());
if (IsThinLTO)
MPM.addPass(NameAnonGlobalPass());
} else {
// Otherwise, use the default pass pipeline. We also have to map our
// optimization levels into one of the distinct levels used to configure
// the pipeline.
// Map our optimization levels into one of the distinct levels used to
// configure the pipeline.
PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts);
MPM = PB.buildPerModuleDefaultPipeline(Level);
if (IsThinLTO) {
MPM = PB.buildThinLTOPreLinkDefaultPipeline(
Level, CodeGenOpts.DebugPassManager);
MPM.addPass(NameAnonGlobalPass());
} else if (IsLTO) {
MPM = PB.buildLTOPreLinkDefaultPipeline(Level,
CodeGenOpts.DebugPassManager);
} else {
MPM = PB.buildPerModuleDefaultPipeline(Level,
CodeGenOpts.DebugPassManager);
}
}
}

View File

@ -9372,6 +9372,16 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_grow_memory, X->getType());
return Builder.CreateCall(Callee, X);
}
case WebAssembly::BI__builtin_wasm_throw: {
Value *Tag = EmitScalarExpr(E->getArg(0));
Value *Obj = EmitScalarExpr(E->getArg(1));
Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw);
return Builder.CreateCall(Callee, {Tag, Obj});
}
case WebAssembly::BI__builtin_wasm_rethrow: {
Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow);
return Builder.CreateCall(Callee);
}
default:
return nullptr;

View File

@ -1297,7 +1297,7 @@ static void CreateCoercedStore(llvm::Value *Src,
// If store is legal, just bitcast the src pointer.
if (SrcSize <= DstSize) {
Dst = CGF.Builder.CreateBitCast(Dst, llvm::PointerType::getUnqual(SrcTy));
Dst = CGF.Builder.CreateElementBitCast(Dst, SrcTy);
BuildAggStore(CGF, Src, Dst, DstIsVolatile);
} else {
// Otherwise do coercion through memory. This is stupid, but
@ -2412,8 +2412,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
Address AddrToStoreInto = Address::invalid();
if (SrcSize <= DstSize) {
AddrToStoreInto =
Builder.CreateBitCast(Ptr, llvm::PointerType::getUnqual(STy));
AddrToStoreInto = Builder.CreateElementBitCast(Ptr, STy);
} else {
AddrToStoreInto =
CreateTempAlloca(STy, Alloca.getAlignment(), "coerce");
@ -3389,6 +3388,14 @@ void CodeGenFunction::EmitCallArgs(
unsigned Idx = LeftToRight ? I : E - I - 1;
CallExpr::const_arg_iterator Arg = ArgRange.begin() + Idx;
unsigned InitialArgSize = Args.size();
// If *Arg is an ObjCIndirectCopyRestoreExpr, check that either the types of
// the argument and parameter match or the objc method is parameterized.
assert((!isa<ObjCIndirectCopyRestoreExpr>(*Arg) ||
getContext().hasSameUnqualifiedType((*Arg)->getType(),
ArgTypes[Idx]) ||
(isa<ObjCMethodDecl>(AC.getDecl()) &&
isObjCMethodWithTypeParams(cast<ObjCMethodDecl>(AC.getDecl())))) &&
"Argument and parameter types don't match");
EmitCallArg(Args, *Arg, ArgTypes[Idx]);
// In particular, we depend on it being the last arg in Args, and the
// objectsize bits depend on there only being one arg if !LeftToRight.
@ -3449,7 +3456,6 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
if (const ObjCIndirectCopyRestoreExpr *CRE
= dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
assert(getLangOpts().ObjCAutoRefCount);
assert(getContext().hasSameUnqualifiedType(E->getType(), type));
return emitWritebackArg(*this, args, CRE);
}

View File

@ -1860,6 +1860,10 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
lt = Qualifiers::OCL_ExplicitNone;
}
// Load objects passed indirectly.
if (Arg.isIndirect() && !ArgVal)
ArgVal = Builder.CreateLoad(DeclPtr);
if (lt == Qualifiers::OCL_Strong) {
if (!isConsumed) {
if (CGM.getCodeGenOpts().OptimizationLevel == 0) {

View File

@ -1678,7 +1678,10 @@ struct NullReturnState {
/// Complete the null-return operation. It is valid to call this
/// regardless of whether 'init' has been called.
RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType,
RValue complete(CodeGenFunction &CGF,
ReturnValueSlot returnSlot,
RValue result,
QualType resultType,
const CallArgList &CallArgs,
const ObjCMethodDecl *Method) {
// If we never had to do a null-check, just use the raw result.
@ -1745,7 +1748,8 @@ struct NullReturnState {
// memory or (2) agg values in registers.
if (result.isAggregate()) {
assert(result.isAggregate() && "null init of non-aggregate result?");
CGF.EmitNullInitialization(result.getAggregateAddress(), resultType);
if (!returnSlot.isUnused())
CGF.EmitNullInitialization(result.getAggregateAddress(), resultType);
if (contBB) CGF.EmitBlock(contBB);
return result;
}
@ -2117,11 +2121,11 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
}
}
NullReturnState nullReturn;
bool RequiresNullCheck = false;
llvm::Constant *Fn = nullptr;
if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
if (ReceiverCanBeNull) nullReturn.init(CGF, Arg0);
if (ReceiverCanBeNull) RequiresNullCheck = true;
Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
: ObjCTypes.getSendStretFn(IsSuper);
} else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
@ -2134,23 +2138,30 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
// arm64 uses objc_msgSend for stret methods and yet null receiver check
// must be made for it.
if (ReceiverCanBeNull && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
nullReturn.init(CGF, Arg0);
RequiresNullCheck = true;
Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
: ObjCTypes.getSendFn(IsSuper);
}
// We don't need to emit a null check to zero out an indirect result if the
// result is ignored.
if (Return.isUnused())
RequiresNullCheck = false;
// Emit a null-check if there's a consumed argument other than the receiver.
bool RequiresNullCheck = false;
if (ReceiverCanBeNull && CGM.getLangOpts().ObjCAutoRefCount && Method) {
if (!RequiresNullCheck && CGM.getLangOpts().ObjCAutoRefCount && Method) {
for (const auto *ParamDecl : Method->parameters()) {
if (ParamDecl->hasAttr<NSConsumedAttr>()) {
if (!nullReturn.NullBB)
nullReturn.init(CGF, Arg0);
RequiresNullCheck = true;
break;
}
}
}
NullReturnState nullReturn;
if (RequiresNullCheck) {
nullReturn.init(CGF, Arg0);
}
llvm::Instruction *CallSite;
Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
@ -2164,7 +2175,7 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
llvm::CallSite(CallSite).setDoesNotReturn();
}
return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
RequiresNullCheck ? Method : nullptr);
}
@ -6381,16 +6392,15 @@ llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
if (PTGV)
return CGF.Builder.CreateAlignedLoad(PTGV, Align);
PTGV = new llvm::GlobalVariable(
CGM.getModule(),
Init->getType(), false,
llvm::GlobalValue::WeakAnyLinkage,
Init,
ProtocolName);
PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
llvm::GlobalValue::WeakAnyLinkage, Init,
ProtocolName);
PTGV->setSection(GetSectionName("__objc_protorefs",
"coalesced,no_dead_strip"));
PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
PTGV->setAlignment(Align.getQuantity());
if (!CGM.getTriple().isOSBinFormatMachO())
PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName));
CGM.addCompilerUsedGlobal(PTGV);
return CGF.Builder.CreateAlignedLoad(PTGV, Align);
}
@ -7074,7 +7084,7 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
CGCallee callee(CGCalleeInfo(), calleePtr);
RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
return nullReturn.complete(CGF, result, resultType, formalArgs,
return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
requiresnullCheck ? method : nullptr);
}

View File

@ -26,61 +26,27 @@
using namespace clang;
using namespace CodeGen;
static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
const ObjCInterfaceDecl *OID,
const ObjCImplementationDecl *ID,
const ObjCIvarDecl *Ivar) {
const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
// FIXME: We should eliminate the need to have ObjCImplementationDecl passed
// in here; it should never be necessary because that should be the lexical
// decl context for the ivar.
// If we know have an implementation (and the ivar is in it) then
// look up in the implementation layout.
const ASTRecordLayout *RL;
if (ID && declaresSameEntity(ID->getClassInterface(), Container))
RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
else
RL = &CGM.getContext().getASTObjCInterfaceLayout(Container);
// Compute field index.
//
// FIXME: The index here is closely tied to how ASTContext::getObjCLayout is
// implemented. This should be fixed to get the information from the layout
// directly.
unsigned Index = 0;
for (const ObjCIvarDecl *IVD = Container->all_declared_ivar_begin();
IVD; IVD = IVD->getNextIvar()) {
if (Ivar == IVD)
break;
++Index;
}
assert(Index < RL->getFieldCount() && "Ivar is not inside record layout!");
return RL->getFieldOffset(Index);
}
uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
const ObjCInterfaceDecl *OID,
const ObjCIvarDecl *Ivar) {
return LookupFieldBitOffset(CGM, OID, nullptr, Ivar) /
CGM.getContext().getCharWidth();
return CGM.getContext().lookupFieldBitOffset(OID, nullptr, Ivar) /
CGM.getContext().getCharWidth();
}
uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
const ObjCImplementationDecl *OID,
const ObjCIvarDecl *Ivar) {
return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) /
CGM.getContext().getCharWidth();
return CGM.getContext().lookupFieldBitOffset(OID->getClassInterface(), OID,
Ivar) /
CGM.getContext().getCharWidth();
}
unsigned CGObjCRuntime::ComputeBitfieldBitOffset(
CodeGen::CodeGenModule &CGM,
const ObjCInterfaceDecl *ID,
const ObjCIvarDecl *Ivar) {
return LookupFieldBitOffset(CGM, ID, ID->getImplementation(), Ivar);
return CGM.getContext().lookupFieldBitOffset(ID, ID->getImplementation(),
Ivar);
}
LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
@ -119,7 +85,8 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
// Note, there is a subtle invariant here: we can only call this routine on
// non-synthesized ivars but we may be called for synthesized ivars. However,
// a synthesized ivar can never be a bit-field, so this is safe.
uint64_t FieldBitOffset = LookupFieldBitOffset(CGF.CGM, OID, nullptr, Ivar);
uint64_t FieldBitOffset =
CGF.CGM.getContext().lookupFieldBitOffset(OID, nullptr, Ivar);
uint64_t BitOffset = FieldBitOffset % CGF.CGM.getContext().getCharWidth();
uint64_t AlignmentBits = CGF.CGM.getTarget().getCharAlign();
uint64_t BitFieldSize = Ivar->getBitWidthValue(CGF.getContext());

View File

@ -5603,7 +5603,7 @@ class MappableExprsHandler {
// We have to process the component lists that relate with the same
// declaration in a single chunk so that we can generate the map flags
// correctly. Therefore, we organize all lists in a map.
llvm::DenseMap<const ValueDecl *, SmallVector<MapInfo, 8>> Info;
llvm::MapVector<const ValueDecl *, SmallVector<MapInfo, 8>> Info;
// Helper function to fill the information map for the different supported
// clauses.
@ -5927,16 +5927,11 @@ emitOffloadingArrays(CodeGenFunction &CGF,
for (unsigned i = 0; i < Info.NumberOfPtrs; ++i) {
llvm::Value *BPVal = *BasePointers[i];
if (BPVal->getType()->isPointerTy())
BPVal = CGF.Builder.CreateBitCast(BPVal, CGM.VoidPtrTy);
else {
assert(BPVal->getType()->isIntegerTy() &&
"If not a pointer, the value type must be an integer.");
BPVal = CGF.Builder.CreateIntToPtr(BPVal, CGM.VoidPtrTy);
}
llvm::Value *BP = CGF.Builder.CreateConstInBoundsGEP2_32(
llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
Info.BasePointersArray, 0, i);
BP = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
BP, BPVal->getType()->getPointerTo(/*AddrSpace=*/0));
Address BPAddr(BP, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
CGF.Builder.CreateStore(BPVal, BPAddr);
@ -5945,16 +5940,11 @@ emitOffloadingArrays(CodeGenFunction &CGF,
Info.CaptureDeviceAddrMap.insert(std::make_pair(DevVD, BPAddr));
llvm::Value *PVal = Pointers[i];
if (PVal->getType()->isPointerTy())
PVal = CGF.Builder.CreateBitCast(PVal, CGM.VoidPtrTy);
else {
assert(PVal->getType()->isIntegerTy() &&
"If not a pointer, the value type must be an integer.");
PVal = CGF.Builder.CreateIntToPtr(PVal, CGM.VoidPtrTy);
}
llvm::Value *P = CGF.Builder.CreateConstInBoundsGEP2_32(
llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
Info.PointersArray, 0, i);
P = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
P, PVal->getType()->getPointerTo(/*AddrSpace=*/0));
Address PAddr(P, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
CGF.Builder.CreateStore(PVal, PAddr);

View File

@ -239,21 +239,47 @@ static QualType getCanonicalParamType(ASTContext &C, QualType T) {
return C.getCanonicalParamType(T);
}
llvm::Function *
CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
assert(
CapturedStmtInfo &&
"CapturedStmtInfo should be set when generating the captured function");
const CapturedDecl *CD = S.getCapturedDecl();
const RecordDecl *RD = S.getCapturedRecordDecl();
namespace {
/// Contains required data for proper outlined function codegen.
struct FunctionOptions {
/// Captured statement for which the function is generated.
const CapturedStmt *S = nullptr;
/// true if cast to/from UIntPtr is required for variables captured by
/// value.
bool UIntPtrCastRequired = true;
/// true if only casted argumefnts must be registered as local args or VLA
/// sizes.
bool RegisterCastedArgsOnly = false;
/// Name of the generated function.
StringRef FunctionName;
explicit FunctionOptions(const CapturedStmt *S, bool UIntPtrCastRequired,
bool RegisterCastedArgsOnly,
StringRef FunctionName)
: S(S), UIntPtrCastRequired(UIntPtrCastRequired),
RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly),
FunctionName(FunctionName) {}
};
}
static std::pair<llvm::Function *, bool> emitOutlinedFunctionPrologue(
CodeGenFunction &CGF, FunctionArgList &Args,
llvm::DenseMap<const Decl *, std::pair<const VarDecl *, Address>>
&LocalAddrs,
llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>>
&VLASizes,
llvm::Value *&CXXThisValue, const FunctionOptions &FO) {
const CapturedDecl *CD = FO.S->getCapturedDecl();
const RecordDecl *RD = FO.S->getCapturedRecordDecl();
assert(CD->hasBody() && "missing CapturedDecl body");
CXXThisValue = nullptr;
// Build the argument list.
CodeGenModule &CGM = CGF.CGM;
ASTContext &Ctx = CGM.getContext();
FunctionArgList Args;
bool HasUIntPtrArgs = false;
Args.append(CD->param_begin(),
std::next(CD->param_begin(), CD->getContextParamPosition()));
auto I = S.captures().begin();
auto I = FO.S->captures().begin();
for (auto *FD : RD->fields()) {
QualType ArgType = FD->getType();
IdentifierInfo *II = nullptr;
@ -265,23 +291,24 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
// deal with pointers. We can pass in the same way the VLA type sizes to the
// outlined function.
if ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) ||
I->capturesVariableArrayType())
ArgType = Ctx.getUIntPtrType();
I->capturesVariableArrayType()) {
HasUIntPtrArgs = true;
if (FO.UIntPtrCastRequired)
ArgType = Ctx.getUIntPtrType();
}
if (I->capturesVariable() || I->capturesVariableByCopy()) {
CapVar = I->getCapturedVar();
II = CapVar->getIdentifier();
} else if (I->capturesThis())
II = &getContext().Idents.get("this");
II = &Ctx.Idents.get("this");
else {
assert(I->capturesVariableArrayType());
II = &getContext().Idents.get("vla");
II = &Ctx.Idents.get("vla");
}
if (ArgType->isVariablyModifiedType()) {
ArgType =
getCanonicalParamType(getContext(), ArgType.getNonReferenceType());
}
Args.push_back(ImplicitParamDecl::Create(getContext(), /*DC=*/nullptr,
if (ArgType->isVariablyModifiedType())
ArgType = getCanonicalParamType(Ctx, ArgType.getNonReferenceType());
Args.push_back(ImplicitParamDecl::Create(Ctx, /*DC=*/nullptr,
FD->getLocation(), II, ArgType,
ImplicitParamDecl::Other));
++I;
@ -296,90 +323,166 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo);
llvm::Function *F = llvm::Function::Create(
FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
CapturedStmtInfo->getHelperName(), &CGM.getModule());
llvm::Function *F =
llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
FO.FunctionName, &CGM.getModule());
CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
if (CD->isNothrow())
F->addFnAttr(llvm::Attribute::NoUnwind);
// Generate the function.
StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, CD->getLocation(),
CD->getBody()->getLocStart());
CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, CD->getLocation(),
CD->getBody()->getLocStart());
unsigned Cnt = CD->getContextParamPosition();
I = S.captures().begin();
I = FO.S->captures().begin();
for (auto *FD : RD->fields()) {
// If we are capturing a pointer by copy we don't need to do anything, just
// use the value that we get from the arguments.
if (I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
const VarDecl *CurVD = I->getCapturedVar();
Address LocalAddr = GetAddrOfLocalVar(Args[Cnt]);
Address LocalAddr = CGF.GetAddrOfLocalVar(Args[Cnt]);
// If the variable is a reference we need to materialize it here.
if (CurVD->getType()->isReferenceType()) {
Address RefAddr = CreateMemTemp(CurVD->getType(), getPointerAlign(),
".materialized_ref");
EmitStoreOfScalar(LocalAddr.getPointer(), RefAddr, /*Volatile=*/false,
CurVD->getType());
Address RefAddr = CGF.CreateMemTemp(
CurVD->getType(), CGM.getPointerAlign(), ".materialized_ref");
CGF.EmitStoreOfScalar(LocalAddr.getPointer(), RefAddr,
/*Volatile=*/false, CurVD->getType());
LocalAddr = RefAddr;
}
setAddrOfLocalVar(CurVD, LocalAddr);
if (!FO.RegisterCastedArgsOnly)
LocalAddrs.insert({Args[Cnt], {CurVD, LocalAddr}});
++Cnt;
++I;
continue;
}
LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
LValue ArgLVal =
MakeAddrLValue(GetAddrOfLocalVar(Args[Cnt]), Args[Cnt]->getType(),
BaseInfo);
LValue ArgLVal = CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(Args[Cnt]),
Args[Cnt]->getType(), BaseInfo);
if (FD->hasCapturedVLAType()) {
LValue CastedArgLVal =
MakeAddrLValue(castValueFromUintptr(*this, FD->getType(),
Args[Cnt]->getName(), ArgLVal),
FD->getType(), BaseInfo);
if (FO.UIntPtrCastRequired) {
ArgLVal = CGF.MakeAddrLValue(castValueFromUintptr(CGF, FD->getType(),
Args[Cnt]->getName(),
ArgLVal),
FD->getType(), BaseInfo);
}
auto *ExprArg =
EmitLoadOfLValue(CastedArgLVal, SourceLocation()).getScalarVal();
CGF.EmitLoadOfLValue(ArgLVal, SourceLocation()).getScalarVal();
auto VAT = FD->getCapturedVLAType();
VLASizeMap[VAT->getSizeExpr()] = ExprArg;
VLASizes.insert({Args[Cnt], {VAT->getSizeExpr(), ExprArg}});
} else if (I->capturesVariable()) {
auto *Var = I->getCapturedVar();
QualType VarTy = Var->getType();
Address ArgAddr = ArgLVal.getAddress();
if (!VarTy->isReferenceType()) {
if (ArgLVal.getType()->isLValueReferenceType()) {
ArgAddr = EmitLoadOfReference(
ArgAddr = CGF.EmitLoadOfReference(
ArgAddr, ArgLVal.getType()->castAs<ReferenceType>());
} else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) {
assert(ArgLVal.getType()->isPointerType());
ArgAddr = EmitLoadOfPointer(
ArgAddr = CGF.EmitLoadOfPointer(
ArgAddr, ArgLVal.getType()->castAs<PointerType>());
}
}
setAddrOfLocalVar(
Var, Address(ArgAddr.getPointer(), getContext().getDeclAlign(Var)));
if (!FO.RegisterCastedArgsOnly) {
LocalAddrs.insert(
{Args[Cnt],
{Var, Address(ArgAddr.getPointer(), Ctx.getDeclAlign(Var))}});
}
} else if (I->capturesVariableByCopy()) {
assert(!FD->getType()->isAnyPointerType() &&
"Not expecting a captured pointer.");
auto *Var = I->getCapturedVar();
QualType VarTy = Var->getType();
setAddrOfLocalVar(Var, castValueFromUintptr(*this, FD->getType(),
Args[Cnt]->getName(), ArgLVal,
VarTy->isReferenceType()));
LocalAddrs.insert(
{Args[Cnt],
{Var,
FO.UIntPtrCastRequired
? castValueFromUintptr(CGF, FD->getType(), Args[Cnt]->getName(),
ArgLVal, VarTy->isReferenceType())
: ArgLVal.getAddress()}});
} else {
// If 'this' is captured, load it into CXXThisValue.
assert(I->capturesThis());
CXXThisValue =
EmitLoadOfLValue(ArgLVal, Args[Cnt]->getLocation()).getScalarVal();
CXXThisValue = CGF.EmitLoadOfLValue(ArgLVal, Args[Cnt]->getLocation())
.getScalarVal();
LocalAddrs.insert({Args[Cnt], {nullptr, ArgLVal.getAddress()}});
}
++Cnt;
++I;
}
return {F, HasUIntPtrArgs};
}
llvm::Function *
CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
assert(
CapturedStmtInfo &&
"CapturedStmtInfo should be set when generating the captured function");
const CapturedDecl *CD = S.getCapturedDecl();
// Build the argument list.
bool NeedWrapperFunction =
getDebugInfo() &&
CGM.getCodeGenOpts().getDebugInfo() >= codegenoptions::LimitedDebugInfo;
FunctionArgList Args;
llvm::DenseMap<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs;
llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes;
FunctionOptions FO(&S, !NeedWrapperFunction, /*RegisterCastedArgsOnly=*/false,
CapturedStmtInfo->getHelperName());
llvm::Function *F;
bool HasUIntPtrArgs;
std::tie(F, HasUIntPtrArgs) = emitOutlinedFunctionPrologue(
*this, Args, LocalAddrs, VLASizes, CXXThisValue, FO);
for (const auto &LocalAddrPair : LocalAddrs) {
if (LocalAddrPair.second.first) {
setAddrOfLocalVar(LocalAddrPair.second.first,
LocalAddrPair.second.second);
}
}
for (const auto &VLASizePair : VLASizes)
VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second;
PGO.assignRegionCounters(GlobalDecl(CD), F);
CapturedStmtInfo->EmitBody(*this, CD->getBody());
FinishFunction(CD->getBodyRBrace());
if (!NeedWrapperFunction || !HasUIntPtrArgs)
return F;
return F;
FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true,
/*RegisterCastedArgsOnly=*/true,
".nondebug_wrapper.");
CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true);
WrapperCGF.disableDebugInfo();
Args.clear();
LocalAddrs.clear();
VLASizes.clear();
llvm::Function *WrapperF =
emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes,
WrapperCGF.CXXThisValue, WrapperFO).first;
LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
llvm::SmallVector<llvm::Value *, 4> CallArgs;
for (const auto *Arg : Args) {
llvm::Value *CallArg;
auto I = LocalAddrs.find(Arg);
if (I != LocalAddrs.end()) {
LValue LV =
WrapperCGF.MakeAddrLValue(I->second.second, Arg->getType(), BaseInfo);
CallArg = WrapperCGF.EmitLoadOfScalar(LV, SourceLocation());
} else {
auto EI = VLASizes.find(Arg);
if (EI != VLASizes.end())
CallArg = EI->second.second;
else {
LValue LV = WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg),
Arg->getType(), BaseInfo);
CallArg = WrapperCGF.EmitLoadOfScalar(LV, SourceLocation());
}
}
CallArgs.emplace_back(CallArg);
}
WrapperCGF.Builder.CreateCall(F, CallArgs);
WrapperCGF.FinishFunction();
return WrapperF;
}
//===----------------------------------------------------------------------===//

View File

@ -228,7 +228,10 @@ namespace clang {
Ctx.getDiagnosticHandler();
void *OldDiagnosticContext = Ctx.getDiagnosticContext();
Ctx.setDiagnosticHandler(DiagnosticHandler, this);
Ctx.setDiagnosticHotnessRequested(CodeGenOpts.DiagnosticsWithHotness);
Ctx.setDiagnosticsHotnessRequested(CodeGenOpts.DiagnosticsWithHotness);
if (CodeGenOpts.DiagnosticsHotnessThreshold != 0)
Ctx.setDiagnosticsHotnessThreshold(
CodeGenOpts.DiagnosticsHotnessThreshold);
std::unique_ptr<llvm::tool_output_file> OptRecordFile;
if (!CodeGenOpts.OptRecordFile.empty()) {
@ -246,7 +249,7 @@ namespace clang {
llvm::make_unique<yaml::Output>(OptRecordFile->os()));
if (CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone)
Ctx.setDiagnosticHotnessRequested(true);
Ctx.setDiagnosticsHotnessRequested(true);
}
// Link each LinkModule into our module.

View File

@ -617,6 +617,9 @@ uint64_t PGOHash::finalize() {
void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
const Decl *D = GD.getDecl();
if (!D->hasBody())
return;
bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
if (!InstrumentRegions && !PGOReader)

View File

@ -23,10 +23,11 @@ using namespace clang;
using namespace llvm::opt;
Compilation::Compilation(const Driver &D, const ToolChain &_DefaultToolChain,
InputArgList *_Args, DerivedArgList *_TranslatedArgs)
InputArgList *_Args, DerivedArgList *_TranslatedArgs,
bool ContainsError)
: TheDriver(D), DefaultToolChain(_DefaultToolChain), ActiveOffloadMask(0u),
Args(_Args), TranslatedArgs(_TranslatedArgs), Redirects(nullptr),
ForDiagnostics(false) {
ForDiagnostics(false), ContainsError(ContainsError) {
// The offloading host toolchain is the default tool chain.
OrderedOffloadingToolchains.insert(
std::make_pair(Action::OFK_Host, &DefaultToolChain));

View File

@ -153,8 +153,10 @@ void Driver::setDriverModeFromOption(StringRef Opt) {
Diag(diag::err_drv_unsupported_option_argument) << OptName << Value;
}
InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings) {
InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings,
bool &ContainsError) {
llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
ContainsError = false;
unsigned IncludedFlagsBitmask;
unsigned ExcludedFlagsBitmask;
@ -167,27 +169,41 @@ InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings) {
IncludedFlagsBitmask, ExcludedFlagsBitmask);
// Check for missing argument error.
if (MissingArgCount)
Diag(clang::diag::err_drv_missing_argument)
if (MissingArgCount) {
Diag(diag::err_drv_missing_argument)
<< Args.getArgString(MissingArgIndex) << MissingArgCount;
ContainsError |=
Diags.getDiagnosticLevel(diag::err_drv_missing_argument,
SourceLocation()) > DiagnosticsEngine::Warning;
}
// Check for unsupported options.
for (const Arg *A : Args) {
if (A->getOption().hasFlag(options::Unsupported)) {
Diag(clang::diag::err_drv_unsupported_opt) << A->getAsString(Args);
Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
SourceLocation()) >
DiagnosticsEngine::Warning;
continue;
}
// Warn about -mcpu= without an argument.
if (A->getOption().matches(options::OPT_mcpu_EQ) && A->containsValue("")) {
Diag(clang::diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
Diag(diag::warn_drv_empty_joined_argument) << A->getAsString(Args);
ContainsError |= Diags.getDiagnosticLevel(
diag::warn_drv_empty_joined_argument,
SourceLocation()) > DiagnosticsEngine::Warning;
}
}
for (const Arg *A : Args.filtered(options::OPT_UNKNOWN))
Diags.Report(IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl :
diag::err_drv_unknown_argument)
<< A->getAsString(Args);
for (const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
auto ID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
: diag::err_drv_unknown_argument;
Diags.Report(ID) << A->getAsString(Args);
ContainsError |= Diags.getDiagnosticLevel(ID, SourceLocation()) >
DiagnosticsEngine::Warning;
}
return Args;
}
@ -600,9 +616,8 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
// FIXME: This stuff needs to go into the Compilation, not the driver.
bool CCCPrintPhases;
InputArgList Args = ParseArgStrings(ArgList.slice(1));
if (Diags.hasErrorOccurred())
return nullptr;
bool ContainsError;
InputArgList Args = ParseArgStrings(ArgList.slice(1), ContainsError);
// Silence driver warnings if requested
Diags.setIgnoreAllWarnings(Args.hasArg(options::OPT_w));
@ -692,7 +707,8 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
*UArgs, computeTargetTriple(*this, DefaultTargetTriple, *UArgs));
// The compilation takes ownership of Args.
Compilation *C = new Compilation(*this, TC, UArgs.release(), TranslatedArgs);
Compilation *C = new Compilation(*this, TC, UArgs.release(), TranslatedArgs,
ContainsError);
if (!HandleImmediateArgs(*C))
return C;

View File

@ -32,7 +32,7 @@ enum : SanitizerMask {
RequiresPIE = DataFlow,
NeedsUnwindTables = Address | Thread | Memory | DataFlow,
SupportsCoverage = Address | KernelAddress | Memory | Leak | Undefined |
Integer | Nullability | DataFlow,
Integer | Nullability | DataFlow | Fuzzer,
RecoverableByDefault = Undefined | Integer | Nullability,
Unrecoverable = Unreachable | Return,
LegacyFsanitizeRecoverMask = Undefined | Integer,

View File

@ -392,9 +392,7 @@ void arm::getARMTargetFeatures(const ToolChain &TC,
if (B->getOption().matches(options::OPT_mlong_calls))
D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
}
CmdArgs.push_back("-backend-option");
CmdArgs.push_back("-arm-execute-only");
Features.push_back("+execute-only");
}
}
}

View File

@ -35,6 +35,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/YAMLParser.h"
#ifdef LLVM_ON_UNIX
@ -129,6 +130,13 @@ forAllAssociatedToolChains(Compilation &C, const JobAction &JA,
else if (JA.isDeviceOffloading(Action::OFK_Cuda))
Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
if (JA.isHostOffloading(Action::OFK_OpenMP)) {
auto TCs = C.getOffloadToolChains<Action::OFK_OpenMP>();
for (auto II = TCs.first, IE = TCs.second; II != IE; ++II)
Work(*II->second);
} else if (JA.isDeviceOffloading(Action::OFK_OpenMP))
Work(*C.getSingleOffloadToolChain<Action::OFK_Host>());
//
// TODO: Add support for other offloading programming models here.
//
@ -781,15 +789,14 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D,
CmdArgs.push_back("-femit-coverage-data");
if (Args.hasFlag(options::OPT_fcoverage_mapping,
options::OPT_fno_coverage_mapping, false) &&
!ProfileGenerateArg)
D.Diag(clang::diag::err_drv_argument_only_allowed_with)
<< "-fcoverage-mapping"
<< "-fprofile-instr-generate";
options::OPT_fno_coverage_mapping, false)) {
if (!ProfileGenerateArg)
D.Diag(clang::diag::err_drv_argument_only_allowed_with)
<< "-fcoverage-mapping"
<< "-fprofile-instr-generate";
if (Args.hasFlag(options::OPT_fcoverage_mapping,
options::OPT_fno_coverage_mapping, false))
CmdArgs.push_back("-fcoverage-mapping");
}
if (C.getArgs().hasArg(options::OPT_c) ||
C.getArgs().hasArg(options::OPT_S)) {
@ -1309,43 +1316,13 @@ void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
// FIXME: Support -meabi.
// FIXME: Parts of this are duplicated in the backend, unify this somehow.
const char *ABIName = nullptr;
if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
ABIName = A->getValue();
} else if (Triple.isOSBinFormatMachO()) {
if (arm::useAAPCSForMachO(Triple)) {
ABIName = "aapcs";
} else if (Triple.isWatchABI()) {
ABIName = "aapcs16";
} else {
ABIName = "apcs-gnu";
}
} else if (Triple.isOSWindows()) {
// FIXME: this is invalid for WindowsCE
ABIName = "aapcs";
} else {
// Select the default based on the platform.
switch (Triple.getEnvironment()) {
case llvm::Triple::Android:
case llvm::Triple::GNUEABI:
case llvm::Triple::GNUEABIHF:
case llvm::Triple::MuslEABI:
case llvm::Triple::MuslEABIHF:
ABIName = "aapcs-linux";
break;
case llvm::Triple::EABIHF:
case llvm::Triple::EABI:
ABIName = "aapcs";
break;
default:
if (Triple.getOS() == llvm::Triple::NetBSD)
ABIName = "apcs-gnu";
else if (Triple.getOS() == llvm::Triple::OpenBSD)
ABIName = "aapcs-linux";
else
ABIName = "aapcs";
break;
}
else {
std::string CPU = getCPUName(Args, Triple, /*FromAs*/ false);
ABIName = llvm::ARM::computeDefaultTargetABI(Triple, CPU).data();
}
CmdArgs.push_back("-target-abi");
CmdArgs.push_back(ABIName);
@ -1993,6 +1970,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
}
if (IsOpenMPDevice) {
// We have to pass the triple of the host if compiling for an OpenMP device.
std::string NormalizedTriple =
C.getSingleOffloadToolChain<Action::OFK_Host>()
->getTriple()
.normalize();
CmdArgs.push_back("-aux-triple");
CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
}
if (Triple.isOSWindows() && (Triple.getArch() == llvm::Triple::arm ||
Triple.getArch() == llvm::Triple::thumb)) {
unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
@ -4056,6 +4043,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_diagnostics_show_hotness, false))
CmdArgs.push_back("-fdiagnostics-show-hotness");
if (const Arg *A =
Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
std::string Opt = std::string("-fdiagnostics-hotness-threshold=") + A->getValue();
CmdArgs.push_back(Args.MakeArgString(Opt));
}
if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
CmdArgs.push_back("-fdiagnostics-format");
CmdArgs.push_back(A->getValue());
@ -4140,11 +4133,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_slp_vectorize, EnableSLPVec))
CmdArgs.push_back("-vectorize-slp");
// -fno-slp-vectorize-aggressive is default.
if (Args.hasFlag(options::OPT_fslp_vectorize_aggressive,
options::OPT_fno_slp_vectorize_aggressive, false))
CmdArgs.push_back("-vectorize-slp-aggressive");
if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
A->render(Args, CmdArgs);
@ -4413,10 +4401,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// device declarations can be identified. Also, -fopenmp-is-device is passed
// along to tell the frontend that it is generating code for a device, so that
// only the relevant declarations are emitted.
if (IsOpenMPDevice && Inputs.size() == 2) {
if (IsOpenMPDevice) {
CmdArgs.push_back("-fopenmp-is-device");
CmdArgs.push_back("-fopenmp-host-ir-file-path");
CmdArgs.push_back(Args.MakeArgString(Inputs.back().getFilename()));
if (Inputs.size() == 2) {
CmdArgs.push_back("-fopenmp-host-ir-file-path");
CmdArgs.push_back(Args.MakeArgString(Inputs.back().getFilename()));
}
}
// For all the host OpenMP offloading compile jobs we need to pass the targets

View File

@ -215,6 +215,21 @@ static std::string getR600TargetGPU(const ArgList &Args) {
return "";
}
static std::string getNios2TargetCPU(const ArgList &Args) {
Arg *A = Args.getLastArg(options::OPT_mcpu_EQ);
if (!A)
A = Args.getLastArg(options::OPT_march_EQ);
if (!A)
return "";
const char *name = A->getValue();
return llvm::StringSwitch<const char *>(name)
.Case("r1", "nios2r1")
.Case("r2", "nios2r2")
.Default(name);
}
static std::string getLanaiTargetCPU(const ArgList &Args) {
if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
return A->getValue();
@ -267,6 +282,10 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
return A->getValue();
return "";
case llvm::Triple::nios2: {
return getNios2TargetCPU(Args);
}
case llvm::Triple::mips:
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
@ -598,7 +617,8 @@ bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
NonWholeStaticRuntimes, HelperStaticRuntimes,
RequiredSymbols);
// Inject libfuzzer dependencies.
if (TC.getSanitizerArgs().needsFuzzer()) {
if (TC.getSanitizerArgs().needsFuzzer()
&& !Args.hasArg(options::OPT_shared)) {
addLibFuzzerRuntime(TC, Args, CmdArgs);
}

View File

@ -238,8 +238,15 @@ AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
const Driver &D = getDriver();
const std::string &SysRoot = D.SysRoot;
if (DriverArgs.hasArg(options::OPT_nostdlibinc))
auto AddSystemAfterIncludes = [&]() {
for (const auto &P : DriverArgs.getAllArgValues(options::OPT_isystem_after))
addSystemInclude(DriverArgs, CC1Args, P);
};
if (DriverArgs.hasArg(options::OPT_nostdinc)) {
AddSystemAfterIncludes();
return;
}
addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
@ -247,8 +254,7 @@ AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::sys::path::append(ResourceDir, "include");
addSystemInclude(DriverArgs, CC1Args, ResourceDir);
}
for (const auto &P : DriverArgs.getAllArgValues(options::OPT_isystem_after))
addSystemInclude(DriverArgs, CC1Args, P);
AddSystemAfterIncludes();
addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
}
@ -258,7 +264,7 @@ AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
const llvm::Triple &Triple = getTriple();
const std::string &SysRoot = getDriver().SysRoot;
if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
if (DriverArgs.hasArg(options::OPT_nostdinc) ||
DriverArgs.hasArg(options::OPT_nostdincxx))
return;

View File

@ -1053,7 +1053,7 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan");
if (Sanitize.needsTsanRt())
AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan");
if (Sanitize.needsFuzzer())
if (Sanitize.needsFuzzer() && !Args.hasArg(options::OPT_dynamiclib))
AddFuzzerLinkArgs(Args, CmdArgs);
if (Sanitize.needsStatsRt()) {
StringRef OS = isTargetMacOS() ? "osx" : "iossim";
@ -1150,6 +1150,17 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
Args.getLastArg(options::OPT_mwatchos_version_min_EQ,
options::OPT_mwatchos_simulator_version_min_EQ);
unsigned Major, Minor, Micro;
bool HadExtra;
// iOS 10 is the maximum deployment target for 32-bit targets.
if (iOSVersion && getTriple().isArch32Bit() &&
Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro,
HadExtra) &&
Major > 10)
getDriver().Diag(diag::err_invalid_ios_deployment_target)
<< iOSVersion->getAsString(Args);
// Add a macro to differentiate between m(iphone|tv|watch)os-version-min=X.Y and
// -m(iphone|tv|watch)simulator-version-min=X.Y.
if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ) ||
@ -1191,6 +1202,14 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
if (char *env = ::getenv("WATCHOS_DEPLOYMENT_TARGET"))
WatchOSTarget = env;
// iOS 10 is the maximum deployment target for 32-bit targets.
if (!iOSTarget.empty() && getTriple().isArch32Bit() &&
Driver::GetReleaseVersion(iOSTarget.c_str(), Major, Minor, Micro,
HadExtra) &&
Major > 10)
getDriver().Diag(diag::err_invalid_ios_deployment_target)
<< std::string("IPHONEOS_DEPLOYMENT_TARGET=") + iOSTarget;
// If there is no command-line argument to specify the Target version and
// no environment variable defined, see if we can set the default based
// on -isysroot.
@ -1308,8 +1327,6 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
llvm_unreachable("Unable to infer Darwin variant");
// Set the tool chain target information.
unsigned Major, Minor, Micro;
bool HadExtra;
if (Platform == MacOS) {
assert((!iOSVersion && !TvOSVersion && !WatchOSVersion) &&
"Unknown target platform!");
@ -1325,6 +1342,13 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
<< iOSVersion->getAsString(Args);
// iOS 10 is the maximum deployment target for 32-bit targets. If the
// inferred deployment target is iOS 11 or later, set it to 10.99.
if (getTriple().isArch32Bit() && Major >= 11) {
Major = 10;
Minor = 99;
Micro = 99;
}
} else if (Platform == TvOS) {
if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor,
Micro, HadExtra) || HadExtra ||
@ -1667,6 +1691,28 @@ void MachO::AddLinkRuntimeLibArgs(const ArgList &Args,
AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true);
}
bool Darwin::isAlignedAllocationUnavailable() const {
switch (TargetPlatform) {
case MacOS: // Earlier than 10.13.
return TargetVersion < VersionTuple(10U, 13U, 0U);
case IPhoneOS:
case IPhoneOSSimulator:
case TvOS:
case TvOSSimulator: // Earlier than 11.0.
return TargetVersion < VersionTuple(11U, 0U, 0U);
case WatchOS:
case WatchOSSimulator: // Earlier than 4.0.
return TargetVersion < VersionTuple(4U, 0U, 0U);
}
llvm_unreachable("Unsupported platform");
}
void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
if (isAlignedAllocationUnavailable())
CC1Args.push_back("-faligned-alloc-unavailable");
}
DerivedArgList *
Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
Action::OffloadKind DeviceOffloadKind) const {

View File

@ -384,6 +384,14 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
return TargetVersion < VersionTuple(V0, V1, V2);
}
/// Return true if c++17 aligned allocation/deallocation functions are not
/// implemented in the c++ standard library of the deployment target we are
/// targeting.
bool isAlignedAllocationUnavailable() const;
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
StringRef getPlatformFamily() const;
static StringRef getSDKName(StringRef isysroot);
StringRef getOSLibraryNameSuffix() const;

View File

@ -109,7 +109,7 @@ std::string MipsLLVMToolChain::findLibCxxIncludePath() const {
void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) &&
"Only -lc++ (aka libxx) is suported in this toolchain.");
"Only -lc++ (aka libxx) is supported in this toolchain.");
CmdArgs.push_back("-lc++");
CmdArgs.push_back("-lc++abi");

View File

@ -56,6 +56,8 @@ static bool startsNextParameter(const FormatToken &Current,
if (Current.is(TT_CtorInitializerComma) &&
Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma)
return true;
if (Style.Language == FormatStyle::LK_Proto && Current.is(TT_SelectorName))
return true;
return Previous.is(tok::comma) && !Current.isTrailingComment() &&
((Previous.isNot(TT_CtorInitializerComma) ||
Style.BreakConstructorInitializers !=
@ -499,6 +501,13 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
}
}
static bool lessOpensProtoMessageField(const FormatToken &LessTok,
const LineState &State) {
assert(LessTok.is(tok::less));
return LessTok.NestingLevel > 0 ||
(LessTok.Previous && LessTok.Previous->is(tok::equal));
}
unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
bool DryRun) {
FormatToken &Current = *State.NextToken;
@ -641,6 +650,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
// before the corresponding } or ].
if (PreviousNonComment &&
(PreviousNonComment->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
(Style.Language == FormatStyle::LK_Proto &&
PreviousNonComment->is(tok::less) &&
lessOpensProtoMessageField(*PreviousNonComment, State)) ||
(PreviousNonComment->is(TT_TemplateString) &&
PreviousNonComment->opensScope())))
State.Stack.back().BreakBeforeClosingBrace = true;
@ -682,7 +694,9 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
if (NextNonComment->is(tok::l_brace) && NextNonComment->BlockKind == BK_Block)
return Current.NestingLevel == 0 ? State.FirstIndent
: State.Stack.back().Indent;
if (Current.isOneOf(tok::r_brace, tok::r_square) && State.Stack.size() > 1) {
if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
(Current.is(tok::greater) && Style.Language == FormatStyle::LK_Proto)) &&
State.Stack.size() > 1) {
if (Current.closesBlockOrBlockTypeList(Style))
return State.Stack[State.Stack.size() - 2].NestedBlockIndent;
if (Current.MatchingParen &&
@ -1035,7 +1049,9 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
bool BreakBeforeParameter = false;
unsigned NestedBlockIndent = std::max(State.Stack.back().StartOfFunctionCall,
State.Stack.back().NestedBlockIndent);
if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare)) {
if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
(Style.Language == FormatStyle::LK_Proto && Current.is(tok::less) &&
lessOpensProtoMessageField(Current, State))) {
if (Current.opensBlockOrBlockTypeList(Style)) {
NewIndent = Style.IndentWidth +
std::min(State.Column, State.Stack.back().NestedBlockIndent);
@ -1047,12 +1063,12 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
Current.MatchingParen->Previous &&
Current.MatchingParen->Previous->is(tok::comma);
AvoidBinPacking =
(Current.is(TT_ArrayInitializerLSquare) && EndsInComma) ||
Current.is(TT_DictLiteral) ||
EndsInComma || Current.is(TT_DictLiteral) ||
Style.Language == FormatStyle::LK_Proto || !Style.BinPackArguments ||
(NextNoComment &&
NextNoComment->isOneOf(TT_DesignatedInitializerPeriod,
TT_DesignatedInitializerLSquare));
BreakBeforeParameter = EndsInComma;
if (Current.ParameterCount > 1)
NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
} else {

View File

@ -44,7 +44,6 @@
using clang::format::FormatStyle;
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string)
LLVM_YAML_IS_SEQUENCE_VECTOR(clang::format::FormatStyle::IncludeCategory)
namespace llvm {
@ -414,7 +413,9 @@ template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> {
IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch);
IO.mapOptional("BeforeElse", Wrapping.BeforeElse);
IO.mapOptional("IndentBraces", Wrapping.IndentBraces);
IO.mapOptional("SplitEmptyFunctionBody", Wrapping.SplitEmptyFunctionBody);
IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);
IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord);
IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
}
};
@ -490,7 +491,8 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
return Style;
FormatStyle Expanded = Style;
Expanded.BraceWrapping = {false, false, false, false, false, false,
false, false, false, false, false, true};
false, false, false, false, false, true,
true, true};
switch (Style.BreakBeforeBraces) {
case FormatStyle::BS_Linux:
Expanded.BraceWrapping.AfterClass = true;
@ -503,7 +505,8 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
Expanded.BraceWrapping.AfterFunction = true;
Expanded.BraceWrapping.AfterStruct = true;
Expanded.BraceWrapping.AfterUnion = true;
Expanded.BraceWrapping.SplitEmptyFunctionBody = false;
Expanded.BraceWrapping.SplitEmptyFunction = false;
Expanded.BraceWrapping.SplitEmptyRecord = false;
break;
case FormatStyle::BS_Stroustrup:
Expanded.BraceWrapping.AfterFunction = true;
@ -523,7 +526,8 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
break;
case FormatStyle::BS_GNU:
Expanded.BraceWrapping = {true, true, true, true, true, true,
true, true, true, true, true, true};
true, true, true, true, true, true,
true, true};
break;
case FormatStyle::BS_WebKit:
Expanded.BraceWrapping.AfterFunction = true;
@ -560,7 +564,8 @@ FormatStyle getLLVMStyle() {
LLVMStyle.BreakBeforeTernaryOperators = true;
LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
LLVMStyle.BraceWrapping = {false, false, false, false, false, false,
false, false, false, false, false, true};
false, false, false, false, false, true,
true, true};
LLVMStyle.BreakAfterJavaFieldAnnotations = false;
LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
LLVMStyle.BreakBeforeInheritanceComma = false;
@ -579,9 +584,9 @@ FormatStyle getLLVMStyle() {
LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
LLVMStyle.IncludeCategories = {{"^\"(llvm|llvm-c|clang|clang-c)/", 2},
{"^(<|\"(gtest|isl|json)/)", 3},
{"^(<|\"(gtest|gmock|isl|json)/)", 3},
{".*", 1}};
LLVMStyle.IncludeIsMainRegex = "$";
LLVMStyle.IncludeIsMainRegex = "(Test)?$";
LLVMStyle.IndentCaseLabels = false;
LLVMStyle.IndentWrappedFunctionNames = false;
LLVMStyle.IndentWidth = 2;
@ -1409,7 +1414,7 @@ class IncludeCategoryManager {
: Style(Style), FileName(FileName) {
FileStem = llvm::sys::path::stem(FileName);
for (const auto &Category : Style.IncludeCategories)
CategoryRegexs.emplace_back(Category.Regex);
CategoryRegexs.emplace_back(Category.Regex, llvm::Regex::IgnoreCase);
IsMainFile = FileName.endswith(".c") || FileName.endswith(".cc") ||
FileName.endswith(".cpp") || FileName.endswith(".c++") ||
FileName.endswith(".cxx") || FileName.endswith(".m") ||
@ -1437,9 +1442,11 @@ class IncludeCategoryManager {
return false;
StringRef HeaderStem =
llvm::sys::path::stem(IncludeName.drop_front(1).drop_back(1));
if (FileStem.startswith(HeaderStem)) {
if (FileStem.startswith(HeaderStem) ||
FileStem.startswith_lower(HeaderStem)) {
llvm::Regex MainIncludeRegex(
(HeaderStem + Style.IncludeIsMainRegex).str());
(HeaderStem + Style.IncludeIsMainRegex).str(),
llvm::Regex::IgnoreCase);
if (MainIncludeRegex.match(FileStem))
return true;
}

View File

@ -465,7 +465,8 @@ struct FormatToken {
return is(TT_ArrayInitializerLSquare) ||
(is(tok::l_brace) &&
(BlockKind == BK_Block || is(TT_DictLiteral) ||
(!Style.Cpp11BracedListStyle && NestingLevel == 0)));
(!Style.Cpp11BracedListStyle && NestingLevel == 0))) ||
(is(tok::less) && Style.Language == FormatStyle::LK_Proto);
}
/// \brief Same as opensBlockOrBlockTypeList, but for the closing token.
@ -475,6 +476,19 @@ struct FormatToken {
return MatchingParen && MatchingParen->opensBlockOrBlockTypeList(Style);
}
/// \brief Return the actual namespace token, if this token starts a namespace
/// block.
const FormatToken *getNamespaceToken() const {
const FormatToken *NamespaceTok = this;
if (is(tok::comment))
NamespaceTok = NamespaceTok->getNextNonComment();
// Detect "(inline)? namespace" in the beginning of a line.
if (NamespaceTok && NamespaceTok->is(tok::kw_inline))
NamespaceTok = NamespaceTok->getNextNonComment();
return NamespaceTok && NamespaceTok->is(tok::kw_namespace) ? NamespaceTok
: nullptr;
}
private:
// Disallow copying.
FormatToken(const FormatToken &) = delete;

View File

@ -174,7 +174,7 @@ tooling::Replacements NamespaceEndCommentsFixer::analyze(
AllNamespaceNames = "::" + NamespaceName + AllNamespaceNames;
continue;
}
NamespaceName += std::move(AllNamespaceNames);
NamespaceName += AllNamespaceNames;
CompactedNamespacesCount = 0;
AllNamespaceNames = std::string();
}

View File

@ -89,7 +89,8 @@ class AnnotatingParser {
continue;
}
if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) ||
(CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext))
(CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext &&
Style.Language != FormatStyle::LK_Proto))
return false;
// If a && or || is found and interpreted as a binary operator, this set
// of angles is likely part of something like "a < b && c > d". If the
@ -103,6 +104,14 @@ class AnnotatingParser {
!Line.startsWith(tok::kw_template))
return false;
updateParameterCount(Left, CurrentToken);
if (Style.Language == FormatStyle::LK_Proto) {
if (FormatToken *Previous = CurrentToken->getPreviousNonComment()) {
if (CurrentToken->is(tok::colon) ||
(CurrentToken->isOneOf(tok::l_brace, tok::less) &&
Previous->isNot(tok::colon)))
Previous->Type = TT_SelectorName;
}
}
if (!consumeToken())
return false;
}
@ -440,7 +449,7 @@ class AnnotatingParser {
if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
return false;
updateParameterCount(Left, CurrentToken);
if (CurrentToken->isOneOf(tok::colon, tok::l_brace)) {
if (CurrentToken->isOneOf(tok::colon, tok::l_brace, tok::less)) {
FormatToken *Previous = CurrentToken->getPreviousNonComment();
if (((CurrentToken->is(tok::colon) &&
(!Contexts.back().ColonIsDictLiteral || !Style.isCpp())) ||
@ -1561,8 +1570,10 @@ class ExpressionParser {
const FormatToken *NextNonComment = Current->getNextNonComment();
if (Current->is(TT_ConditionalExpr))
return prec::Conditional;
if (NextNonComment && NextNonComment->is(tok::colon) &&
NextNonComment->is(TT_DictLiteral))
if (NextNonComment && Current->is(TT_SelectorName) &&
(NextNonComment->is(TT_DictLiteral) ||
(Style.Language == FormatStyle::LK_Proto &&
NextNonComment->is(tok::less))))
return prec::Assignment;
if (Current->is(TT_JsComputedPropertyName))
return prec::Assignment;
@ -2549,10 +2560,16 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
// deliberate choice and might have aligned the contents of the string
// literal accordingly. Thus, we try keep existing line breaks.
return Right.NewlinesBefore > 0;
if (Right.Previous->is(tok::l_brace) && Right.NestingLevel == 1 &&
Style.Language == FormatStyle::LK_Proto)
// Don't put enums onto single lines in protocol buffers.
if ((Right.Previous->is(tok::l_brace) ||
(Right.Previous->is(tok::less) &&
Right.Previous->Previous &&
Right.Previous->Previous->is(tok::equal))
) &&
Right.NestingLevel == 1 && Style.Language == FormatStyle::LK_Proto) {
// Don't put enums or option definitions onto single lines in protocol
// buffers.
return true;
}
if (Right.is(TT_InlineASMBrace))
return Right.HasUnescapedNewline;
if (isAllmanBrace(Left) || isAllmanBrace(Right))

View File

@ -136,10 +136,7 @@ class LevelIndentTracker {
bool isNamespaceDeclaration(const AnnotatedLine *Line) {
const FormatToken *NamespaceTok = Line->First;
// Detect "(inline)? namespace" in the beginning of a line.
if (NamespaceTok->is(tok::kw_inline))
NamespaceTok = NamespaceTok->getNextNonComment();
return NamespaceTok && NamespaceTok->is(tok::kw_namespace);
return NamespaceTok && NamespaceTok->getNamespaceToken();
}
bool isEndOfNamespace(const AnnotatedLine *Line,
@ -216,10 +213,31 @@ class LineJoiner {
if (TheLine->Last->is(TT_FunctionLBrace) &&
TheLine->First == TheLine->Last &&
!Style.BraceWrapping.SplitEmptyFunctionBody &&
!Style.BraceWrapping.SplitEmptyFunction &&
I[1]->First->is(tok::r_brace))
return tryMergeSimpleBlock(I, E, Limit);
// Handle empty record blocks where the brace has already been wrapped
if (TheLine->Last->is(tok::l_brace) && TheLine->First == TheLine->Last &&
I != AnnotatedLines.begin()) {
bool EmptyBlock = I[1]->First->is(tok::r_brace);
const FormatToken *Tok = I[-1]->First;
if (Tok && Tok->is(tok::comment))
Tok = Tok->getNextNonComment();
if (Tok && Tok->getNamespaceToken())
return !Style.BraceWrapping.SplitEmptyNamespace && EmptyBlock
? tryMergeSimpleBlock(I, E, Limit) : 0;
if (Tok && Tok->is(tok::kw_typedef))
Tok = Tok->getNextNonComment();
if (Tok && Tok->isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union,
Keywords.kw_interface))
return !Style.BraceWrapping.SplitEmptyRecord && EmptyBlock
? tryMergeSimpleBlock(I, E, Limit) : 0;
}
// FIXME: TheLine->Level != 0 might or might not be the right check to do.
// If necessary, change to something smarter.
bool MergeShortFunctions =

View File

@ -1176,9 +1176,12 @@ void UnwrappedLineParser::parseStructuralElement() {
}
nextToken();
if (FormatTok->Tok.is(tok::l_brace)) {
if (FormatTok->Tok.is(tok::l_brace))
parseBracedList();
}
else if (Style.Language == FormatStyle::LK_Proto &&
FormatTok->Tok.is(tok::less))
parseBracedList(/*ContinueOnSemicolons=*/false,
/*ClosingBraceKind=*/tok::greater);
break;
case tok::l_square:
parseSquare();
@ -1346,7 +1349,8 @@ bool UnwrappedLineParser::tryToParseBracedList() {
return true;
}
bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons,
tok::TokenKind ClosingBraceKind) {
bool HasError = false;
nextToken();
@ -1375,6 +1379,10 @@ bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
parseChildBlock();
}
}
if (FormatTok->Tok.getKind() == ClosingBraceKind) {
nextToken();
return !HasError;
}
switch (FormatTok->Tok.getKind()) {
case tok::caret:
nextToken();
@ -1401,9 +1409,6 @@ bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
FormatTok->BlockKind = BK_BracedInit;
parseBracedList();
break;
case tok::r_brace:
nextToken();
return !HasError;
case tok::semi:
// JavaScript (or more precisely TypeScript) can have semicolons in braced
// lists (in so-called TypeMemberLists). Thus, the semicolon cannot be

View File

@ -93,7 +93,8 @@ class UnwrappedLineParser {
void readTokenWithJavaScriptASI();
void parseStructuralElement();
bool tryToParseBracedList();
bool parseBracedList(bool ContinueOnSemicolons = false);
bool parseBracedList(bool ContinueOnSemicolons = false,
tok::TokenKind ClosingBraceKind = tok::r_brace);
void parseParens();
void parseSquare();
void parseIfThenElse();

View File

@ -44,9 +44,9 @@ void ASTMergeAction::ExecuteAction() {
new ForwardingDiagnosticConsumer(
*CI.getDiagnostics().getClient()),
/*ShouldOwnClient=*/true));
std::unique_ptr<ASTUnit> Unit =
ASTUnit::LoadFromASTFile(ASTFiles[I], CI.getPCHContainerReader(),
Diags, CI.getFileSystemOpts(), false);
std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile(
ASTFiles[I], CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags,
CI.getFileSystemOpts(), false);
if (!Unit)
continue;

View File

@ -458,7 +458,7 @@ namespace {
/// a Preprocessor.
class ASTInfoCollector : public ASTReaderListener {
Preprocessor &PP;
ASTContext &Context;
ASTContext *Context;
HeaderSearchOptions &HSOpts;
PreprocessorOptions &PPOpts;
LangOptions &LangOpt;
@ -468,7 +468,7 @@ class ASTInfoCollector : public ASTReaderListener {
bool InitializedLanguage;
public:
ASTInfoCollector(Preprocessor &PP, ASTContext &Context,
ASTInfoCollector(Preprocessor &PP, ASTContext *Context,
HeaderSearchOptions &HSOpts, PreprocessorOptions &PPOpts,
LangOptions &LangOpt,
std::shared_ptr<TargetOptions> &TargetOpts,
@ -536,12 +536,15 @@ class ASTInfoCollector : public ASTReaderListener {
// Initialize the preprocessor.
PP.Initialize(*Target);
if (!Context)
return;
// Initialize the ASTContext
Context.InitBuiltinTypes(*Target);
Context->InitBuiltinTypes(*Target);
// We didn't have access to the comment options when the ASTContext was
// constructed, so register them now.
Context.getCommentCommandTraits().registerCommentOptions(
Context->getCommentCommandTraits().registerCommentOptions(
LangOpt.CommentOpts);
}
};
@ -671,7 +674,7 @@ void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
const std::string &Filename, const PCHContainerReader &PCHContainerRdr,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
const FileSystemOptions &FileSystemOpts, bool UseDebugInfo,
bool OnlyLocalDecls, ArrayRef<RemappedFile> RemappedFiles,
bool CaptureDiagnostics, bool AllowPCHWithCompilerErrors,
@ -722,21 +725,21 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
/*OwnsHeaderSearch=*/false);
Preprocessor &PP = *AST->PP;
AST->Ctx = new ASTContext(*AST->LangOpts, AST->getSourceManager(),
PP.getIdentifierTable(), PP.getSelectorTable(),
PP.getBuiltinInfo());
ASTContext &Context = *AST->Ctx;
if (ToLoad >= LoadASTOnly)
AST->Ctx = new ASTContext(*AST->LangOpts, AST->getSourceManager(),
PP.getIdentifierTable(), PP.getSelectorTable(),
PP.getBuiltinInfo());
bool disableValid = false;
if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
disableValid = true;
AST->Reader = new ASTReader(PP, Context, PCHContainerRdr, { },
AST->Reader = new ASTReader(PP, AST->Ctx.get(), PCHContainerRdr, { },
/*isysroot=*/"",
/*DisableValidation=*/disableValid,
AllowPCHWithCompilerErrors);
AST->Reader->setListener(llvm::make_unique<ASTInfoCollector>(
*AST->PP, Context, *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
*AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
AST->TargetOpts, AST->Target, Counter));
// Attach the AST reader to the AST context as an external AST
@ -744,7 +747,8 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
// AST file as needed.
// We need the external source to be set up before we read the AST, because
// eagerly-deserialized declarations may use it.
Context.setExternalSource(AST->Reader);
if (AST->Ctx)
AST->Ctx->setExternalSource(AST->Reader);
switch (AST->Reader->ReadAST(Filename, serialization::MK_MainFile,
SourceLocation(), ASTReader::ARR_None)) {
@ -766,15 +770,18 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
PP.setCounterValue(Counter);
// Create an AST consumer, even though it isn't used.
AST->Consumer.reset(new ASTConsumer);
if (ToLoad >= LoadASTOnly)
AST->Consumer.reset(new ASTConsumer);
// Create a semantic analysis object and tell the AST reader about it.
AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer));
AST->TheSema->Initialize();
AST->Reader->InitializeSema(*AST->TheSema);
if (ToLoad >= LoadEverything) {
AST->TheSema.reset(new Sema(PP, *AST->Ctx, *AST->Consumer));
AST->TheSema->Initialize();
AST->Reader->InitializeSema(*AST->TheSema);
}
// Tell the diagnostic client that we have started a source file.
AST->getDiagnostics().getClient()->BeginSourceFile(Context.getLangOpts(),&PP);
AST->getDiagnostics().getClient()->BeginSourceFile(PP.getLangOpts(), &PP);
return AST;
}
@ -1638,7 +1645,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
&StoredDiagnostics, nullptr);
CI = clang::createInvocationFromCommandLine(
llvm::makeArrayRef(ArgBegin, ArgEnd), Diags);
llvm::makeArrayRef(ArgBegin, ArgEnd), Diags, VFS);
if (!CI)
return nullptr;
}

View File

@ -83,7 +83,7 @@ createASTReader(CompilerInstance &CI, StringRef pchFile,
ASTDeserializationListener *deserialListener = nullptr) {
Preprocessor &PP = CI.getPreprocessor();
std::unique_ptr<ASTReader> Reader;
Reader.reset(new ASTReader(PP, CI.getASTContext(),
Reader.reset(new ASTReader(PP, &CI.getASTContext(),
CI.getPCHContainerReader(),
/*Extensions=*/{ },
/*isysroot=*/"", /*DisableValidation=*/true));

View File

@ -517,7 +517,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader(
PP, Context, PCHContainerRdr, Extensions,
PP, &Context, PCHContainerRdr, Extensions,
Sysroot.empty() ? "" : Sysroot.data(), DisablePCHValidation,
AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false,
HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex));
@ -825,8 +825,11 @@ bool CompilerInstance::InitializeSourceManager(
const FrontendInputFile &Input, DiagnosticsEngine &Diags,
FileManager &FileMgr, SourceManager &SourceMgr, HeaderSearch *HS,
DependencyOutputOptions &DepOpts, const FrontendOptions &Opts) {
SrcMgr::CharacteristicKind
Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
SrcMgr::CharacteristicKind Kind =
Input.getKind().getFormat() == InputKind::ModuleMap
? Input.isSystem() ? SrcMgr::C_System_ModuleMap
: SrcMgr::C_User_ModuleMap
: Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
if (Input.isBuffer()) {
SourceMgr.setMainFileID(SourceMgr.createFileID(
@ -933,8 +936,9 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
if (!hasTarget())
return false;
// Create TargetInfo for the other side of CUDA compilation.
if (getLangOpts().CUDA && !getFrontendOpts().AuxTriple.empty()) {
// Create TargetInfo for the other side of CUDA and OpenMP compilation.
if ((getLangOpts().CUDA || getLangOpts().OpenMPIsDevice) &&
!getFrontendOpts().AuxTriple.empty()) {
auto TO = std::make_shared<TargetOptions>();
TO->Triple = getFrontendOpts().AuxTriple;
TO->HostTriple = getTarget().getTriple().str();
@ -1469,7 +1473,7 @@ void CompilerInstance::createModuleManager() {
"Reading modules",
*FrontendTimerGroup);
ModuleManager = new ASTReader(
getPreprocessor(), getASTContext(), getPCHContainerReader(),
getPreprocessor(), &getASTContext(), getPCHContainerReader(),
getFrontendOpts().ModuleFileExtensions,
Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation,
/*AllowASTWithCompilerErrors=*/false,

View File

@ -476,6 +476,10 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
OPT_fexperimental_new_pass_manager, OPT_fno_experimental_new_pass_manager,
/* Default */ false);
Opts.DebugPassManager =
Args.hasFlag(OPT_fdebug_pass_manager, OPT_fno_debug_pass_manager,
/* Default */ false);
if (Arg *A = Args.getLastArg(OPT_fveclib)) {
StringRef Name = A->getValue();
if (Name == "Accelerate")
@ -668,7 +672,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.MSVolatile = Args.hasArg(OPT_fms_volatile);
Opts.VectorizeBB = Args.hasArg(OPT_vectorize_slp_aggressive);
Opts.VectorizeLoop = Args.hasArg(OPT_vectorize_loops);
Opts.VectorizeSLP = Args.hasArg(OPT_vectorize_slp);
@ -906,12 +909,18 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.DiagnosticsWithHotness =
Args.hasArg(options::OPT_fdiagnostics_show_hotness);
bool UsingSampleProfile = !Opts.SampleProfileFile.empty();
bool UsingProfile = UsingSampleProfile ||
(Opts.getProfileUse() != CodeGenOptions::ProfileNone);
if (Opts.DiagnosticsWithHotness &&
Opts.getProfileUse() == CodeGenOptions::ProfileNone &&
!UsingSampleProfile) {
Diags.Report(diag::warn_drv_fdiagnostics_show_hotness_requires_pgo);
}
if (Opts.DiagnosticsWithHotness && !UsingProfile)
Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
<< "-fdiagnostics-show-hotness";
Opts.DiagnosticsHotnessThreshold = getLastArgUInt64Value(
Args, options::OPT_fdiagnostics_hotness_threshold_EQ, 0);
if (Opts.DiagnosticsHotnessThreshold > 0 && !UsingProfile)
Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
<< "-fdiagnostics-hotness-threshold=";
// If the user requested to use a sample profile for PGO, then the
// backend will need to track source location information so the profile
@ -2106,6 +2115,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.AlignedAllocation =
Args.hasFlag(OPT_faligned_allocation, OPT_fno_aligned_allocation,
Opts.AlignedAllocation);
Opts.AlignedAllocationUnavailable =
Opts.AlignedAllocation && Args.hasArg(OPT_aligned_alloc_unavailable);
Opts.NewAlignOverride =
getLastArgIntValue(Args, OPT_fnew_alignment_EQ, 0, Diags);
if (Opts.NewAlignOverride && !llvm::isPowerOf2_32(Opts.NewAlignOverride)) {
@ -2557,7 +2568,7 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
<< Value;
else
Opts.EABIVersion = Value;
Opts.EABIVersion = EABIVersion;
}
Opts.CPU = Args.getLastArgValue(OPT_target_cpu);
Opts.FPMath = Args.getLastArgValue(OPT_mfpmath);
@ -2644,6 +2655,10 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
}
// Set the triple of the host for OpenMP device compile.
if (LangOpts.OpenMPIsDevice)
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
// FIXME: Override value name discarding when asan or msan is used because the
// backend passes depend on the name of the alloca in order to print out
// names.

View File

@ -31,8 +31,8 @@ using namespace llvm::opt;
/// \return A CompilerInvocation, or 0 if none was built for the given
/// argument vector.
std::unique_ptr<CompilerInvocation> clang::createInvocationFromCommandLine(
ArrayRef<const char *> ArgList,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags) {
ArrayRef<const char *> ArgList, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
if (!Diags.get()) {
// No diagnostics engine was provided, so create our own diagnostics object
// with the default options.
@ -46,7 +46,7 @@ std::unique_ptr<CompilerInvocation> clang::createInvocationFromCommandLine(
// FIXME: We shouldn't have to pass in the path info.
driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(),
*Diags);
*Diags, VFS);
// Don't check that inputs exist, they may have been remapped.
TheDriver.setCheckInputsExist(false);

View File

@ -55,8 +55,8 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
llvm::sys::path::remove_leading_dotslash(FE->getName());
DepCollector.maybeAddDependency(Filename, /*FromModule*/false,
FileType != SrcMgr::C_User,
/*IsModuleFile*/false, /*IsMissing*/false);
isSystem(FileType),
/*IsModuleFile*/false, /*IsMissing*/false);
}
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
@ -265,7 +265,7 @@ bool DFGImpl::FileMatchesDepCriteria(const char *Filename,
if (IncludeSystemHeaders)
return true;
return FileType == SrcMgr::C_User;
return !isSystem(FileType);
}
void DFGImpl::FileChanged(SourceLocation Loc,

View File

@ -76,20 +76,19 @@ static void mergeFixits(ArrayRef<FixItHint> FixItHints,
}
}
void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
void DiagnosticRenderer::emitDiagnostic(FullSourceLoc Loc,
DiagnosticsEngine::Level Level,
StringRef Message,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> FixItHints,
const SourceManager *SM,
DiagOrStoredDiag D) {
assert(SM || Loc.isInvalid());
assert(Loc.hasManager() || Loc.isInvalid());
beginDiagnostic(D, Level);
if (!Loc.isValid())
// If we have no source location, just emit the diagnostic message.
emitDiagnosticMessage(Loc, PresumedLoc(), Level, Message, Ranges, SM, D);
emitDiagnosticMessage(Loc, PresumedLoc(), Level, Message, Ranges, D);
else {
// Get the ranges into a local array we can hack on.
SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(),
@ -97,7 +96,7 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
SmallVector<FixItHint, 8> MergedFixits;
if (!FixItHints.empty()) {
mergeFixits(FixItHints, *SM, LangOpts, MergedFixits);
mergeFixits(FixItHints, Loc.getManager(), LangOpts, MergedFixits);
FixItHints = MergedFixits;
}
@ -107,25 +106,25 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
if (I->RemoveRange.isValid())
MutableRanges.push_back(I->RemoveRange);
SourceLocation UnexpandedLoc = Loc;
FullSourceLoc UnexpandedLoc = Loc;
// Find the ultimate expansion location for the diagnostic.
Loc = SM->getFileLoc(Loc);
Loc = Loc.getFileLoc();
PresumedLoc PLoc = SM->getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc);
PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
// First, if this diagnostic is not in the main file, print out the
// "included from" lines.
emitIncludeStack(Loc, PLoc, Level, *SM);
emitIncludeStack(Loc, PLoc, Level);
// Next, emit the actual diagnostic message and caret.
emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, SM, D);
emitCaret(Loc, Level, MutableRanges, FixItHints, *SM);
emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, D);
emitCaret(Loc, Level, MutableRanges, FixItHints);
// If this location is within a macro, walk from UnexpandedLoc up to Loc
// and produce a macro backtrace.
if (UnexpandedLoc.isValid() && UnexpandedLoc.isMacroID()) {
emitMacroExpansions(UnexpandedLoc, Level, MutableRanges, FixItHints, *SM);
emitMacroExpansions(UnexpandedLoc, Level, MutableRanges, FixItHints);
}
}
@ -139,15 +138,12 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) {
emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(),
Diag.getRanges(), Diag.getFixIts(),
Diag.getLocation().isValid() ? &Diag.getLocation().getManager()
: nullptr,
&Diag);
}
void DiagnosticRenderer::emitBasicNote(StringRef Message) {
emitDiagnosticMessage(
SourceLocation(), PresumedLoc(), DiagnosticsEngine::Note, Message,
None, nullptr, DiagOrStoredDiag());
emitDiagnosticMessage(FullSourceLoc(), PresumedLoc(), DiagnosticsEngine::Note,
Message, None, DiagOrStoredDiag());
}
/// \brief Prints an include stack when appropriate for a particular
@ -161,12 +157,11 @@ void DiagnosticRenderer::emitBasicNote(StringRef Message) {
/// \param Loc The diagnostic location.
/// \param PLoc The presumed location of the diagnostic location.
/// \param Level The diagnostic level of the message this stack pertains to.
void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc,
PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
const SourceManager &SM) {
SourceLocation IncludeLoc =
PLoc.isInvalid() ? SourceLocation() : PLoc.getIncludeLoc();
void DiagnosticRenderer::emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level) {
FullSourceLoc IncludeLoc =
PLoc.isInvalid() ? FullSourceLoc()
: FullSourceLoc(PLoc.getIncludeLoc(), Loc.getManager());
// Skip redundant include stacks altogether.
if (LastIncludeLoc == IncludeLoc)
@ -178,74 +173,70 @@ void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc,
return;
if (IncludeLoc.isValid())
emitIncludeStackRecursively(IncludeLoc, SM);
emitIncludeStackRecursively(IncludeLoc);
else {
emitModuleBuildStack(SM);
emitImportStack(Loc, SM);
emitModuleBuildStack(Loc.getManager());
emitImportStack(Loc);
}
}
/// \brief Helper to recursivly walk up the include stack and print each layer
/// on the way back down.
void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc,
const SourceManager &SM) {
void DiagnosticRenderer::emitIncludeStackRecursively(FullSourceLoc Loc) {
if (Loc.isInvalid()) {
emitModuleBuildStack(SM);
emitModuleBuildStack(Loc.getManager());
return;
}
PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc);
PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
if (PLoc.isInvalid())
return;
// If this source location was imported from a module, print the module
// import stack rather than the
// FIXME: We want submodule granularity here.
std::pair<SourceLocation, StringRef> Imported = SM.getModuleImportLoc(Loc);
std::pair<FullSourceLoc, StringRef> Imported = Loc.getModuleImportLoc();
if (!Imported.second.empty()) {
// This location was imported by a module. Emit the module import stack.
emitImportStackRecursively(Imported.first, Imported.second, SM);
emitImportStackRecursively(Imported.first, Imported.second);
return;
}
// Emit the other include frames first.
emitIncludeStackRecursively(PLoc.getIncludeLoc(), SM);
emitIncludeStackRecursively(
FullSourceLoc(PLoc.getIncludeLoc(), Loc.getManager()));
// Emit the inclusion text/note.
emitIncludeLocation(Loc, PLoc, SM);
emitIncludeLocation(Loc, PLoc);
}
/// \brief Emit the module import stack associated with the current location.
void DiagnosticRenderer::emitImportStack(SourceLocation Loc,
const SourceManager &SM) {
void DiagnosticRenderer::emitImportStack(FullSourceLoc Loc) {
if (Loc.isInvalid()) {
emitModuleBuildStack(SM);
emitModuleBuildStack(Loc.getManager());
return;
}
std::pair<SourceLocation, StringRef> NextImportLoc
= SM.getModuleImportLoc(Loc);
emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM);
std::pair<FullSourceLoc, StringRef> NextImportLoc = Loc.getModuleImportLoc();
emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second);
}
/// \brief Helper to recursivly walk up the import stack and print each layer
/// on the way back down.
void DiagnosticRenderer::emitImportStackRecursively(SourceLocation Loc,
StringRef ModuleName,
const SourceManager &SM) {
void DiagnosticRenderer::emitImportStackRecursively(FullSourceLoc Loc,
StringRef ModuleName) {
if (ModuleName.empty()) {
return;
}
PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc);
PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
// Emit the other import frames first.
std::pair<SourceLocation, StringRef> NextImportLoc
= SM.getModuleImportLoc(Loc);
emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM);
std::pair<FullSourceLoc, StringRef> NextImportLoc = Loc.getModuleImportLoc();
emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second);
// Emit the inclusion text/note.
emitImportLocation(Loc, PLoc, ModuleName, SM);
emitImportLocation(Loc, PLoc, ModuleName);
}
/// \brief Emit the module build stack, for cases where a module is (re-)built
@ -253,13 +244,9 @@ void DiagnosticRenderer::emitImportStackRecursively(SourceLocation Loc,
void DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) {
ModuleBuildStack Stack = SM.getModuleBuildStack();
for (unsigned I = 0, N = Stack.size(); I != N; ++I) {
const SourceManager &CurSM = Stack[I].second.getManager();
SourceLocation CurLoc = Stack[I].second;
emitBuildingModuleLocation(CurLoc,
CurSM.getPresumedLoc(CurLoc,
emitBuildingModuleLocation(Stack[I].second, Stack[I].second.getPresumedLoc(
DiagOpts->ShowPresumedLoc),
Stack[I].first,
CurSM);
Stack[I].first);
}
}
@ -348,12 +335,12 @@ static void computeCommonMacroArgExpansionFileIDs(
// in the same expansion as the caret; otherwise, we crawl to the top of
// each chain. Two locations are part of the same macro expansion
// iff the FileID is the same.
static void mapDiagnosticRanges(
SourceLocation CaretLoc,
ArrayRef<CharSourceRange> Ranges,
SmallVectorImpl<CharSourceRange> &SpellingRanges,
const SourceManager *SM) {
FileID CaretLocFileID = SM->getFileID(CaretLoc);
static void
mapDiagnosticRanges(FullSourceLoc CaretLoc, ArrayRef<CharSourceRange> Ranges,
SmallVectorImpl<CharSourceRange> &SpellingRanges) {
FileID CaretLocFileID = CaretLoc.getFileID();
const SourceManager *SM = &CaretLoc.getManager();
for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
if (I->isInvalid()) continue;
@ -404,42 +391,39 @@ static void mapDiagnosticRanges(
}
}
void DiagnosticRenderer::emitCaret(SourceLocation Loc,
void DiagnosticRenderer::emitCaret(FullSourceLoc Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) {
ArrayRef<FixItHint> Hints) {
SmallVector<CharSourceRange, 4> SpellingRanges;
mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
emitCodeContext(Loc, Level, SpellingRanges, Hints, SM);
mapDiagnosticRanges(Loc, Ranges, SpellingRanges);
emitCodeContext(Loc, Level, SpellingRanges, Hints);
}
/// \brief A helper function for emitMacroExpansion to print the
/// macro expansion message
void DiagnosticRenderer::emitSingleMacroExpansion(
SourceLocation Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) {
FullSourceLoc Loc, DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges) {
// Find the spelling location for the macro definition. We must use the
// spelling location here to avoid emitting a macro backtrace for the note.
SourceLocation SpellingLoc = SM.getSpellingLoc(Loc);
FullSourceLoc SpellingLoc = Loc.getSpellingLoc();
// Map the ranges into the FileID of the diagnostic location.
SmallVector<CharSourceRange, 4> SpellingRanges;
mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
mapDiagnosticRanges(Loc, Ranges, SpellingRanges);
SmallString<100> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
StringRef MacroName =
Lexer::getImmediateMacroNameForDiagnostics(Loc, SM, LangOpts);
StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics(
Loc, Loc.getManager(), LangOpts);
if (MacroName.empty())
Message << "expanded from here";
else
Message << "expanded from macro '" << MacroName << "'";
emitDiagnostic(SpellingLoc, DiagnosticsEngine::Note, Message.str(),
SpellingRanges, None, &SM);
SpellingRanges, None);
}
/// Check that the macro argument location of Loc starts with ArgumentLoc.
@ -473,13 +457,12 @@ static bool checkRangeForMacroArgExpansion(CharSourceRange Range,
/// A helper function to check if the current ranges are all inside the same
/// macro argument expansion as Loc.
static bool checkRangesForMacroArgExpansion(SourceLocation Loc,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) {
static bool checkRangesForMacroArgExpansion(FullSourceLoc Loc,
ArrayRef<CharSourceRange> Ranges) {
assert(Loc.isMacroID() && "Must be a macro expansion!");
SmallVector<CharSourceRange, 4> SpellingRanges;
mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
mapDiagnosticRanges(Loc, Ranges, SpellingRanges);
/// Count all valid ranges.
unsigned ValidCount = 0;
@ -490,15 +473,15 @@ static bool checkRangesForMacroArgExpansion(SourceLocation Loc,
return false;
/// To store the source location of the argument location.
SourceLocation ArgumentLoc;
FullSourceLoc ArgumentLoc;
/// Set the ArgumentLoc to the beginning location of the expansion of Loc
/// so to check if the ranges expands to the same beginning location.
if (!SM.isMacroArgExpansion(Loc,&ArgumentLoc))
if (!Loc.isMacroArgExpansion(&ArgumentLoc))
return false;
for (auto I = SpellingRanges.begin(), E = SpellingRanges.end(); I != E; ++I) {
if (!checkRangeForMacroArgExpansion(*I, SM, ArgumentLoc))
if (!checkRangeForMacroArgExpansion(*I, Loc.getManager(), ArgumentLoc))
return false;
}
@ -516,34 +499,33 @@ static bool checkRangesForMacroArgExpansion(SourceLocation Loc,
/// \param Level The diagnostic level currently being emitted.
/// \param Ranges The underlined ranges for this code snippet.
/// \param Hints The FixIt hints active for this diagnostic.
void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc,
void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) {
ArrayRef<FixItHint> Hints) {
assert(Loc.isValid() && "must have a valid source location here");
// Produce a stack of macro backtraces.
SmallVector<SourceLocation, 8> LocationStack;
SmallVector<FullSourceLoc, 8> LocationStack;
unsigned IgnoredEnd = 0;
while (Loc.isMacroID()) {
// If this is the expansion of a macro argument, point the caret at the
// use of the argument in the definition of the macro, not the expansion.
if (SM.isMacroArgExpansion(Loc))
LocationStack.push_back(SM.getImmediateExpansionRange(Loc).first);
if (Loc.isMacroArgExpansion())
LocationStack.push_back(Loc.getImmediateExpansionRange().first);
else
LocationStack.push_back(Loc);
if (checkRangesForMacroArgExpansion(Loc, Ranges, SM))
if (checkRangesForMacroArgExpansion(Loc, Ranges))
IgnoredEnd = LocationStack.size();
Loc = SM.getImmediateMacroCallerLoc(Loc);
Loc = Loc.getImmediateMacroCallerLoc();
// Once the location no longer points into a macro, try stepping through
// the last found location. This sometimes produces additional useful
// backtraces.
if (Loc.isFileID())
Loc = SM.getImmediateMacroCallerLoc(LocationStack.back());
Loc = LocationStack.back().getImmediateMacroCallerLoc();
assert(Loc.isValid() && "must have a valid source location here");
}
@ -555,7 +537,7 @@ void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc,
if (MacroDepth <= MacroLimit || MacroLimit == 0) {
for (auto I = LocationStack.rbegin(), E = LocationStack.rend();
I != E; ++I)
emitSingleMacroExpansion(*I, Level, Ranges, SM);
emitSingleMacroExpansion(*I, Level, Ranges);
return;
}
@ -565,7 +547,7 @@ void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc,
for (auto I = LocationStack.rbegin(),
E = LocationStack.rbegin() + MacroStartMessages;
I != E; ++I)
emitSingleMacroExpansion(*I, Level, Ranges, SM);
emitSingleMacroExpansion(*I, Level, Ranges);
SmallString<200> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
@ -577,26 +559,24 @@ void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc,
for (auto I = LocationStack.rend() - MacroEndMessages,
E = LocationStack.rend();
I != E; ++I)
emitSingleMacroExpansion(*I, Level, Ranges, SM);
emitSingleMacroExpansion(*I, Level, Ranges);
}
DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {}
void DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc,
PresumedLoc PLoc,
const SourceManager &SM) {
void DiagnosticNoteRenderer::emitIncludeLocation(FullSourceLoc Loc,
PresumedLoc PLoc) {
// Generate a note indicating the include location.
SmallString<200> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
Message << "in file included from " << PLoc.getFilename() << ':'
<< PLoc.getLine() << ":";
emitNote(Loc, Message.str(), &SM);
emitNote(Loc, Message.str());
}
void DiagnosticNoteRenderer::emitImportLocation(SourceLocation Loc,
void DiagnosticNoteRenderer::emitImportLocation(FullSourceLoc Loc,
PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) {
StringRef ModuleName) {
// Generate a note indicating the include location.
SmallString<200> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
@ -605,14 +585,12 @@ void DiagnosticNoteRenderer::emitImportLocation(SourceLocation Loc,
Message << "' imported from " << PLoc.getFilename() << ':'
<< PLoc.getLine();
Message << ":";
emitNote(Loc, Message.str(), &SM);
emitNote(Loc, Message.str());
}
void
DiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc,
PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) {
void DiagnosticNoteRenderer::emitBuildingModuleLocation(FullSourceLoc Loc,
PresumedLoc PLoc,
StringRef ModuleName) {
// Generate a note indicating the include location.
SmallString<200> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
@ -621,5 +599,5 @@ DiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc,
<< PLoc.getFilename() << ':' << PLoc.getLine() << ":";
else
Message << "while building module '" << ModuleName << "':";
emitNote(Loc, Message.str(), &SM);
emitNote(Loc, Message.str());
}

View File

@ -200,12 +200,12 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
///
/// \param CI The compiler instance.
/// \param InputFile Populated with the filename from the line marker.
/// \param AddLineNote If \c true, add a line note corresponding to this line
/// directive. Only use this if the directive will not actually be
/// visited by the preprocessor.
/// \param IsModuleMap If \c true, add a line note corresponding to this line
/// directive. (We need to do this because the directive will not be
/// visited by the preprocessor.)
static SourceLocation ReadOriginalFileName(CompilerInstance &CI,
std::string &InputFile,
bool AddLineNote = false) {
bool IsModuleMap = false) {
auto &SourceMgr = CI.getSourceManager();
auto MainFileID = SourceMgr.getMainFileID();
@ -231,7 +231,7 @@ static SourceLocation ReadOriginalFileName(CompilerInstance &CI,
unsigned LineNo;
SourceLocation LineNoLoc = T.getLocation();
if (AddLineNote) {
if (IsModuleMap) {
llvm::SmallString<16> Buffer;
if (Lexer::getSpelling(LineNoLoc, Buffer, SourceMgr, CI.getLangOpts())
.getAsInteger(10, LineNo))
@ -250,10 +250,10 @@ static SourceLocation ReadOriginalFileName(CompilerInstance &CI,
return SourceLocation();
InputFile = Literal.GetString().str();
if (AddLineNote)
if (IsModuleMap)
CI.getSourceManager().AddLineNote(
LineNoLoc, LineNo, SourceMgr.getLineTableFilenameID(InputFile), false,
false, SrcMgr::C_User);
false, SrcMgr::C_User_ModuleMap);
return T.getLocation();
}
@ -403,7 +403,7 @@ static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem,
Offset = 0;
if (IsPreprocessed) {
SourceLocation EndOfLineMarker =
ReadOriginalFileName(CI, PresumedModuleMapFile, /*AddLineNote*/true);
ReadOriginalFileName(CI, PresumedModuleMapFile, /*IsModuleMap*/ true);
if (EndOfLineMarker.isValid())
Offset = CI.getSourceManager().getDecomposedLoc(EndOfLineMarker).second;
}
@ -536,8 +536,8 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
ASTDiags->setClient(Diags->getClient(), /*OwnsClient*/false);
std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
InputFile, CI.getPCHContainerReader(), ASTDiags, CI.getFileSystemOpts(),
CI.getCodeGenOpts().DebugTypeExtRefs);
InputFile, CI.getPCHContainerReader(), ASTUnit::LoadPreprocessorOnly,
ASTDiags, CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs);
if (!AST)
goto failure;
@ -547,27 +547,36 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
CI.getPreprocessorOpts() = AST->getPreprocessorOpts();
CI.getLangOpts() = AST->getLangOpts();
// Preload all the module files loaded transitively by the AST unit.
if (auto ASTReader = AST->getASTReader()) {
auto &MM = ASTReader->getModuleManager();
for (ModuleFile &MF : MM)
if (&MF != &MM.getPrimaryModule())
CI.getFrontendOpts().ModuleFiles.push_back(MF.FileName);
}
// FIXME: Preload module maps loaded by the AST unit.
// Set the shared objects, these are reset when we finish processing the
// file, otherwise the CompilerInstance will happily destroy them.
CI.setFileManager(&AST->getFileManager());
CI.createSourceManager(CI.getFileManager());
CI.getSourceManager().initializeForReplay(AST->getSourceManager());
// Preload all the module files loaded transitively by the AST unit. Also
// load all module map files that were parsed as part of building the AST
// unit.
if (auto ASTReader = AST->getASTReader()) {
auto &MM = ASTReader->getModuleManager();
auto &PrimaryModule = MM.getPrimaryModule();
for (ModuleFile &MF : MM)
if (&MF != &PrimaryModule)
CI.getFrontendOpts().ModuleFiles.push_back(MF.FileName);
ASTReader->visitTopLevelModuleMaps(PrimaryModule,
[&](const FileEntry *FE) {
CI.getFrontendOpts().ModuleMapFiles.push_back(FE->getName());
});
}
// Set up the input file for replay purposes.
auto Kind = AST->getInputKind();
if (Kind.getFormat() == InputKind::ModuleMap) {
Module *ASTModule =
AST->getPreprocessor().getHeaderSearchInfo().lookupModule(
AST->getLangOpts().CurrentModule, /*AllowSearch*/ false);
assert(ASTModule && "module file does not define its own module");
Input = FrontendInputFile(ASTModule->PresumedModuleMapFile, Kind);
} else {
auto &SM = CI.getSourceManager();
@ -590,8 +599,8 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
InputFile, CI.getPCHContainerReader(), Diags, CI.getFileSystemOpts(),
CI.getCodeGenOpts().DebugTypeExtRefs);
InputFile, CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags,
CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs);
if (!AST)
goto failure;

View File

@ -230,7 +230,7 @@ void VerifyPCHAction::ExecuteAction() {
bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
std::unique_ptr<ASTReader> Reader(new ASTReader(
CI.getPreprocessor(), CI.getASTContext(), CI.getPCHContainerReader(),
CI.getPreprocessor(), &CI.getASTContext(), CI.getPCHContainerReader(),
CI.getFrontendOpts().ModuleFileExtensions,
Sysroot.empty() ? "" : Sysroot.c_str(),
/*DisableValidation*/ false,

View File

@ -1043,7 +1043,7 @@ void clang::InitializePreprocessor(
if (InitOpts.UsePredefines) {
// FIXME: This will create multiple definitions for most of the predefined
// macros. This is not the right way to handle this.
if (LangOpts.CUDA && PP.getAuxTargetInfo())
if ((LangOpts.CUDA || LangOpts.OpenMPIsDevice) && PP.getAuxTargetInfo())
InitializePredefinedMacros(*PP.getAuxTargetInfo(), LangOpts, FEOpts,
Builder);

View File

@ -248,7 +248,7 @@ std::error_code ModuleDependencyCollector::copyToRoot(StringRef Src,
// Always map a canonical src path to its real path into the YAML, by doing
// this we map different virtual src paths to the same entry in the VFS
// overlay, which is a way to emulate symlink inside the VFS; this is also
// needed for correctness, not doing that can lead to module redifinition
// needed for correctness, not doing that can lead to module redefinition
// errors.
addFileMapping(VirtualPath, CacheDst);
return std::error_code();

View File

@ -63,27 +63,20 @@ class SDiagsRenderer : public DiagnosticNoteRenderer {
~SDiagsRenderer() override {}
protected:
void emitDiagnosticMessage(SourceLocation Loc,
PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, StringRef Message,
ArrayRef<CharSourceRange> Ranges,
const SourceManager *SM,
DiagOrStoredDiag D) override;
void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
const SourceManager &SM) override {}
ArrayRef<CharSourceRange> Ranges) override {}
void emitNote(SourceLocation Loc, StringRef Message,
const SourceManager *SM) override;
void emitNote(FullSourceLoc Loc, StringRef Message) override;
void emitCodeContext(SourceLocation Loc,
DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) override;
void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints) override;
void beginDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) override;
@ -193,11 +186,8 @@ class SDiagsWriter : public DiagnosticConsumer {
void ExitDiagBlock();
/// \brief Emit a DIAG record.
void EmitDiagnosticMessage(SourceLocation Loc,
PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
const SourceManager *SM,
void EmitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, StringRef Message,
DiagOrStoredDiag D);
/// \brief Emit FIXIT and SOURCE_RANGE records for a diagnostic.
@ -220,16 +210,14 @@ class SDiagsWriter : public DiagnosticConsumer {
/// \brief Emit (lazily) the file string and retrieved the file identifier.
unsigned getEmitFile(const char *Filename);
/// \brief Add SourceLocation information the specified record.
void AddLocToRecord(SourceLocation Loc, const SourceManager *SM,
PresumedLoc PLoc, RecordDataImpl &Record,
unsigned TokSize = 0);
/// \brief Add SourceLocation information the specified record.
void AddLocToRecord(FullSourceLoc Loc, PresumedLoc PLoc,
RecordDataImpl &Record, unsigned TokSize = 0);
/// \brief Add SourceLocation information the specified record.
void AddLocToRecord(SourceLocation Loc, RecordDataImpl &Record,
const SourceManager *SM,
void AddLocToRecord(FullSourceLoc Loc, RecordDataImpl &Record,
unsigned TokSize = 0) {
AddLocToRecord(Loc, SM, SM ? SM->getPresumedLoc(Loc) : PresumedLoc(),
AddLocToRecord(Loc, Loc.hasManager() ? Loc.getPresumedLoc() : PresumedLoc(),
Record, TokSize);
}
@ -350,11 +338,8 @@ static void EmitRecordID(unsigned ID, const char *Name,
Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
}
void SDiagsWriter::AddLocToRecord(SourceLocation Loc,
const SourceManager *SM,
PresumedLoc PLoc,
RecordDataImpl &Record,
unsigned TokSize) {
void SDiagsWriter::AddLocToRecord(FullSourceLoc Loc, PresumedLoc PLoc,
RecordDataImpl &Record, unsigned TokSize) {
if (PLoc.isInvalid()) {
// Emit a "sentinel" location.
Record.push_back((unsigned)0); // File.
@ -367,19 +352,19 @@ void SDiagsWriter::AddLocToRecord(SourceLocation Loc,
Record.push_back(getEmitFile(PLoc.getFilename()));
Record.push_back(PLoc.getLine());
Record.push_back(PLoc.getColumn()+TokSize);
Record.push_back(SM->getFileOffset(Loc));
Record.push_back(Loc.getFileOffset());
}
void SDiagsWriter::AddCharSourceRangeToRecord(CharSourceRange Range,
RecordDataImpl &Record,
const SourceManager &SM) {
AddLocToRecord(Range.getBegin(), Record, &SM);
AddLocToRecord(FullSourceLoc(Range.getBegin(), SM), Record);
unsigned TokSize = 0;
if (Range.isTokenRange())
TokSize = Lexer::MeasureTokenLength(Range.getEnd(),
SM, *LangOpts);
AddLocToRecord(Range.getEnd(), Record, &SM, TokSize);
AddLocToRecord(FullSourceLoc(Range.getEnd(), SM), Record, TokSize);
}
unsigned SDiagsWriter::getEmitFile(const char *FileName){
@ -606,8 +591,8 @@ void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
if (DiagLevel == DiagnosticsEngine::Note)
EnterDiagBlock();
EmitDiagnosticMessage(SourceLocation(), PresumedLoc(), DiagLevel,
State->diagBuf, nullptr, &Info);
EmitDiagnosticMessage(FullSourceLoc(), PresumedLoc(), DiagLevel,
State->diagBuf, &Info);
if (DiagLevel == DiagnosticsEngine::Note)
ExitDiagBlock();
@ -618,12 +603,9 @@ void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
assert(Info.hasSourceManager() && LangOpts &&
"Unexpected diagnostic with valid location outside of a source file");
SDiagsRenderer Renderer(*this, *LangOpts, &*State->DiagOpts);
Renderer.emitDiagnostic(Info.getLocation(), DiagLevel,
State->diagBuf,
Info.getRanges(),
Info.getFixItHints(),
&Info.getSourceManager(),
&Info);
Renderer.emitDiagnostic(
FullSourceLoc(Info.getLocation(), Info.getSourceManager()), DiagLevel,
State->diagBuf, Info.getRanges(), Info.getFixItHints(), &Info);
}
static serialized_diags::Level getStableLevel(DiagnosticsEngine::Level Level) {
@ -641,11 +623,9 @@ static serialized_diags::Level getStableLevel(DiagnosticsEngine::Level Level) {
llvm_unreachable("invalid diagnostic level");
}
void SDiagsWriter::EmitDiagnosticMessage(SourceLocation Loc,
PresumedLoc PLoc,
void SDiagsWriter::EmitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
const SourceManager *SM,
DiagOrStoredDiag D) {
llvm::BitstreamWriter &Stream = State->Stream;
RecordData &Record = State->Record;
@ -655,7 +635,7 @@ void SDiagsWriter::EmitDiagnosticMessage(SourceLocation Loc,
Record.clear();
Record.push_back(RECORD_DIAG);
Record.push_back(getStableLevel(Level));
AddLocToRecord(Loc, SM, PLoc, Record);
AddLocToRecord(Loc, PLoc, Record);
if (const Diagnostic *Info = D.dyn_cast<const Diagnostic*>()) {
// Emit the category string lazily and get the category ID.
@ -672,15 +652,11 @@ void SDiagsWriter::EmitDiagnosticMessage(SourceLocation Loc,
Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_DIAG), Record, Message);
}
void
SDiagsRenderer::emitDiagnosticMessage(SourceLocation Loc,
PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
StringRef Message,
ArrayRef<clang::CharSourceRange> Ranges,
const SourceManager *SM,
DiagOrStoredDiag D) {
Writer.EmitDiagnosticMessage(Loc, PLoc, Level, Message, SM, D);
void SDiagsRenderer::emitDiagnosticMessage(
FullSourceLoc Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level,
StringRef Message, ArrayRef<clang::CharSourceRange> Ranges,
DiagOrStoredDiag D) {
Writer.EmitDiagnosticMessage(Loc, PLoc, Level, Message, D);
}
void SDiagsWriter::EnterDiagBlock() {
@ -733,20 +709,18 @@ void SDiagsWriter::EmitCodeContext(SmallVectorImpl<CharSourceRange> &Ranges,
}
}
void SDiagsRenderer::emitCodeContext(SourceLocation Loc,
void SDiagsRenderer::emitCodeContext(FullSourceLoc Loc,
DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) {
Writer.EmitCodeContext(Ranges, Hints, SM);
ArrayRef<FixItHint> Hints) {
Writer.EmitCodeContext(Ranges, Hints, Loc.getManager());
}
void SDiagsRenderer::emitNote(SourceLocation Loc, StringRef Message,
const SourceManager *SM) {
void SDiagsRenderer::emitNote(FullSourceLoc Loc, StringRef Message) {
Writer.EnterDiagBlock();
PresumedLoc PLoc = SM ? SM->getPresumedLoc(Loc) : PresumedLoc();
Writer.EmitDiagnosticMessage(Loc, PLoc, DiagnosticsEngine::Note,
Message, SM, DiagOrStoredDiag());
PresumedLoc PLoc = Loc.hasManager() ? Loc.getPresumedLoc() : PresumedLoc();
Writer.EmitDiagnosticMessage(Loc, PLoc, DiagnosticsEngine::Note, Message,
DiagOrStoredDiag());
Writer.ExitDiagBlock();
}

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