Vendor import of clang trunk r306956:
https://llvm.org/svn/llvm-project/cfe/trunk@306956
This commit is contained in:
parent
ef915aab0a
commit
cf1b401909
@ -1367,6 +1367,30 @@ TemplateArgumentKind.DECLARATION = TemplateArgumentKind(2)
|
||||
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 @@ class Cursor(Structure):
|
||||
|
||||
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 @@ class Type(Structure):
|
||||
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."""
|
||||
|
27
bindings/python/tests/test_exception_specification_kind.py
Normal file
27
bindings/python/tests/test_exception_specification_kind.py
Normal 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
|
@ -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**
|
||||
|
@ -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.
|
||||
|
@ -2050,6 +2050,11 @@ public:
|
||||
/// 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();
|
||||
|
@ -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);
|
||||
|
@ -2019,7 +2019,10 @@ public:
|
||||
/// 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;
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
NSStr_initWithString,
|
||||
NSStr_initWithUTF8String
|
||||
};
|
||||
static const unsigned NumNSStringMethods = 5;
|
||||
static const unsigned NumNSStringMethods = 6;
|
||||
|
||||
IdentifierInfo *getNSClassId(NSClassIdKindKind K) const;
|
||||
|
||||
@ -112,7 +112,7 @@ public:
|
||||
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;
|
||||
|
@ -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 @@ protected:
|
||||
// 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();
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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)``.
|
||||
}];
|
||||
}
|
||||
|
||||
|
70
include/clang/Basic/BuiltinsNios2.def
Normal file
70
include/clang/Basic/BuiltinsNios2.def
Normal 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
|
@ -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
|
||||
|
@ -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">;
|
||||
|
@ -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'">;
|
||||
|
@ -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">;
|
||||
|
@ -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<
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -262,6 +262,65 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
|
||||
};
|
||||
|
||||
/// \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
|
||||
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
/// \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 @@ public:
|
||||
/// \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 {
|
||||
|
@ -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 {
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "clang/Basic/OpenCLOptions.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
@ -41,7 +42,7 @@ public:
|
||||
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;
|
||||
|
@ -75,6 +75,9 @@ public:
|
||||
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_; }
|
||||
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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 @@ public:
|
||||
/// 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
|
||||
|
@ -341,7 +341,8 @@ public:
|
||||
|
||||
/// 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.
|
||||
|
@ -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">,
|
||||
|
@ -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
|
||||
|
@ -628,6 +628,15 @@ public:
|
||||
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 @@ public:
|
||||
/// \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,
|
||||
|
@ -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)
|
||||
|
||||
|
@ -70,33 +70,27 @@ protected:
|
||||
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 @@ protected:
|
||||
|
||||
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 @@ public:
|
||||
/// \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 @@ public:
|
||||
|
||||
~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
|
||||
|
@ -75,44 +75,35 @@ public:
|
||||
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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 @@ public:
|
||||
/// 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 @@ public:
|
||||
Paths = nullptr;
|
||||
}
|
||||
} else {
|
||||
AmbiguityKind SavedAK;
|
||||
llvm::Optional<AmbiguityKind> SavedAK;
|
||||
bool WasAmbiguous = false;
|
||||
if (ResultKind == Ambiguous) {
|
||||
SavedAK = Ambiguity;
|
||||
@ -479,7 +481,7 @@ public:
|
||||
if (ResultKind == Ambiguous) {
|
||||
(void)WasAmbiguous;
|
||||
assert(WasAmbiguous);
|
||||
Ambiguity = SavedAK;
|
||||
Ambiguity = SavedAK.getValue();
|
||||
} else if (Paths) {
|
||||
deletePaths(Paths);
|
||||
Paths = nullptr;
|
||||
|
@ -1542,6 +1542,10 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
//
|
||||
|
||||
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 @@ public:
|
||||
};
|
||||
|
||||
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 @@ public:
|
||||
/// 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 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
/// 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 @@ private:
|
||||
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
|
||||
|
@ -400,7 +400,7 @@ private:
|
||||
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 @@ private:
|
||||
time_t StoredTime;
|
||||
bool Overridden;
|
||||
bool Transient;
|
||||
bool TopLevelModuleMap;
|
||||
};
|
||||
|
||||
/// \brief Reads the stored information about an input file.
|
||||
@ -1386,7 +1387,7 @@ public:
|
||||
/// 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 @@ public:
|
||||
///
|
||||
/// \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 @@ public:
|
||||
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 @@ public:
|
||||
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; }
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
70
include/clang/Tooling/Refactoring/Rename/RenamingAction.h
Normal file
70
include/clang/Tooling/Refactoring/Rename/RenamingAction.h
Normal 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
|
84
include/clang/Tooling/Refactoring/Rename/USRFinder.h
Normal file
84
include/clang/Tooling/Refactoring/Rename/USRFinder.h
Normal 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
|
54
include/clang/Tooling/Refactoring/Rename/USRFindingAction.h
Normal file
54
include/clang/Tooling/Refactoring/Rename/USRFindingAction.h
Normal 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
|
49
include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
Normal file
49
include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
Normal 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
|
@ -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"
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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&'.
|
||||
|
@ -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 {
|
||||
|
@ -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)) &&
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -186,7 +186,10 @@ namespace {
|
||||
Hash.AddTemplateName(Name);
|
||||
}
|
||||
void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) override {
|
||||
Hash.AddNestedNameSpecifier(NNS);
|
||||
ID.AddBoolean(NNS);
|
||||
if (NNS) {
|
||||
Hash.AddNestedNameSpecifier(NNS);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
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 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
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:
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -5603,7 +5603,7 @@ public:
|
||||
// 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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -384,6 +384,14 @@ protected:
|
||||
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;
|
||||
|
@ -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");
|
||||
|
@ -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 {
|
||||
|
@ -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 @@ public:
|
||||
: 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 @@ private:
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -174,7 +174,7 @@ tooling::Replacements NamespaceEndCommentsFixer::analyze(
|
||||
AllNamespaceNames = "::" + NamespaceName + AllNamespaceNames;
|
||||
continue;
|
||||
}
|
||||
NamespaceName += std::move(AllNamespaceNames);
|
||||
NamespaceName += AllNamespaceNames;
|
||||
CompactedNamespacesCount = 0;
|
||||
AllNamespaceNames = std::string();
|
||||
}
|
||||
|
@ -89,7 +89,8 @@ private:
|
||||
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 @@ private:
|
||||
!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 @@ private:
|
||||
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 @@ private:
|
||||
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))
|
||||
|
@ -136,10 +136,7 @@ private:
|
||||
|
||||
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 @@ private:
|
||||
|
||||
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 =
|
||||
|
@ -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
|
||||
|
@ -93,7 +93,8 @@ private:
|
||||
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();
|
||||
|
@ -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;
|
||||
|
@ -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 @@ private:
|
||||
// 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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -63,27 +63,20 @@ public:
|
||||
~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 @@ private:
|
||||
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 @@ private:
|
||||
/// \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
Loading…
x
Reference in New Issue
Block a user