forked from OSchip/llvm-project
Revert "Implement _ExtInt as an extended int type specifier."
This reverts commit 61ba1481e2
.
I'm reverting this because it breaks the lldb build with
incomplete switch coverage warnings. I would fix it forward,
but am not familiar enough with lldb to determine the correct
fix.
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:3958:11: error: enumeration values 'DependentExtInt' and 'ExtInt' not handled in switch [-Werror,-Wswitch]
switch (qual_type->getTypeClass()) {
^
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:4633:11: error: enumeration values 'DependentExtInt' and 'ExtInt' not handled in switch [-Werror,-Wswitch]
switch (qual_type->getTypeClass()) {
^
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:4889:11: error: enumeration values 'DependentExtInt' and 'ExtInt' not handled in switch [-Werror,-Wswitch]
switch (qual_type->getTypeClass()) {
This commit is contained in:
parent
5793c84925
commit
a4b88c0449
|
@ -3461,56 +3461,3 @@ Since the size of ``buffer`` can't be known at compile time, Clang will fold
|
|||
``__builtin_object_size(buffer, 0)`` into ``-1``. However, if this was written
|
||||
as ``__builtin_dynamic_object_size(buffer, 0)``, Clang will fold it into
|
||||
``size``, providing some extra runtime safety.
|
||||
|
||||
Extended Integer Types
|
||||
======================
|
||||
|
||||
Clang supports a set of extended integer types under the syntax ``_ExtInt(N)``
|
||||
where ``N`` is an integer that specifies the number of bits that are used to represent
|
||||
the type, including the sign bit. The keyword ``_ExtInt`` is a type specifier, thus
|
||||
it can be used in any place a type can, including as a non-type-template-parameter,
|
||||
as the type of a bitfield, and as the underlying type of an enumeration.
|
||||
|
||||
An extended integer can be declared either signed, or unsigned by using the
|
||||
``signed``/``unsigned`` keywords. If no sign specifier is used or if the ``signed``
|
||||
keyword is used, the extended integer type is a signed integer and can represent
|
||||
negative values.
|
||||
|
||||
The ``N`` expression is an integer constant expression, which specifies the number
|
||||
of bits used to represent the type, following normal integer representations for
|
||||
both signed and unsigned types. Both a signed and unsigned extended integer of the
|
||||
same ``N`` value will have the same number of bits in its representation. Many
|
||||
architectures don't have a way of representing non power-of-2 integers, so these
|
||||
architectures emulate these types using larger integers. In these cases, they are
|
||||
expected to follow the 'as-if' rule and do math 'as-if' they were done at the
|
||||
specified number of bits.
|
||||
|
||||
In order to be consistent with the C language specification, and make the extended
|
||||
integer types useful for their intended purpose, extended integers follow the C
|
||||
standard integer conversion ranks. An extended integer type has a greater rank than
|
||||
any integer type with less precision. However, they have lower rank than any
|
||||
of the built in or other integer types (such as __int128). Usual arithmetic conversions
|
||||
also work the same, where the smaller ranked integer is converted to the larger.
|
||||
|
||||
The one exception to the C rules for integers for these types is Integer Promotion.
|
||||
Unary +, -, and ~ operators typically will promote operands to ``int``. Doing these
|
||||
promotions would inflate the size of required hardware on some platforms, so extended
|
||||
integer types aren't subject to the integer promotion rules in these cases.
|
||||
|
||||
In languages (such as OpenCL) that define shift by-out-of-range behavior as a mask,
|
||||
non-power-of-two versions of these types use an unsigned remainder operation to constrain
|
||||
the value to the proper range, preventing undefined behavior.
|
||||
|
||||
Extended integer types are aligned to the next greatest power-of-2 up to 64 bits.
|
||||
The size of these types for the purposes of layout and ``sizeof`` are the number of
|
||||
bits aligned to this calculated alignment. This permits the use of these types in
|
||||
allocated arrays using common ``sizeof(Array)/sizeof(ElementType)`` pattern.
|
||||
|
||||
Extended integer types work with the C _Atomic type modifier, however only precisions
|
||||
that are powers-of-2 greater than 8 bit are accepted.
|
||||
|
||||
Extended integer types align with existing calling conventions. They have the same size
|
||||
and alignment as the smallest basic type that can contain them. Types that are larger
|
||||
than 64 bits are handled in the same way as _int128 is handled; they are conceptually
|
||||
treated as struct of register size chunks. They number of chunks are the smallest
|
||||
number that can contain the types which does not necessarily mean a power-of-2 size.
|
||||
|
|
|
@ -62,14 +62,6 @@ Non-comprehensive list of changes in this release
|
|||
in the Arm C Language Extensions.
|
||||
|
||||
|
||||
* clang adds support for a set of extended integer types (``_ExtInt(N)``) that
|
||||
permit non-power of 2 integers, exposing the LLVM integer types. Since a major
|
||||
motivating use case for these types is to limit 'bit' usage, these types don't
|
||||
automatically promote to 'int' when operations are done between two ``ExtInt(N)``
|
||||
types, instead math occurs at the size of the largest ``ExtInt(N)`` type.
|
||||
|
||||
|
||||
|
||||
New Compiler Flags
|
||||
------------------
|
||||
|
||||
|
|
|
@ -224,8 +224,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
|||
mutable llvm::FoldingSet<AtomicType> AtomicTypes;
|
||||
llvm::FoldingSet<AttributedType> AttributedTypes;
|
||||
mutable llvm::FoldingSet<PipeType> PipeTypes;
|
||||
mutable llvm::FoldingSet<ExtIntType> ExtIntTypes;
|
||||
mutable llvm::FoldingSet<DependentExtIntType> DependentExtIntTypes;
|
||||
|
||||
mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
|
||||
mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
|
||||
|
@ -1205,14 +1203,6 @@ public:
|
|||
/// Return a write_only pipe type for the specified type.
|
||||
QualType getWritePipeType(QualType T) const;
|
||||
|
||||
/// Return an extended integer type with the specified signedness and bit
|
||||
/// count.
|
||||
QualType getExtIntType(bool Unsigned, unsigned NumBits) const;
|
||||
|
||||
/// Return a dependent extended integer type with the specified signedness and
|
||||
/// bit count.
|
||||
QualType getDependentExtIntType(bool Unsigned, Expr *BitsExpr) const;
|
||||
|
||||
/// Gets the struct used to keep track of the extended descriptor for
|
||||
/// pointer to blocks.
|
||||
QualType getBlockDescriptorExtendedType() const;
|
||||
|
|
|
@ -1115,10 +1115,6 @@ DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
|
|||
|
||||
DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
|
||||
|
||||
DEF_TRAVERSE_TYPE(ExtIntType, {})
|
||||
DEF_TRAVERSE_TYPE(DependentExtIntType,
|
||||
{ TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
|
||||
|
||||
#undef DEF_TRAVERSE_TYPE
|
||||
|
||||
// ----------------- TypeLoc traversal -----------------
|
||||
|
@ -1389,11 +1385,6 @@ DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
|
|||
|
||||
DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
|
||||
|
||||
DEF_TRAVERSE_TYPELOC(ExtIntType, {})
|
||||
DEF_TRAVERSE_TYPELOC(DependentExtIntType, {
|
||||
TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
|
||||
})
|
||||
|
||||
#undef DEF_TRAVERSE_TYPELOC
|
||||
|
||||
// ----------------- Decl traversal -----------------
|
||||
|
|
|
@ -2101,7 +2101,6 @@ public:
|
|||
bool isOCLExtOpaqueType() const; // Any OpenCL extension type
|
||||
|
||||
bool isPipeType() const; // OpenCL pipe type
|
||||
bool isExtIntType() const; // Extended Int Type
|
||||
bool isOpenCLSpecificType() const; // Any OpenCL specific type
|
||||
|
||||
/// Determines if this type, which must satisfy
|
||||
|
@ -6128,64 +6127,6 @@ public:
|
|||
bool isReadOnly() const { return isRead; }
|
||||
};
|
||||
|
||||
/// A fixed int type of a specified bitwidth.
|
||||
class ExtIntType final : public Type, public llvm::FoldingSetNode {
|
||||
friend class ASTContext;
|
||||
unsigned IsUnsigned : 1;
|
||||
unsigned NumBits : 24;
|
||||
|
||||
protected:
|
||||
ExtIntType(bool isUnsigned, unsigned NumBits);
|
||||
|
||||
public:
|
||||
bool isUnsigned() const { return IsUnsigned; }
|
||||
bool isSigned() const { return !IsUnsigned; }
|
||||
unsigned getNumBits() const { return NumBits; }
|
||||
|
||||
bool isSugared() const { return false; }
|
||||
QualType desugar() const { return QualType(this, 0); }
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, isUnsigned(), getNumBits());
|
||||
}
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, bool IsUnsigned,
|
||||
unsigned NumBits) {
|
||||
ID.AddBoolean(IsUnsigned);
|
||||
ID.AddInteger(NumBits);
|
||||
}
|
||||
|
||||
static bool classof(const Type *T) { return T->getTypeClass() == ExtInt; }
|
||||
};
|
||||
|
||||
class DependentExtIntType final : public Type, public llvm::FoldingSetNode {
|
||||
friend class ASTContext;
|
||||
const ASTContext &Context;
|
||||
llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned;
|
||||
|
||||
protected:
|
||||
DependentExtIntType(const ASTContext &Context, bool IsUnsigned,
|
||||
Expr *NumBits);
|
||||
|
||||
public:
|
||||
bool isUnsigned() const;
|
||||
bool isSigned() const { return !isUnsigned(); }
|
||||
Expr *getNumBitsExpr() const;
|
||||
|
||||
bool isSugared() const { return false; }
|
||||
QualType desugar() const { return QualType(this, 0); }
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, Context, isUnsigned(), getNumBitsExpr());
|
||||
}
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
|
||||
bool IsUnsigned, Expr *NumBitsExpr);
|
||||
|
||||
static bool classof(const Type *T) {
|
||||
return T->getTypeClass() == DependentExtInt;
|
||||
}
|
||||
};
|
||||
|
||||
/// A qualifier set is used to build a set of qualifiers.
|
||||
class QualifierCollector : public Qualifiers {
|
||||
public:
|
||||
|
@ -6705,10 +6646,6 @@ inline bool Type::isPipeType() const {
|
|||
return isa<PipeType>(CanonicalType);
|
||||
}
|
||||
|
||||
inline bool Type::isExtIntType() const {
|
||||
return isa<ExtIntType>(CanonicalType);
|
||||
}
|
||||
|
||||
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
|
||||
inline bool Type::is##Id##Type() const { \
|
||||
return isSpecificBuiltinType(BuiltinType::Id); \
|
||||
|
@ -6804,7 +6741,7 @@ inline bool Type::isIntegerType() const {
|
|||
return IsEnumDeclComplete(ET->getDecl()) &&
|
||||
!IsEnumDeclScoped(ET->getDecl());
|
||||
}
|
||||
return isExtIntType();
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool Type::isFixedPointType() const {
|
||||
|
@ -6861,8 +6798,7 @@ inline bool Type::isScalarType() const {
|
|||
isa<BlockPointerType>(CanonicalType) ||
|
||||
isa<MemberPointerType>(CanonicalType) ||
|
||||
isa<ComplexType>(CanonicalType) ||
|
||||
isa<ObjCObjectPointerType>(CanonicalType) ||
|
||||
isExtIntType();
|
||||
isa<ObjCObjectPointerType>(CanonicalType);
|
||||
}
|
||||
|
||||
inline bool Type::isIntegralOrEnumerationType() const {
|
||||
|
@ -6875,7 +6811,7 @@ inline bool Type::isIntegralOrEnumerationType() const {
|
|||
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
return IsEnumDeclComplete(ET->getDecl());
|
||||
|
||||
return isExtIntType();
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool Type::isBooleanType() const {
|
||||
|
|
|
@ -2450,12 +2450,6 @@ inline T TypeLoc::getAsAdjusted() const {
|
|||
}
|
||||
return Cur.getAs<T>();
|
||||
}
|
||||
class ExtIntTypeLoc final
|
||||
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc, ExtIntTypeLoc,
|
||||
ExtIntType> {};
|
||||
class DependentExtIntTypeLoc final
|
||||
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentExtIntTypeLoc,
|
||||
DependentExtIntType> {};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
|
|
|
@ -833,28 +833,3 @@ let Class = PipeType in {
|
|||
return ctx.getPipeType(elementType, isReadOnly);
|
||||
}]>;
|
||||
}
|
||||
|
||||
let Class = ExtIntType in {
|
||||
def : Property<"isUnsigned", Bool> {
|
||||
let Read = [{ node->isUnsigned() }];
|
||||
}
|
||||
def : Property <"numBits", UInt32> {
|
||||
let Read = [{ node->getNumBits() }];
|
||||
}
|
||||
|
||||
def : Creator<[{
|
||||
return ctx.getExtIntType(isUnsigned, numBits);
|
||||
}]>;
|
||||
}
|
||||
|
||||
let Class = DependentExtIntType in {
|
||||
def : Property<"isUnsigned", Bool> {
|
||||
let Read = [{ node->isUnsigned() }];
|
||||
}
|
||||
def : Property <"numBitsExpr", ExprRef> {
|
||||
let Read = [{ node->getNumBitsExpr() }];
|
||||
}
|
||||
def : Creator<[{
|
||||
return ctx.getDependentExtIntType(isUnsigned, numBitsExpr);
|
||||
}]>;
|
||||
}
|
||||
|
|
|
@ -5947,12 +5947,10 @@ def err_block_return_missing_expr : Error<
|
|||
"non-void block should return a value">;
|
||||
def err_func_def_incomplete_result : Error<
|
||||
"incomplete result type %0 in function definition">;
|
||||
def err_atomic_specifier_bad_type
|
||||
: Error<"_Atomic cannot be applied to "
|
||||
"%select{incomplete |array |function |reference |atomic |qualified "
|
||||
"|sizeless ||integer |integer }0type "
|
||||
"%1 %select{|||||||which is not trivially copyable|with less than "
|
||||
"1 byte of precision|with a non power of 2 precision}0">;
|
||||
def err_atomic_specifier_bad_type : Error<
|
||||
"_Atomic cannot be applied to "
|
||||
"%select{incomplete |array |function |reference |atomic |qualified |sizeless |}0type "
|
||||
"%1 %select{|||||||which is not trivially copyable}0">;
|
||||
|
||||
// Expressions.
|
||||
def select_unary_expr_or_type_trait_kind : TextSubstitution<
|
||||
|
@ -10713,8 +10711,4 @@ def warn_sycl_kernel_return_type : Warning<
|
|||
"function template with 'sycl_kernel' attribute must have a 'void' return type">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
|
||||
def err_ext_int_bad_size : Error<"%select{signed|unsigned}0 _ExtInt must "
|
||||
"have a bit size of at least %select{2|1}0">;
|
||||
def err_ext_int_max_size : Error<"%select{signed|unsigned}0 _ExtInt of bit "
|
||||
"sizes greater than %1 not supported">;
|
||||
} // end of sema component.
|
||||
|
|
|
@ -67,7 +67,6 @@ namespace clang {
|
|||
TST_char32, // C++11 char32_t
|
||||
TST_int,
|
||||
TST_int128,
|
||||
TST_extint, // Extended Int types.
|
||||
TST_half, // OpenCL half, ARM NEON __fp16
|
||||
TST_Float16, // C11 extension ISO/IEC TS 18661-3
|
||||
TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension
|
||||
|
|
|
@ -285,7 +285,6 @@ KEYWORD(goto , KEYALL)
|
|||
KEYWORD(if , KEYALL)
|
||||
KEYWORD(inline , KEYC99|KEYCXX|KEYGNU)
|
||||
KEYWORD(int , KEYALL)
|
||||
KEYWORD(_ExtInt , KEYALL)
|
||||
KEYWORD(long , KEYALL)
|
||||
KEYWORD(register , KEYALL)
|
||||
KEYWORD(restrict , KEYC99)
|
||||
|
|
|
@ -104,5 +104,3 @@ def ObjCInterfaceType : TypeNode<ObjCObjectType>, LeafType;
|
|||
def ObjCObjectPointerType : TypeNode<Type>;
|
||||
def PipeType : TypeNode<Type>;
|
||||
def AtomicType : TypeNode<Type>;
|
||||
def ExtIntType : TypeNode<Type>;
|
||||
def DependentExtIntType : TypeNode<Type>, AlwaysDependent;
|
||||
|
|
|
@ -2721,7 +2721,6 @@ private:
|
|||
SourceLocation &EllipsisLoc);
|
||||
void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
|
||||
SourceLocation *endLoc = nullptr);
|
||||
ExprResult ParseExtIntegerArgument();
|
||||
|
||||
VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const;
|
||||
VirtSpecifiers::Specifier isCXX11VirtSpecifier() const {
|
||||
|
|
|
@ -278,7 +278,6 @@ public:
|
|||
static const TST TST_char32 = clang::TST_char32;
|
||||
static const TST TST_int = clang::TST_int;
|
||||
static const TST TST_int128 = clang::TST_int128;
|
||||
static const TST TST_extint = clang::TST_extint;
|
||||
static const TST TST_half = clang::TST_half;
|
||||
static const TST TST_float = clang::TST_float;
|
||||
static const TST TST_double = clang::TST_double;
|
||||
|
@ -414,7 +413,7 @@ private:
|
|||
T == TST_underlyingType || T == TST_atomic);
|
||||
}
|
||||
static bool isExprRep(TST T) {
|
||||
return (T == TST_typeofExpr || T == TST_decltype || T == TST_extint);
|
||||
return (T == TST_typeofExpr || T == TST_decltype);
|
||||
}
|
||||
static bool isTemplateIdRep(TST T) {
|
||||
return (T == TST_auto || T == TST_decltype_auto);
|
||||
|
@ -705,9 +704,6 @@ public:
|
|||
bool SetTypePipe(bool isPipe, SourceLocation Loc,
|
||||
const char *&PrevSpec, unsigned &DiagID,
|
||||
const PrintingPolicy &Policy);
|
||||
bool SetExtIntType(SourceLocation KWLoc, Expr *BitWidth,
|
||||
const char *&PrevSpec, unsigned &DiagID,
|
||||
const PrintingPolicy &Policy);
|
||||
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec,
|
||||
unsigned &DiagID);
|
||||
bool SetTypeSpecError();
|
||||
|
|
|
@ -1678,7 +1678,6 @@ public:
|
|||
SourceLocation Loc);
|
||||
QualType BuildWritePipeType(QualType T,
|
||||
SourceLocation Loc);
|
||||
QualType BuildExtIntType(bool IsUnsigned, Expr *BitWidth, SourceLocation Loc);
|
||||
|
||||
TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S);
|
||||
TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy);
|
||||
|
|
|
@ -58,7 +58,5 @@ TYPE_BIT_CODE(DependentSizedExtVector, DEPENDENT_SIZED_EXT_VECTOR, 46)
|
|||
TYPE_BIT_CODE(DependentAddressSpace, DEPENDENT_ADDRESS_SPACE, 47)
|
||||
TYPE_BIT_CODE(DependentVector, DEPENDENT_SIZED_VECTOR, 48)
|
||||
TYPE_BIT_CODE(MacroQualified, MACRO_QUALIFIED, 49)
|
||||
TYPE_BIT_CODE(ExtInt, EXT_INT, 50)
|
||||
TYPE_BIT_CODE(DependentExtInt, DEPENDENT_EXT_INT, 51)
|
||||
|
||||
#undef TYPE_BIT_CODE
|
||||
|
|
|
@ -2180,15 +2180,6 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
|
|||
Align = toBits(Layout.getAlignment());
|
||||
break;
|
||||
}
|
||||
case Type::ExtInt: {
|
||||
const auto *EIT = cast<ExtIntType>(T);
|
||||
Align =
|
||||
std::min(static_cast<unsigned>(std::max(
|
||||
getCharWidth(), llvm::PowerOf2Ceil(EIT->getNumBits()))),
|
||||
Target->getLongLongAlign());
|
||||
Width = llvm::alignTo(EIT->getNumBits(), Align);
|
||||
break;
|
||||
}
|
||||
case Type::Record:
|
||||
case Type::Enum: {
|
||||
const auto *TT = cast<TagType>(T);
|
||||
|
@ -3385,8 +3376,6 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
|
|||
case Type::Auto:
|
||||
case Type::DeducedTemplateSpecialization:
|
||||
case Type::PackExpansion:
|
||||
case Type::ExtInt:
|
||||
case Type::DependentExtInt:
|
||||
llvm_unreachable("type should never be variably-modified");
|
||||
|
||||
// These types can be variably-modified but should never need to
|
||||
|
@ -4081,39 +4070,6 @@ QualType ASTContext::getWritePipeType(QualType T) const {
|
|||
return getPipeType(T, false);
|
||||
}
|
||||
|
||||
QualType ASTContext::getExtIntType(bool IsUnsigned, unsigned NumBits) const {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
ExtIntType::Profile(ID, IsUnsigned, NumBits);
|
||||
|
||||
void *InsertPos = nullptr;
|
||||
if (ExtIntType *EIT = ExtIntTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||
return QualType(EIT, 0);
|
||||
|
||||
auto *New = new (*this, TypeAlignment) ExtIntType(IsUnsigned, NumBits);
|
||||
ExtIntTypes.InsertNode(New, InsertPos);
|
||||
Types.push_back(New);
|
||||
return QualType(New, 0);
|
||||
}
|
||||
|
||||
QualType ASTContext::getDependentExtIntType(bool IsUnsigned,
|
||||
Expr *NumBitsExpr) const {
|
||||
assert(NumBitsExpr->isInstantiationDependent() && "Only good for dependent");
|
||||
llvm::FoldingSetNodeID ID;
|
||||
DependentExtIntType::Profile(ID, *this, IsUnsigned, NumBitsExpr);
|
||||
|
||||
void *InsertPos = nullptr;
|
||||
if (DependentExtIntType *Existing =
|
||||
DependentExtIntTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||
return QualType(Existing, 0);
|
||||
|
||||
auto *New = new (*this, TypeAlignment)
|
||||
DependentExtIntType(*this, IsUnsigned, NumBitsExpr);
|
||||
DependentExtIntTypes.InsertNode(New, InsertPos);
|
||||
|
||||
Types.push_back(New);
|
||||
return QualType(New, 0);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
static bool NeedsInjectedClassNameType(const RecordDecl *D) {
|
||||
if (!isa<CXXRecordDecl>(D)) return false;
|
||||
|
@ -5949,11 +5905,6 @@ int ASTContext::getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const {
|
|||
unsigned ASTContext::getIntegerRank(const Type *T) const {
|
||||
assert(T->isCanonicalUnqualified() && "T should be canonicalized");
|
||||
|
||||
// Results in this 'losing' to any type of the same size, but winning if
|
||||
// larger.
|
||||
if (const auto *EIT = dyn_cast<ExtIntType>(T))
|
||||
return 0 + (EIT->getNumBits() << 3);
|
||||
|
||||
switch (cast<BuiltinType>(T)->getKind()) {
|
||||
default: llvm_unreachable("getIntegerRank(): not a built-in integer");
|
||||
case BuiltinType::Bool:
|
||||
|
@ -7337,7 +7288,6 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
|
|||
return;
|
||||
|
||||
case Type::Pipe:
|
||||
case Type::ExtInt:
|
||||
#define ABSTRACT_TYPE(KIND, BASE)
|
||||
#define TYPE(KIND, BASE)
|
||||
#define DEPENDENT_TYPE(KIND, BASE) \
|
||||
|
@ -9431,21 +9381,6 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
|
|||
assert(LHS != RHS &&
|
||||
"Equivalent pipe types should have already been handled!");
|
||||
return {};
|
||||
case Type::ExtInt: {
|
||||
// Merge two ext-int types, while trying to preserve typedef info.
|
||||
bool LHSUnsigned = LHS->castAs<ExtIntType>()->isUnsigned();
|
||||
bool RHSUnsigned = RHS->castAs<ExtIntType>()->isUnsigned();
|
||||
unsigned LHSBits = LHS->castAs<ExtIntType>()->getNumBits();
|
||||
unsigned RHSBits = RHS->castAs<ExtIntType>()->getNumBits();
|
||||
|
||||
// Like unsigned/int, shouldn't have a type if they dont match.
|
||||
if (LHSUnsigned != RHSUnsigned)
|
||||
return {};
|
||||
|
||||
if (LHSBits != RHSBits)
|
||||
return {};
|
||||
return LHS;
|
||||
}
|
||||
}
|
||||
|
||||
llvm_unreachable("Invalid Type::Class!");
|
||||
|
@ -9586,8 +9521,6 @@ unsigned ASTContext::getIntWidth(QualType T) const {
|
|||
T = ET->getDecl()->getIntegerType();
|
||||
if (T->isBooleanType())
|
||||
return 1;
|
||||
if(const auto *EIT = T->getAs<ExtIntType>())
|
||||
return EIT->getNumBits();
|
||||
// For builtin types, just use the standard type sizing method
|
||||
return (unsigned)getTypeSize(T);
|
||||
}
|
||||
|
|
|
@ -949,24 +949,6 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
|||
cast<PipeType>(T2)->getElementType()))
|
||||
return false;
|
||||
break;
|
||||
case Type::ExtInt: {
|
||||
const auto *Int1 = cast<ExtIntType>(T1);
|
||||
const auto *Int2 = cast<ExtIntType>(T2);
|
||||
|
||||
if (Int1->isUnsigned() != Int2->isUnsigned() ||
|
||||
Int1->getNumBits() != Int2->getNumBits())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case Type::DependentExtInt: {
|
||||
const auto *Int1 = cast<DependentExtIntType>(T1);
|
||||
const auto *Int2 = cast<DependentExtIntType>(T2);
|
||||
|
||||
if (Int1->isUnsigned() != Int2->isUnsigned() ||
|
||||
!IsStructurallyEquivalent(Context, Int1->getNumBitsExpr(),
|
||||
Int2->getNumBitsExpr()))
|
||||
return false;
|
||||
}
|
||||
} // end switch
|
||||
|
||||
return true;
|
||||
|
|
|
@ -10354,7 +10354,6 @@ EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts) {
|
|||
case Type::ObjCInterface:
|
||||
case Type::ObjCObjectPointer:
|
||||
case Type::Pipe:
|
||||
case Type::ExtInt:
|
||||
// GCC classifies vectors as None. We follow its lead and classify all
|
||||
// other types that don't fit into the regular classification the same way.
|
||||
return GCCTypeClass::None;
|
||||
|
|
|
@ -2093,8 +2093,6 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
|
|||
case Type::Atomic:
|
||||
case Type::Pipe:
|
||||
case Type::MacroQualified:
|
||||
case Type::ExtInt:
|
||||
case Type::DependentExtInt:
|
||||
llvm_unreachable("type is illegal as a nested name specifier");
|
||||
|
||||
case Type::SubstTemplateTypeParmPack:
|
||||
|
@ -3553,28 +3551,6 @@ void CXXNameMangler::mangleType(const PipeType *T) {
|
|||
Out << "8ocl_pipe";
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleType(const ExtIntType *T) {
|
||||
Out << "U7_ExtInt";
|
||||
llvm::APSInt BW(32, true);
|
||||
BW = T->getNumBits();
|
||||
TemplateArgument TA(Context.getASTContext(), BW, getASTContext().IntTy);
|
||||
mangleTemplateArgs(&TA, 1);
|
||||
if (T->isUnsigned())
|
||||
Out << "j";
|
||||
else
|
||||
Out << "i";
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleType(const DependentExtIntType *T) {
|
||||
Out << "U7_ExtInt";
|
||||
TemplateArgument TA(T->getNumBitsExpr());
|
||||
mangleTemplateArgs(&TA, 1);
|
||||
if (T->isUnsigned())
|
||||
Out << "j";
|
||||
else
|
||||
Out << "i";
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleIntegerLiteral(QualType T,
|
||||
const llvm::APSInt &Value) {
|
||||
// <expr-primary> ::= L <type> <value number> E # integer literal
|
||||
|
|
|
@ -2953,30 +2953,6 @@ void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
|
|||
return Mangler.mangle(D);
|
||||
}
|
||||
|
||||
void MicrosoftCXXNameMangler::mangleType(const ExtIntType *T, Qualifiers,
|
||||
SourceRange Range) {
|
||||
llvm::SmallString<64> TemplateMangling;
|
||||
llvm::raw_svector_ostream Stream(TemplateMangling);
|
||||
MicrosoftCXXNameMangler Extra(Context, Stream);
|
||||
Stream << "?$";
|
||||
if (T->isUnsigned())
|
||||
Extra.mangleSourceName("_UExtInt");
|
||||
else
|
||||
Extra.mangleSourceName("_ExtInt");
|
||||
Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()),
|
||||
/*IsBoolean=*/false);
|
||||
|
||||
mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"});
|
||||
}
|
||||
|
||||
void MicrosoftCXXNameMangler::mangleType(const DependentExtIntType *T,
|
||||
Qualifiers, SourceRange Range) {
|
||||
DiagnosticsEngine &Diags = Context.getDiags();
|
||||
unsigned DiagID = Diags.getCustomDiagID(
|
||||
DiagnosticsEngine::Error, "cannot mangle this DependentExtInt type yet");
|
||||
Diags.Report(Range.getBegin(), DiagID) << Range;
|
||||
}
|
||||
|
||||
// <this-adjustment> ::= <no-adjustment> | <static-adjustment> |
|
||||
// <virtual-adjustment>
|
||||
// <no-adjustment> ::= A # private near
|
||||
|
|
|
@ -293,39 +293,6 @@ VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements,
|
|||
VectorTypeBits.NumElements = nElements;
|
||||
}
|
||||
|
||||
ExtIntType::ExtIntType(bool IsUnsigned, unsigned NumBits)
|
||||
: Type(ExtInt, QualType{}, TypeDependence::None), IsUnsigned(IsUnsigned),
|
||||
NumBits(NumBits) {}
|
||||
|
||||
DependentExtIntType::DependentExtIntType(const ASTContext &Context,
|
||||
bool IsUnsigned, Expr *NumBitsExpr)
|
||||
: Type(DependentExtInt, QualType{},
|
||||
((NumBitsExpr->isValueDependent() || NumBitsExpr->isTypeDependent())
|
||||
? TypeDependence::Dependent
|
||||
: TypeDependence::None) |
|
||||
(NumBitsExpr->isInstantiationDependent()
|
||||
? TypeDependence::Instantiation
|
||||
: TypeDependence::None) |
|
||||
(NumBitsExpr->containsUnexpandedParameterPack()
|
||||
? TypeDependence::VariablyModified
|
||||
: TypeDependence::None)),
|
||||
Context(Context), ExprAndUnsigned(NumBitsExpr, IsUnsigned) {}
|
||||
|
||||
bool DependentExtIntType::isUnsigned() const {
|
||||
return ExprAndUnsigned.getInt();
|
||||
}
|
||||
|
||||
clang::Expr *DependentExtIntType::getNumBitsExpr() const {
|
||||
return ExprAndUnsigned.getPointer();
|
||||
}
|
||||
|
||||
void DependentExtIntType::Profile(llvm::FoldingSetNodeID &ID,
|
||||
const ASTContext &Context, bool IsUnsigned,
|
||||
Expr *NumBitsExpr) {
|
||||
ID.AddBoolean(IsUnsigned);
|
||||
NumBitsExpr->Profile(ID, Context, true);
|
||||
}
|
||||
|
||||
/// getArrayElementTypeNoTypeQual - If this is an array type, return the
|
||||
/// element type of the array, potentially with type qualifiers missing.
|
||||
/// This method should never be used when type qualifiers are meaningful.
|
||||
|
@ -1869,17 +1836,13 @@ bool Type::isIntegralType(const ASTContext &Ctx) const {
|
|||
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
return ET->getDecl()->isComplete();
|
||||
|
||||
return isExtIntType();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Type::isIntegralOrUnscopedEnumerationType() const {
|
||||
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() >= BuiltinType::Bool &&
|
||||
BT->getKind() <= BuiltinType::Int128;
|
||||
|
||||
if (isExtIntType())
|
||||
return true;
|
||||
|
||||
return isUnscopedEnumerationType();
|
||||
}
|
||||
|
||||
|
@ -1960,9 +1923,6 @@ bool Type::isSignedIntegerType() const {
|
|||
return ET->getDecl()->getIntegerType()->isSignedIntegerType();
|
||||
}
|
||||
|
||||
if (const ExtIntType *IT = dyn_cast<ExtIntType>(CanonicalType))
|
||||
return IT->isSigned();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1977,10 +1937,6 @@ bool Type::isSignedIntegerOrEnumerationType() const {
|
|||
return ET->getDecl()->getIntegerType()->isSignedIntegerType();
|
||||
}
|
||||
|
||||
if (const ExtIntType *IT = dyn_cast<ExtIntType>(CanonicalType))
|
||||
return IT->isSigned();
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2007,9 +1963,6 @@ bool Type::isUnsignedIntegerType() const {
|
|||
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
|
||||
}
|
||||
|
||||
if (const ExtIntType *IT = dyn_cast<ExtIntType>(CanonicalType))
|
||||
return IT->isUnsigned();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2024,9 +1977,6 @@ bool Type::isUnsignedIntegerOrEnumerationType() const {
|
|||
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
|
||||
}
|
||||
|
||||
if (const ExtIntType *IT = dyn_cast<ExtIntType>(CanonicalType))
|
||||
return IT->isUnsigned();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2065,7 +2015,7 @@ bool Type::isRealType() const {
|
|||
BT->getKind() <= BuiltinType::Float128;
|
||||
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
|
||||
return isExtIntType();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Type::isArithmeticType() const {
|
||||
|
@ -2080,7 +2030,7 @@ bool Type::isArithmeticType() const {
|
|||
// false for scoped enumerations since that will disable any
|
||||
// unwanted implicit conversions.
|
||||
return !ET->getDecl()->isScoped() && ET->getDecl()->isComplete();
|
||||
return isa<ComplexType>(CanonicalType) || isExtIntType();
|
||||
return isa<ComplexType>(CanonicalType);
|
||||
}
|
||||
|
||||
Type::ScalarTypeKind Type::getScalarTypeKind() const {
|
||||
|
@ -2109,8 +2059,6 @@ Type::ScalarTypeKind Type::getScalarTypeKind() const {
|
|||
if (CT->getElementType()->isRealFloatingType())
|
||||
return STK_FloatingComplex;
|
||||
return STK_IntegralComplex;
|
||||
} else if (isExtIntType()) {
|
||||
return STK_Integral;
|
||||
}
|
||||
|
||||
llvm_unreachable("unknown scalar type");
|
||||
|
@ -2276,7 +2224,6 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const {
|
|||
case Type::MemberPointer:
|
||||
case Type::Vector:
|
||||
case Type::ExtVector:
|
||||
case Type::ExtInt:
|
||||
return true;
|
||||
|
||||
case Type::Enum:
|
||||
|
@ -3696,7 +3643,6 @@ static CachedProperties computeCachedProperties(const Type *T) {
|
|||
// here in error recovery.
|
||||
return CachedProperties(ExternalLinkage, false);
|
||||
|
||||
case Type::ExtInt:
|
||||
case Type::Builtin:
|
||||
// C++ [basic.link]p8:
|
||||
// A type is said to have linkage if and only if:
|
||||
|
@ -3794,7 +3740,6 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
|
|||
assert(T->isInstantiationDependentType());
|
||||
return LinkageInfo::external();
|
||||
|
||||
case Type::ExtInt:
|
||||
case Type::Builtin:
|
||||
return LinkageInfo::external();
|
||||
|
||||
|
@ -4003,8 +3948,6 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
|
|||
case Type::ObjCInterface:
|
||||
case Type::Atomic:
|
||||
case Type::Pipe:
|
||||
case Type::ExtInt:
|
||||
case Type::DependentExtInt:
|
||||
return false;
|
||||
}
|
||||
llvm_unreachable("bad type kind!");
|
||||
|
|
|
@ -227,8 +227,6 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
|
|||
case Type::ObjCInterface:
|
||||
case Type::Atomic:
|
||||
case Type::Pipe:
|
||||
case Type::ExtInt:
|
||||
case Type::DependentExtInt:
|
||||
CanPrefixQualifiers = true;
|
||||
break;
|
||||
|
||||
|
@ -1116,28 +1114,6 @@ void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
|
|||
|
||||
void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
|
||||
|
||||
void TypePrinter::printExtIntBefore(const ExtIntType *T, raw_ostream &OS) {
|
||||
if (T->isUnsigned())
|
||||
OS << "unsigned ";
|
||||
OS << "_ExtInt(" << T->getNumBits() << ")";
|
||||
spaceBeforePlaceHolder(OS);
|
||||
}
|
||||
|
||||
void TypePrinter::printExtIntAfter(const ExtIntType *T, raw_ostream &OS) {}
|
||||
|
||||
void TypePrinter::printDependentExtIntBefore(const DependentExtIntType *T,
|
||||
raw_ostream &OS) {
|
||||
if (T->isUnsigned())
|
||||
OS << "unsigned ";
|
||||
OS << "_ExtInt(";
|
||||
T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
|
||||
OS << ")";
|
||||
spaceBeforePlaceHolder(OS);
|
||||
}
|
||||
|
||||
void TypePrinter::printDependentExtIntAfter(const DependentExtIntType *T,
|
||||
raw_ostream &OS) {}
|
||||
|
||||
/// Appends the given scope to the end of a string.
|
||||
void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) {
|
||||
if (DC->isTranslationUnit()) return;
|
||||
|
|
|
@ -826,17 +826,6 @@ llvm::DIType *CGDebugInfo::CreateType(const AutoType *Ty) {
|
|||
return DBuilder.createUnspecifiedType("auto");
|
||||
}
|
||||
|
||||
llvm::DIType *CGDebugInfo::CreateType(const ExtIntType *Ty) {
|
||||
|
||||
StringRef Name = Ty->isUnsigned() ? "unsigned _ExtInt" : "_ExtInt";
|
||||
llvm::dwarf::TypeKind Encoding = Ty->isUnsigned()
|
||||
? llvm::dwarf::DW_ATE_unsigned
|
||||
: llvm::dwarf::DW_ATE_signed;
|
||||
|
||||
return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
|
||||
Encoding);
|
||||
}
|
||||
|
||||
llvm::DIType *CGDebugInfo::CreateType(const ComplexType *Ty) {
|
||||
// Bit size and offset of the type.
|
||||
llvm::dwarf::TypeKind Encoding = llvm::dwarf::DW_ATE_complex_float;
|
||||
|
@ -3170,8 +3159,6 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
|
|||
case Type::Atomic:
|
||||
return CreateType(cast<AtomicType>(Ty), Unit);
|
||||
|
||||
case Type::ExtInt:
|
||||
return CreateType(cast<ExtIntType>(Ty));
|
||||
case Type::Pipe:
|
||||
return CreateType(cast<PipeType>(Ty), Unit);
|
||||
|
||||
|
|
|
@ -168,7 +168,6 @@ class CGDebugInfo {
|
|||
llvm::DIType *CreateType(const BuiltinType *Ty);
|
||||
llvm::DIType *CreateType(const ComplexType *Ty);
|
||||
llvm::DIType *CreateType(const AutoType *Ty);
|
||||
llvm::DIType *CreateType(const ExtIntType *Ty);
|
||||
llvm::DIType *CreateQualifiedType(QualType Ty, llvm::DIFile *Fg);
|
||||
llvm::DIType *CreateType(const TypedefType *Ty, llvm::DIFile *Fg);
|
||||
llvm::DIType *CreateType(const TemplateSpecializationType *Ty,
|
||||
|
|
|
@ -760,11 +760,6 @@ public:
|
|||
llvm::Value *Zero,bool isDiv);
|
||||
// Common helper for getting how wide LHS of shift is.
|
||||
static Value *GetWidthMinusOneValue(Value* LHS,Value* RHS);
|
||||
|
||||
// Used for shifting constraints for OpenCL, do mask for powers of 2, URem for
|
||||
// non powers of two.
|
||||
Value *ConstrainShiftValue(Value *LHS, Value *RHS, const Twine &Name);
|
||||
|
||||
Value *EmitDiv(const BinOpInfo &Ops);
|
||||
Value *EmitRem(const BinOpInfo &Ops);
|
||||
Value *EmitAdd(const BinOpInfo &Ops);
|
||||
|
@ -3767,21 +3762,6 @@ Value *ScalarExprEmitter::GetWidthMinusOneValue(Value* LHS,Value* RHS) {
|
|||
return llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth() - 1);
|
||||
}
|
||||
|
||||
Value *ScalarExprEmitter::ConstrainShiftValue(Value *LHS, Value *RHS,
|
||||
const Twine &Name) {
|
||||
llvm::IntegerType *Ty;
|
||||
if (auto *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
|
||||
Ty = cast<llvm::IntegerType>(VT->getElementType());
|
||||
else
|
||||
Ty = cast<llvm::IntegerType>(LHS->getType());
|
||||
|
||||
if (llvm::isPowerOf2_64(Ty->getBitWidth()))
|
||||
return Builder.CreateAnd(RHS, GetWidthMinusOneValue(LHS, RHS), Name);
|
||||
|
||||
return Builder.CreateURem(
|
||||
RHS, llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth()), Name);
|
||||
}
|
||||
|
||||
Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
|
||||
// LLVM requires the LHS and RHS to be the same type: promote or truncate the
|
||||
// RHS to the same size as the LHS.
|
||||
|
@ -3796,7 +3776,8 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
|
|||
bool SanitizeExponent = CGF.SanOpts.has(SanitizerKind::ShiftExponent);
|
||||
// OpenCL 6.3j: shift values are effectively % word size of LHS.
|
||||
if (CGF.getLangOpts().OpenCL)
|
||||
RHS = ConstrainShiftValue(Ops.LHS, RHS, "shl.mask");
|
||||
RHS =
|
||||
Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS), "shl.mask");
|
||||
else if ((SanitizeBase || SanitizeExponent) &&
|
||||
isa<llvm::IntegerType>(Ops.LHS->getType())) {
|
||||
CodeGenFunction::SanitizerScope SanScope(&CGF);
|
||||
|
@ -3858,7 +3839,8 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
|
|||
|
||||
// OpenCL 6.3j: shift values are effectively % word size of LHS.
|
||||
if (CGF.getLangOpts().OpenCL)
|
||||
RHS = ConstrainShiftValue(Ops.LHS, RHS, "shr.mask");
|
||||
RHS =
|
||||
Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS), "shr.mask");
|
||||
else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) &&
|
||||
isa<llvm::IntegerType>(Ops.LHS->getType())) {
|
||||
CodeGenFunction::SanitizerScope SanScope(&CGF);
|
||||
|
|
|
@ -385,8 +385,7 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
|
|||
Run = FieldEnd;
|
||||
continue;
|
||||
}
|
||||
llvm::Type *Type =
|
||||
Types.ConvertTypeForMem(Field->getType(), /*ForBitFields=*/true);
|
||||
llvm::Type *Type = Types.ConvertTypeForMem(Field->getType());
|
||||
// If we don't have a run yet, or don't live within the previous run's
|
||||
// allocated storage then we allocate some storage and start a new run.
|
||||
if (Run == FieldEnd || BitOffset >= Tail) {
|
||||
|
|
|
@ -257,7 +257,6 @@ TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) {
|
|||
case Type::Enum:
|
||||
case Type::ObjCObjectPointer:
|
||||
case Type::Pipe:
|
||||
case Type::ExtInt:
|
||||
return TEK_Scalar;
|
||||
|
||||
// Complexes.
|
||||
|
@ -2011,7 +2010,6 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
|
|||
case Type::ObjCObject:
|
||||
case Type::ObjCInterface:
|
||||
case Type::ObjCObjectPointer:
|
||||
case Type::ExtInt:
|
||||
llvm_unreachable("type class is never variably-modified!");
|
||||
|
||||
case Type::Adjusted:
|
||||
|
|
|
@ -209,15 +209,6 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
|
|||
return createScalarTypeNode(OutName, getChar(), Size);
|
||||
}
|
||||
|
||||
if (const auto *EIT = dyn_cast<ExtIntType>(Ty)) {
|
||||
SmallString<256> OutName;
|
||||
llvm::raw_svector_ostream Out(OutName);
|
||||
// Don't specify signed/unsigned since integer types can alias despite sign
|
||||
// differences.
|
||||
Out << "_ExtInt(" << EIT->getNumBits() << ')';
|
||||
return createScalarTypeNode(OutName, getChar(), Size);
|
||||
}
|
||||
|
||||
// For now, handle any other kind of type conservatively.
|
||||
return getChar();
|
||||
}
|
||||
|
|
|
@ -83,19 +83,19 @@ void CodeGenTypes::addRecordTypeName(const RecordDecl *RD,
|
|||
/// ConvertType in that it is used to convert to the memory representation for
|
||||
/// a type. For example, the scalar representation for _Bool is i1, but the
|
||||
/// memory representation is usually i8 or i32, depending on the target.
|
||||
llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T, bool ForBitField) {
|
||||
llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) {
|
||||
llvm::Type *R = ConvertType(T);
|
||||
|
||||
// If this is a bool type, or an ExtIntType in a bitfield representation,
|
||||
// map this integer to the target-specified size.
|
||||
if ((ForBitField && T->isExtIntType()) || R->isIntegerTy(1))
|
||||
return llvm::IntegerType::get(getLLVMContext(),
|
||||
(unsigned)Context.getTypeSize(T));
|
||||
// If this is a non-bool type, don't map it.
|
||||
if (!R->isIntegerTy(1))
|
||||
return R;
|
||||
|
||||
// Else, don't map it.
|
||||
return R;
|
||||
// Otherwise, return an integer of the target-specified size.
|
||||
return llvm::IntegerType::get(getLLVMContext(),
|
||||
(unsigned)Context.getTypeSize(T));
|
||||
}
|
||||
|
||||
|
||||
/// isRecordLayoutComplete - Return true if the specified type is already
|
||||
/// completely laid out.
|
||||
bool CodeGenTypes::isRecordLayoutComplete(const Type *Ty) const {
|
||||
|
@ -731,11 +731,6 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
|||
ResultType = CGM.getOpenCLRuntime().getPipeType(cast<PipeType>(Ty));
|
||||
break;
|
||||
}
|
||||
case Type::ExtInt: {
|
||||
const auto &EIT = cast<ExtIntType>(Ty);
|
||||
ResultType = llvm::Type::getIntNTy(getLLVMContext(), EIT->getNumBits());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(ResultType && "Didn't convert a type?");
|
||||
|
|
|
@ -134,7 +134,7 @@ public:
|
|||
/// ConvertType in that it is used to convert to the memory representation for
|
||||
/// a type. For example, the scalar representation for _Bool is i1, but the
|
||||
/// memory representation is usually i8 or i32, depending on the target.
|
||||
llvm::Type *ConvertTypeForMem(QualType T, bool ForBitField = false);
|
||||
llvm::Type *ConvertTypeForMem(QualType T);
|
||||
|
||||
/// GetFunctionType - Get the LLVM function type for \arg Info.
|
||||
llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info);
|
||||
|
|
|
@ -3219,7 +3219,6 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
|
|||
llvm_unreachable("Pipe types shouldn't get here");
|
||||
|
||||
case Type::Builtin:
|
||||
case Type::ExtInt:
|
||||
// GCC treats vector and complex types as fundamental types.
|
||||
case Type::Vector:
|
||||
case Type::ExtVector:
|
||||
|
@ -3473,10 +3472,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
|
|||
llvm_unreachable("Undeduced type shouldn't get here");
|
||||
|
||||
case Type::Pipe:
|
||||
break;
|
||||
|
||||
case Type::ExtInt:
|
||||
break;
|
||||
llvm_unreachable("Pipe type shouldn't get here");
|
||||
|
||||
case Type::ConstantArray:
|
||||
case Type::IncompleteArray:
|
||||
|
|
|
@ -2880,25 +2880,6 @@ void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
|
|||
ParsedAttr::AS_Keyword, EllipsisLoc);
|
||||
}
|
||||
|
||||
ExprResult Parser::ParseExtIntegerArgument() {
|
||||
assert(Tok.is(tok::kw__ExtInt) && "Not an extended int type");
|
||||
ConsumeToken();
|
||||
|
||||
BalancedDelimiterTracker T(*this, tok::l_paren);
|
||||
if (T.expectAndConsume())
|
||||
return ExprError();
|
||||
|
||||
ExprResult ER = ParseConstantExpression();
|
||||
if (ER.isInvalid()) {
|
||||
T.skipToEnd();
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
if(T.consumeClose())
|
||||
return ExprError();
|
||||
return ER;
|
||||
}
|
||||
|
||||
/// Determine whether we're looking at something that might be a declarator
|
||||
/// in a simple-declaration. If it can't possibly be a declarator, maybe
|
||||
/// diagnose a missing semicolon after a prior tag definition in the decl
|
||||
|
@ -3826,14 +3807,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
|
||||
DiagID, Policy);
|
||||
break;
|
||||
case tok::kw__ExtInt: {
|
||||
ExprResult ER = ParseExtIntegerArgument();
|
||||
if (ER.isInvalid())
|
||||
continue;
|
||||
isInvalid = DS.SetExtIntType(Loc, ER.get(), PrevSpec, DiagID, Policy);
|
||||
ConsumedEnd = PrevTokLocation;
|
||||
break;
|
||||
}
|
||||
case tok::kw___int128:
|
||||
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
|
||||
DiagID, Policy);
|
||||
|
@ -4917,7 +4890,6 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
|
|||
case tok::kw_char16_t:
|
||||
case tok::kw_char32_t:
|
||||
case tok::kw_int:
|
||||
case tok::kw__ExtInt:
|
||||
case tok::kw_half:
|
||||
case tok::kw_float:
|
||||
case tok::kw_double:
|
||||
|
@ -4997,7 +4969,6 @@ bool Parser::isTypeSpecifierQualifier() {
|
|||
case tok::kw_char16_t:
|
||||
case tok::kw_char32_t:
|
||||
case tok::kw_int:
|
||||
case tok::kw__ExtInt:
|
||||
case tok::kw_half:
|
||||
case tok::kw_float:
|
||||
case tok::kw_double:
|
||||
|
@ -5164,7 +5135,6 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
|
|||
case tok::kw_char32_t:
|
||||
|
||||
case tok::kw_int:
|
||||
case tok::kw__ExtInt:
|
||||
case tok::kw_half:
|
||||
case tok::kw_float:
|
||||
case tok::kw_double:
|
||||
|
|
|
@ -1492,7 +1492,6 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
|
|||
case tok::kw_long:
|
||||
case tok::kw___int64:
|
||||
case tok::kw___int128:
|
||||
case tok::kw__ExtInt:
|
||||
case tok::kw_signed:
|
||||
case tok::kw_unsigned:
|
||||
case tok::kw_half:
|
||||
|
|
|
@ -2156,19 +2156,6 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
|
|||
return;
|
||||
}
|
||||
|
||||
case tok::kw__ExtInt: {
|
||||
ExprResult ER = ParseExtIntegerArgument();
|
||||
if (ER.isInvalid())
|
||||
DS.SetTypeSpecError();
|
||||
else
|
||||
DS.SetExtIntType(Loc, ER.get(), PrevSpec, DiagID, Policy);
|
||||
|
||||
// Do this here because we have already consumed the close paren.
|
||||
DS.SetRangeEnd(PrevTokLocation);
|
||||
DS.Finish(Actions, Policy);
|
||||
return;
|
||||
}
|
||||
|
||||
// builtin types
|
||||
case tok::kw_short:
|
||||
DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID, Policy);
|
||||
|
|
|
@ -1141,7 +1141,6 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
|
|||
case tok::kw_half:
|
||||
case tok::kw_float:
|
||||
case tok::kw_int:
|
||||
case tok::kw__ExtInt:
|
||||
case tok::kw_long:
|
||||
case tok::kw___int64:
|
||||
case tok::kw___int128:
|
||||
|
@ -1779,24 +1778,6 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
|||
case tok::kw__Atomic:
|
||||
return TPResult::True;
|
||||
|
||||
case tok::kw__ExtInt: {
|
||||
if (NextToken().isNot(tok::l_paren))
|
||||
return TPResult::Error;
|
||||
RevertingTentativeParsingAction PA(*this);
|
||||
ConsumeToken();
|
||||
ConsumeParen();
|
||||
|
||||
if (!SkipUntil(tok::r_paren, StopAtSemi))
|
||||
return TPResult::Error;
|
||||
|
||||
if (Tok.is(tok::l_paren))
|
||||
return TPResult::Ambiguous;
|
||||
|
||||
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))
|
||||
return BracedCastResult;
|
||||
|
||||
return TPResult::True;
|
||||
}
|
||||
default:
|
||||
return TPResult::False;
|
||||
}
|
||||
|
@ -1829,7 +1810,6 @@ bool Parser::isCXXDeclarationSpecifierAType() {
|
|||
case tok::kw_bool:
|
||||
case tok::kw_short:
|
||||
case tok::kw_int:
|
||||
case tok::kw__ExtInt:
|
||||
case tok::kw_long:
|
||||
case tok::kw___int64:
|
||||
case tok::kw___int128:
|
||||
|
|
|
@ -360,7 +360,6 @@ bool Declarator::isDeclarationOfFunction() const {
|
|||
case TST_half:
|
||||
case TST_int:
|
||||
case TST_int128:
|
||||
case TST_extint:
|
||||
case TST_struct:
|
||||
case TST_interface:
|
||||
case TST_union:
|
||||
|
@ -539,7 +538,6 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
|
|||
case DeclSpec::TST_char32: return "char32_t";
|
||||
case DeclSpec::TST_int: return "int";
|
||||
case DeclSpec::TST_int128: return "__int128";
|
||||
case DeclSpec::TST_extint: return "_ExtInt";
|
||||
case DeclSpec::TST_half: return "half";
|
||||
case DeclSpec::TST_float: return "float";
|
||||
case DeclSpec::TST_double: return "double";
|
||||
|
@ -915,27 +913,6 @@ bool DeclSpec::SetTypeSpecError() {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool DeclSpec::SetExtIntType(SourceLocation KWLoc, Expr *BitsExpr,
|
||||
const char *&PrevSpec, unsigned &DiagID,
|
||||
const PrintingPolicy &Policy) {
|
||||
assert(BitsExpr && "no expression provided!");
|
||||
if (TypeSpecType == TST_error)
|
||||
return false;
|
||||
|
||||
if (TypeSpecType != TST_unspecified) {
|
||||
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
|
||||
DiagID = diag::err_invalid_decl_spec_combination;
|
||||
return true;
|
||||
}
|
||||
|
||||
TypeSpecType = TST_extint;
|
||||
ExprRep = BitsExpr;
|
||||
TSTLoc = KWLoc;
|
||||
TSTNameLoc = KWLoc;
|
||||
TypeSpecOwned = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
|
||||
unsigned &DiagID, const LangOptions &Lang) {
|
||||
// Duplicates are permitted in C99 onwards, but are not permitted in C89 or
|
||||
|
@ -1217,7 +1194,7 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
|
|||
TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
|
||||
else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 &&
|
||||
TypeSpecType != TST_char && TypeSpecType != TST_wchar &&
|
||||
!IsFixedPointType && TypeSpecType != TST_extint) {
|
||||
!IsFixedPointType) {
|
||||
S.Diag(TSSLoc, diag::err_invalid_sign_spec)
|
||||
<< getSpecifierName((TST)TypeSpecType, Policy);
|
||||
// signed double -> double.
|
||||
|
@ -1264,8 +1241,7 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
|
|||
S.getLocForEndOfToken(getTypeSpecComplexLoc()),
|
||||
" double");
|
||||
TypeSpecType = TST_double; // _Complex -> _Complex double.
|
||||
} else if (TypeSpecType == TST_int || TypeSpecType == TST_char ||
|
||||
TypeSpecType == TST_extint) {
|
||||
} else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
|
||||
// Note that this intentionally doesn't include _Complex _Bool.
|
||||
if (!S.getLangOpts().CPlusPlus)
|
||||
S.Diag(TSTLoc, diag::ext_integer_complex);
|
||||
|
|
|
@ -9793,9 +9793,6 @@ struct IntRange {
|
|||
false/*NonNegative*/);
|
||||
}
|
||||
|
||||
if (const auto *EIT = dyn_cast<ExtIntType>(T))
|
||||
return IntRange(EIT->getNumBits(), EIT->isUnsigned());
|
||||
|
||||
const BuiltinType *BT = cast<BuiltinType>(T);
|
||||
assert(BT->isInteger());
|
||||
|
||||
|
@ -9819,9 +9816,6 @@ struct IntRange {
|
|||
if (const EnumType *ET = dyn_cast<EnumType>(T))
|
||||
T = C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr();
|
||||
|
||||
if (const auto *EIT = dyn_cast<ExtIntType>(T))
|
||||
return IntRange(EIT->getNumBits(), EIT->isUnsigned());
|
||||
|
||||
const BuiltinType *BT = cast<BuiltinType>(T);
|
||||
assert(BT->isInteger());
|
||||
|
||||
|
|
|
@ -14811,16 +14811,12 @@ bool Sema::CheckEnumUnderlyingType(TypeSourceInfo *TI) {
|
|||
if (T->isDependentType())
|
||||
return false;
|
||||
|
||||
// This doesn't use 'isIntegralType' despite the error message mentioning
|
||||
// integral type because isIntegralType would also allow enum types in C.
|
||||
if (const BuiltinType *BT = T->getAs<BuiltinType>())
|
||||
if (BT->isInteger())
|
||||
return false;
|
||||
|
||||
if (T->isExtIntType())
|
||||
return false;
|
||||
|
||||
return Diag(UnderlyingLoc, diag::err_enum_invalid_underlying) << T;
|
||||
Diag(UnderlyingLoc, diag::err_enum_invalid_underlying) << T;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Check whether this is a valid redeclaration of a previous enumeration.
|
||||
|
|
|
@ -4087,9 +4087,8 @@ void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI,
|
|||
Diag(AttrLoc, diag::err_enum_mode_vector_type) << Name << CI.getRange();
|
||||
return;
|
||||
}
|
||||
bool IntegralOrAnyEnumType = (OldElemTy->isIntegralOrEnumerationType() &&
|
||||
!OldElemTy->isExtIntType()) ||
|
||||
OldElemTy->getAs<EnumType>();
|
||||
bool IntegralOrAnyEnumType =
|
||||
OldElemTy->isIntegralOrEnumerationType() || OldElemTy->getAs<EnumType>();
|
||||
|
||||
if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType() &&
|
||||
!IntegralOrAnyEnumType)
|
||||
|
|
|
@ -1482,11 +1482,6 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
|
|||
if (LHSType == RHSType)
|
||||
return LHSType;
|
||||
|
||||
// ExtInt types aren't subject to conversions between them or normal integers,
|
||||
// so this fails.
|
||||
if(LHSType->isExtIntType() || RHSType->isExtIntType())
|
||||
return QualType();
|
||||
|
||||
// At this point, we have two different arithmetic types.
|
||||
|
||||
// Diagnose attempts to convert between __float128 and long double where
|
||||
|
@ -4266,7 +4261,6 @@ static void captureVariablyModifiedType(ASTContext &Context, QualType T,
|
|||
case Type::ObjCObjectPointer:
|
||||
case Type::ObjCTypeParam:
|
||||
case Type::Pipe:
|
||||
case Type::ExtInt:
|
||||
llvm_unreachable("type class is never variably-modified!");
|
||||
case Type::Adjusted:
|
||||
T = cast<AdjustedType>(Ty)->getOriginalType();
|
||||
|
@ -10437,19 +10431,14 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
|
|||
<< RHS.get()->getSourceRange());
|
||||
return;
|
||||
}
|
||||
|
||||
QualType LHSExprType = LHS.get()->getType();
|
||||
uint64_t LeftSize = LHSExprType->isExtIntType()
|
||||
? S.Context.getIntWidth(LHSExprType)
|
||||
: S.Context.getTypeSize(LHSExprType);
|
||||
llvm::APInt LeftBits(Right.getBitWidth(), LeftSize);
|
||||
llvm::APInt LeftBits(Right.getBitWidth(),
|
||||
S.Context.getTypeSize(LHS.get()->getType()));
|
||||
if (Right.uge(LeftBits)) {
|
||||
S.DiagRuntimeBehavior(Loc, RHS.get(),
|
||||
S.PDiag(diag::warn_shift_gt_typewidth)
|
||||
<< RHS.get()->getSourceRange());
|
||||
return;
|
||||
}
|
||||
|
||||
if (Opc != BO_Shl)
|
||||
return;
|
||||
|
||||
|
|
|
@ -2967,7 +2967,6 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
|
|||
case Type::Vector:
|
||||
case Type::ExtVector:
|
||||
case Type::Complex:
|
||||
case Type::ExtInt:
|
||||
break;
|
||||
|
||||
// Non-deduced auto types only get here for error cases.
|
||||
|
|
|
@ -5998,15 +5998,6 @@ bool UnnamedLocalNoLinkageFinder::VisitPipeType(const PipeType* T) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool UnnamedLocalNoLinkageFinder::VisitExtIntType(const ExtIntType *T) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UnnamedLocalNoLinkageFinder::VisitDependentExtIntType(
|
||||
const DependentExtIntType *T) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UnnamedLocalNoLinkageFinder::VisitTagDecl(const TagDecl *Tag) {
|
||||
if (Tag->getDeclContext()->isFunctionOrMethod()) {
|
||||
S.Diag(SR.getBegin(),
|
||||
|
@ -6900,9 +6891,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
|
|||
QualType IntegerType = ParamType;
|
||||
if (const EnumType *Enum = IntegerType->getAs<EnumType>())
|
||||
IntegerType = Enum->getDecl()->getIntegerType();
|
||||
Value = Value.extOrTrunc(IntegerType->isExtIntType()
|
||||
? Context.getIntWidth(IntegerType)
|
||||
: Context.getTypeSize(IntegerType));
|
||||
Value = Value.extOrTrunc(Context.getTypeSize(IntegerType));
|
||||
|
||||
Converted = TemplateArgument(Context, Value,
|
||||
Context.getCanonicalType(ParamType));
|
||||
|
@ -6996,9 +6985,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
|
|||
|
||||
// Coerce the template argument's value to the value it will have
|
||||
// based on the template parameter's type.
|
||||
unsigned AllowedBits = IntegerType->isExtIntType()
|
||||
? Context.getIntWidth(IntegerType)
|
||||
: Context.getTypeSize(IntegerType);
|
||||
unsigned AllowedBits = Context.getTypeSize(IntegerType);
|
||||
if (Value.getBitWidth() != AllowedBits)
|
||||
Value = Value.extOrTrunc(AllowedBits);
|
||||
Value.setIsSigned(IntegerType->isSignedIntegerOrEnumerationType());
|
||||
|
|
|
@ -1515,7 +1515,6 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
|
|||
case Type::ObjCObject:
|
||||
case Type::ObjCInterface:
|
||||
case Type::ObjCObjectPointer:
|
||||
case Type::ExtInt:
|
||||
if (TDF & TDF_SkipNonDependent)
|
||||
return Sema::TDK_Success;
|
||||
|
||||
|
@ -2107,33 +2106,6 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
|
|||
|
||||
return Sema::TDK_NonDeducedMismatch;
|
||||
}
|
||||
case Type::DependentExtInt: {
|
||||
const auto *IntParam = cast<DependentExtIntType>(Param);
|
||||
|
||||
if (const auto *IntArg = dyn_cast<ExtIntType>(Arg)){
|
||||
if (IntParam->isUnsigned() != IntArg->isUnsigned())
|
||||
return Sema::TDK_NonDeducedMismatch;
|
||||
|
||||
NonTypeTemplateParmDecl *NTTP =
|
||||
getDeducedParameterFromExpr(Info, IntParam->getNumBitsExpr());
|
||||
if (!NTTP)
|
||||
return Sema::TDK_Success;
|
||||
|
||||
llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
|
||||
ArgSize = IntArg->getNumBits();
|
||||
|
||||
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgSize,
|
||||
S.Context.IntTy, true, Info,
|
||||
Deduced);
|
||||
}
|
||||
|
||||
if (const auto *IntArg = dyn_cast<DependentExtIntType>(Arg)) {
|
||||
if (IntParam->isUnsigned() != IntArg->isUnsigned())
|
||||
return Sema::TDK_NonDeducedMismatch;
|
||||
return Sema::TDK_Success;
|
||||
}
|
||||
return Sema::TDK_NonDeducedMismatch;
|
||||
}
|
||||
|
||||
case Type::TypeOfExpr:
|
||||
case Type::TypeOf:
|
||||
|
@ -5878,11 +5850,6 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
|
|||
cast<DeducedType>(T)->getDeducedType(),
|
||||
OnlyDeduced, Depth, Used);
|
||||
break;
|
||||
case Type::DependentExtInt:
|
||||
MarkUsedTemplateParameters(Ctx,
|
||||
cast<DependentExtIntType>(T)->getNumBitsExpr(),
|
||||
OnlyDeduced, Depth, Used);
|
||||
break;
|
||||
|
||||
// None of these types have any template parameters in them.
|
||||
case Type::Builtin:
|
||||
|
@ -5895,7 +5862,6 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
|
|||
case Type::ObjCObjectPointer:
|
||||
case Type::UnresolvedUsing:
|
||||
case Type::Pipe:
|
||||
case Type::ExtInt:
|
||||
#define TYPE(Class, Base)
|
||||
#define ABSTRACT_TYPE(Class, Base)
|
||||
#define DEPENDENT_TYPE(Class, Base)
|
||||
|
|
|
@ -847,7 +847,6 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
|
|||
|
||||
case TST_typeofExpr:
|
||||
case TST_decltype:
|
||||
case TST_extint:
|
||||
if (DS.getRepAsExpr() &&
|
||||
DS.getRepAsExpr()->containsUnexpandedParameterPack())
|
||||
return true;
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
using namespace clang;
|
||||
|
@ -1442,15 +1441,6 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case DeclSpec::TST_extint: {
|
||||
Result = S.BuildExtIntType(DS.getTypeSpecSign() == TSS_unsigned,
|
||||
DS.getRepAsExpr(), DS.getBeginLoc());
|
||||
if (Result.isNull()) {
|
||||
Result = Context.IntTy;
|
||||
declarator.setInvalidType(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DeclSpec::TST_accum: {
|
||||
switch (DS.getTypeSpecWidth()) {
|
||||
case DeclSpec::TSW_short:
|
||||
|
@ -2170,45 +2160,6 @@ QualType Sema::BuildWritePipeType(QualType T, SourceLocation Loc) {
|
|||
return Context.getWritePipeType(T);
|
||||
}
|
||||
|
||||
/// Build a extended int type.
|
||||
///
|
||||
/// \param IsUnsigned Boolean representing the signedness of the type.
|
||||
///
|
||||
/// \param BitWidth Size of this int type in bits, or an expression representing
|
||||
/// that.
|
||||
///
|
||||
/// \param Loc Location of the keyword.
|
||||
QualType Sema::BuildExtIntType(bool IsUnsigned, Expr *BitWidth,
|
||||
SourceLocation Loc) {
|
||||
if (BitWidth->isInstantiationDependent())
|
||||
return Context.getDependentExtIntType(IsUnsigned, BitWidth);
|
||||
|
||||
llvm::APSInt Bits(32);
|
||||
ExprResult ICE = VerifyIntegerConstantExpression(BitWidth, &Bits);
|
||||
|
||||
if (ICE.isInvalid())
|
||||
return QualType();
|
||||
|
||||
int64_t NumBits = Bits.getSExtValue();
|
||||
if (!IsUnsigned && NumBits < 2) {
|
||||
Diag(Loc, diag::err_ext_int_bad_size) << 0;
|
||||
return QualType();
|
||||
}
|
||||
|
||||
if (IsUnsigned && NumBits < 1) {
|
||||
Diag(Loc, diag::err_ext_int_bad_size) << 1;
|
||||
return QualType();
|
||||
}
|
||||
|
||||
if (NumBits > llvm::IntegerType::MAX_INT_BITS) {
|
||||
Diag(Loc, diag::err_ext_int_max_size) << IsUnsigned
|
||||
<< llvm::IntegerType::MAX_INT_BITS;
|
||||
return QualType();
|
||||
}
|
||||
|
||||
return Context.getExtIntType(IsUnsigned, NumBits);
|
||||
}
|
||||
|
||||
/// Check whether the specified array size makes the array type a VLA. If so,
|
||||
/// return true, if not, return the size of the array in SizeVal.
|
||||
static bool isArraySizeVLA(Sema &S, Expr *ArraySize, llvm::APSInt &SizeVal) {
|
||||
|
@ -5823,14 +5774,6 @@ namespace {
|
|||
TL.getValueLoc().initializeFullCopy(TInfo->getTypeLoc());
|
||||
}
|
||||
|
||||
void VisitExtIntTypeLoc(ExtIntTypeLoc TL) {
|
||||
TL.setNameLoc(DS.getTypeSpecTypeLoc());
|
||||
}
|
||||
|
||||
void VisitDependentExtIntTypeLoc(DependentExtIntTypeLoc TL) {
|
||||
TL.setNameLoc(DS.getTypeSpecTypeLoc());
|
||||
}
|
||||
|
||||
void VisitTypeLoc(TypeLoc TL) {
|
||||
// FIXME: add other typespec types and change this to an assert.
|
||||
TL.initialize(Context, DS.getTypeSpecTypeLoc());
|
||||
|
@ -5957,9 +5900,6 @@ namespace {
|
|||
assert(Chunk.Kind == DeclaratorChunk::Pipe);
|
||||
TL.setKWLoc(Chunk.Loc);
|
||||
}
|
||||
void VisitExtIntTypeLoc(ExtIntTypeLoc TL) {
|
||||
TL.setNameLoc(Chunk.Loc);
|
||||
}
|
||||
void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
|
||||
TL.setExpansionLoc(Chunk.Loc);
|
||||
}
|
||||
|
@ -8691,12 +8631,6 @@ QualType Sema::BuildAtomicType(QualType T, SourceLocation Loc) {
|
|||
else if (!T.isTriviallyCopyableType(Context))
|
||||
// Some other non-trivially-copyable type (probably a C++ class)
|
||||
DisallowedKind = 7;
|
||||
else if (auto *ExtTy = T->getAs<ExtIntType>()) {
|
||||
if (ExtTy->getNumBits() < 8)
|
||||
DisallowedKind = 8;
|
||||
else if (!llvm::isPowerOf2_32(ExtTy->getNumBits()))
|
||||
DisallowedKind = 9;
|
||||
}
|
||||
|
||||
if (DisallowedKind != -1) {
|
||||
Diag(Loc, diag::err_atomic_specifier_bad_type) << DisallowedKind << T;
|
||||
|
|
|
@ -1183,14 +1183,6 @@ public:
|
|||
QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
|
||||
bool isReadPipe);
|
||||
|
||||
/// Build an extended int given its value type.
|
||||
QualType RebuildExtIntType(bool IsUnsigned, unsigned NumBits,
|
||||
SourceLocation Loc);
|
||||
|
||||
/// Build a dependent extended int given its value type.
|
||||
QualType RebuildDependentExtIntType(bool IsUnsigned, Expr *NumBitsExpr,
|
||||
SourceLocation Loc);
|
||||
|
||||
/// Build a new template name given a nested name specifier, a flag
|
||||
/// indicating whether the "template" keyword was provided, and the template
|
||||
/// that the template name refers to.
|
||||
|
@ -6128,57 +6120,6 @@ QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
|
|||
return Result;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
QualType TreeTransform<Derived>::TransformExtIntType(TypeLocBuilder &TLB,
|
||||
ExtIntTypeLoc TL) {
|
||||
const ExtIntType *EIT = TL.getTypePtr();
|
||||
QualType Result = TL.getType();
|
||||
|
||||
if (getDerived().AlwaysRebuild()) {
|
||||
Result = getDerived().RebuildExtIntType(EIT->isUnsigned(),
|
||||
EIT->getNumBits(), TL.getNameLoc());
|
||||
if (Result.isNull())
|
||||
return QualType();
|
||||
}
|
||||
|
||||
ExtIntTypeLoc NewTL = TLB.push<ExtIntTypeLoc>(Result);
|
||||
NewTL.setNameLoc(TL.getNameLoc());
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
QualType TreeTransform<Derived>::TransformDependentExtIntType(
|
||||
TypeLocBuilder &TLB, DependentExtIntTypeLoc TL) {
|
||||
const DependentExtIntType *EIT = TL.getTypePtr();
|
||||
|
||||
EnterExpressionEvaluationContext Unevaluated(
|
||||
SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
|
||||
ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
|
||||
BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr);
|
||||
|
||||
if (BitsExpr.isInvalid())
|
||||
return QualType();
|
||||
|
||||
QualType Result = TL.getType();
|
||||
|
||||
if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
|
||||
Result = getDerived().RebuildDependentExtIntType(
|
||||
EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
|
||||
|
||||
if (Result.isNull())
|
||||
return QualType();
|
||||
}
|
||||
|
||||
if (isa<DependentExtIntType>(Result)) {
|
||||
DependentExtIntTypeLoc NewTL = TLB.push<DependentExtIntTypeLoc>(Result);
|
||||
NewTL.setNameLoc(TL.getNameLoc());
|
||||
} else {
|
||||
ExtIntTypeLoc NewTL = TLB.push<ExtIntTypeLoc>(Result);
|
||||
NewTL.setNameLoc(TL.getNameLoc());
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// Simple iterator that traverses the template arguments in a
|
||||
/// container that provides a \c getArgLoc() member function.
|
||||
///
|
||||
|
@ -13841,23 +13782,6 @@ QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
|
|||
: SemaRef.BuildWritePipeType(ValueType, KWLoc);
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
QualType TreeTransform<Derived>::RebuildExtIntType(bool IsUnsigned,
|
||||
unsigned NumBits,
|
||||
SourceLocation Loc) {
|
||||
llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
|
||||
NumBits, true);
|
||||
IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
|
||||
SemaRef.Context.IntTy, Loc);
|
||||
return SemaRef.BuildExtIntType(IsUnsigned, Bits, Loc);
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
QualType TreeTransform<Derived>::RebuildDependentExtIntType(
|
||||
bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
|
||||
return SemaRef.BuildExtIntType(IsUnsigned, NumBitsExpr, Loc);
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
TemplateName
|
||||
TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
|
||||
|
|
|
@ -6719,15 +6719,6 @@ void TypeLocReader::VisitPipeTypeLoc(PipeTypeLoc TL) {
|
|||
TL.setKWLoc(readSourceLocation());
|
||||
}
|
||||
|
||||
void TypeLocReader::VisitExtIntTypeLoc(clang::ExtIntTypeLoc TL) {
|
||||
TL.setNameLoc(readSourceLocation());
|
||||
}
|
||||
void TypeLocReader::VisitDependentExtIntTypeLoc(
|
||||
clang::DependentExtIntTypeLoc TL) {
|
||||
TL.setNameLoc(readSourceLocation());
|
||||
}
|
||||
|
||||
|
||||
void ASTRecordReader::readTypeLoc(TypeLoc TL) {
|
||||
TypeLocReader TLR(*this);
|
||||
for (; !TL.isNull(); TL = TL.getNextTypeLoc())
|
||||
|
|
|
@ -476,14 +476,6 @@ void TypeLocWriter::VisitPipeTypeLoc(PipeTypeLoc TL) {
|
|||
Record.AddSourceLocation(TL.getKWLoc());
|
||||
}
|
||||
|
||||
void TypeLocWriter::VisitExtIntTypeLoc(clang::ExtIntTypeLoc TL) {
|
||||
Record.AddSourceLocation(TL.getNameLoc());
|
||||
}
|
||||
void TypeLocWriter::VisitDependentExtIntTypeLoc(
|
||||
clang::DependentExtIntTypeLoc TL) {
|
||||
Record.AddSourceLocation(TL.getNameLoc());
|
||||
}
|
||||
|
||||
void ASTWriter::WriteTypeAbbrevs() {
|
||||
using namespace llvm;
|
||||
|
||||
|
|
|
@ -1,265 +0,0 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-gnu-linux -fsanitize=array-bounds,enum,float-cast-overflow,integer-divide-by-zero,implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change,unsigned-integer-overflow,signed-integer-overflow,shift-base,shift-exponent -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
|
||||
// CHECK: define void @_Z6BoundsRA10_KiU7_ExtIntILi15EEi
|
||||
void Bounds(const int (&Array)[10], _ExtInt(15) Index) {
|
||||
int I1 = Array[Index];
|
||||
// CHECK: %[[SEXT:.+]] = sext i15 %{{.+}} to i64
|
||||
// CHECK: %[[CMP:.+]] = icmp ult i64 %[[SEXT]], 10
|
||||
// CHECK: br i1 %[[CMP]]
|
||||
// CHECK: call void @__ubsan_handle_out_of_bounds
|
||||
}
|
||||
|
||||
// CHECK: define void @_Z4Enumv
|
||||
void Enum() {
|
||||
enum E1 { e1a = 0, e1b = 127 }
|
||||
e1;
|
||||
enum E2 { e2a = -1, e2b = 64 }
|
||||
e2;
|
||||
enum E3 { e3a = (1u << 31) - 1 }
|
||||
e3;
|
||||
|
||||
_ExtInt(34) a = e1;
|
||||
// CHECK: %[[E1:.+]] = icmp ule i32 %{{.*}}, 127
|
||||
// CHECK: br i1 %[[E1]]
|
||||
// CHECK: call void @__ubsan_handle_load_invalid_value_abort
|
||||
_ExtInt(34) b = e2;
|
||||
// CHECK: %[[E2HI:.*]] = icmp sle i32 {{.*}}, 127
|
||||
// CHECK: %[[E2LO:.*]] = icmp sge i32 {{.*}}, -128
|
||||
// CHECK: %[[E2:.*]] = and i1 %[[E2HI]], %[[E2LO]]
|
||||
// CHECK: br i1 %[[E2]]
|
||||
// CHECK: call void @__ubsan_handle_load_invalid_value_abort
|
||||
_ExtInt(34) c = e3;
|
||||
// CHECK: %[[E3:.*]] = icmp ule i32 {{.*}}, 2147483647
|
||||
// CHECK: br i1 %[[E3]]
|
||||
// CHECK: call void @__ubsan_handle_load_invalid_value_abort
|
||||
}
|
||||
|
||||
// CHECK: define void @_Z13FloatOverflowfd
|
||||
void FloatOverflow(float f, double d) {
|
||||
_ExtInt(10) E = f;
|
||||
// CHECK: fcmp ogt float %{{.+}}, -5.130000e+02
|
||||
// CHECK: fcmp olt float %{{.+}}, 5.120000e+02
|
||||
_ExtInt(10) E2 = d;
|
||||
// CHECK: fcmp ogt double %{{.+}}, -5.130000e+02
|
||||
// CHECK: fcmp olt double %{{.+}}, 5.120000e+02
|
||||
_ExtInt(7) E3 = f;
|
||||
// CHECK: fcmp ogt float %{{.+}}, -6.500000e+01
|
||||
// CHECK: fcmp olt float %{{.+}}, 6.400000e+01
|
||||
_ExtInt(7) E4 = d;
|
||||
// CHECK: fcmp ogt double %{{.+}}, -6.500000e+01
|
||||
// CHECK: fcmp olt double %{{.+}}, 6.400000e+01
|
||||
}
|
||||
|
||||
// CHECK: define void @_Z14UIntTruncationU7_ExtIntILi35EEjjy
|
||||
void UIntTruncation(unsigned _ExtInt(35) E, unsigned int i, unsigned long long ll) {
|
||||
|
||||
i = E;
|
||||
// CHECK: %[[LOADE:.+]] = load i35
|
||||
// CHECK: %[[CONV:.+]] = trunc i35 %[[LOADE]] to i32
|
||||
// CHECK: %[[EXT:.+]] = zext i32 %[[CONV]] to i35
|
||||
// CHECK: %[[CHECK:.+]] = icmp eq i35 %[[EXT]], %[[LOADE]]
|
||||
// CHECK: br i1 %[[CHECK]]
|
||||
// CHECK: call void @__ubsan_handle_implicit_conversion_abort
|
||||
|
||||
E = ll;
|
||||
// CHECK: %[[LOADLL:.+]] = load i64
|
||||
// CHECK: %[[CONV:.+]] = trunc i64 %[[LOADLL]] to i35
|
||||
// CHECK: %[[EXT:.+]] = zext i35 %[[CONV]] to i64
|
||||
// CHECK: %[[CHECK:.+]] = icmp eq i64 %[[EXT]], %[[LOADLL]]
|
||||
// CHECK: br i1 %[[CHECK]]
|
||||
// CHECK: call void @__ubsan_handle_implicit_conversion_abort
|
||||
}
|
||||
|
||||
// CHECK: define void @_Z13IntTruncationU7_ExtIntILi35EEiU7_ExtIntILi42EEjij
|
||||
void IntTruncation(_ExtInt(35) E, unsigned _ExtInt(42) UE, int i, unsigned j) {
|
||||
|
||||
j = E;
|
||||
// CHECK: %[[LOADE:.+]] = load i35
|
||||
// CHECK: %[[CONV:.+]] = trunc i35 %[[LOADE]] to i32
|
||||
// CHECK: %[[EXT:.+]] = zext i32 %[[CONV]] to i35
|
||||
// CHECK: %[[CHECK:.+]] = icmp eq i35 %[[EXT]], %[[LOADE]]
|
||||
// CHECK: br i1 %[[CHECK]]
|
||||
// CHECK: call void @__ubsan_handle_implicit_conversion_abort
|
||||
|
||||
j = UE;
|
||||
// CHECK: %[[LOADUE:.+]] = load i42
|
||||
// CHECK: %[[CONV:.+]] = trunc i42 %[[LOADUE]] to i32
|
||||
// CHECK: %[[EXT:.+]] = zext i32 %[[CONV]] to i42
|
||||
// CHECK: %[[CHECK:.+]] = icmp eq i42 %[[EXT]], %[[LOADUE]]
|
||||
// CHECK: br i1 %[[CHECK]]
|
||||
// CHECK: call void @__ubsan_handle_implicit_conversion_abort
|
||||
|
||||
// Note: also triggers sign change check.
|
||||
i = UE;
|
||||
// CHECK: %[[LOADUE:.+]] = load i42
|
||||
// CHECK: %[[CONV:.+]] = trunc i42 %[[LOADUE]] to i32
|
||||
// CHECK: %[[NEG:.+]] = icmp slt i32 %[[CONV]], 0
|
||||
// CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 false, %[[NEG]]
|
||||
// CHECK: %[[EXT:.+]] = sext i32 %[[CONV]] to i42
|
||||
// CHECK: %[[CHECK:.+]] = icmp eq i42 %[[EXT]], %[[LOADUE]]
|
||||
// CHECK: %[[CHECKBOTH:.+]] = and i1 %[[SIGNCHECK]], %[[CHECK]]
|
||||
// CHECK: br i1 %[[CHECKBOTH]]
|
||||
// CHECK: call void @__ubsan_handle_implicit_conversion_abort
|
||||
|
||||
// Note: also triggers sign change check.
|
||||
E = UE;
|
||||
// CHECK: %[[LOADUE:.+]] = load i42
|
||||
// CHECK: %[[CONV:.+]] = trunc i42 %[[LOADUE]] to i35
|
||||
// CHECK: %[[NEG:.+]] = icmp slt i35 %[[CONV]], 0
|
||||
// CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 false, %[[NEG]]
|
||||
// CHECK: %[[EXT:.+]] = sext i35 %[[CONV]] to i42
|
||||
// CHECK: %[[CHECK:.+]] = icmp eq i42 %[[EXT]], %[[LOADUE]]
|
||||
// CHECK: %[[CHECKBOTH:.+]] = and i1 %[[SIGNCHECK]], %[[CHECK]]
|
||||
// CHECK: br i1 %[[CHECKBOTH]]
|
||||
// CHECK: call void @__ubsan_handle_implicit_conversion_abort
|
||||
}
|
||||
|
||||
// CHECK: define void @_Z15SignChangeCheckU7_ExtIntILi39EEjU7_ExtIntILi39EEi
|
||||
void SignChangeCheck(unsigned _ExtInt(39) UE, _ExtInt(39) E) {
|
||||
UE = E;
|
||||
// CHECK: %[[LOADE:.+]] = load i39
|
||||
// CHECK: %[[NEG:.+]] = icmp slt i39 %[[LOADE]], 0
|
||||
// CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 %[[NEG]], false
|
||||
// CHECK: br i1 %[[SIGNCHECK]]
|
||||
// CHECK: call void @__ubsan_handle_implicit_conversion_abort
|
||||
|
||||
|
||||
E = UE;
|
||||
// CHECK: %[[LOADUE:.+]] = load i39
|
||||
// CHECK: %[[NEG:.+]] = icmp slt i39 %[[LOADUE]], 0
|
||||
// CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 false, %[[NEG]]
|
||||
// CHECK: br i1 %[[SIGNCHECK]]
|
||||
// CHECK: call void @__ubsan_handle_implicit_conversion_abort
|
||||
}
|
||||
|
||||
// CHECK: define void @_Z9DivByZeroU7_ExtIntILi11EEii
|
||||
void DivByZero(_ExtInt(11) E, int i) {
|
||||
|
||||
// Also triggers signed integer overflow.
|
||||
E / E;
|
||||
// CHECK: %[[E:.+]] = load i11, i11*
|
||||
// CHECK: %[[E2:.+]] = load i11, i11*
|
||||
// CHECK: %[[NEZERO:.+]] = icmp ne i11 %[[E2]], 0
|
||||
// CHECK: %[[NEMIN:.+]] = icmp ne i11 %[[E]], -1024
|
||||
// CHECK: %[[NENEG1:.+]] = icmp ne i11 %[[E2]], -1
|
||||
// CHECK: %[[OR:.+]] = or i1 %[[NEMIN]], %[[NENEG1]]
|
||||
// CHECK: %[[AND:.+]] = and i1 %[[NEZERO]], %[[OR]]
|
||||
// CHECK: br i1 %[[AND]]
|
||||
// CHECK: call void @__ubsan_handle_divrem_overflow_abort
|
||||
}
|
||||
|
||||
// TODO:
|
||||
//-fsanitize=shift: (shift-base, shift-exponent) Shift operators where the amount shifted is greater or equal to the promoted bit-width of the left hand side or less than zero, or where the left hand side is negative. For a signed left shift, also checks for signed overflow in C, and for unsigned overflow in C++. You can use -fsanitize=shift-base or -fsanitize=shift-exponent to check only left-hand side or right-hand side of shift operation, respectively.
|
||||
// CHECK: define void @_Z6ShiftsU7_ExtIntILi9EEi
|
||||
void Shifts(_ExtInt(9) E) {
|
||||
E >> E;
|
||||
// CHECK: %[[LHSE:.+]] = load i9, i9*
|
||||
// CHECK: %[[RHSE:.+]] = load i9, i9*
|
||||
// CHECK: %[[CMP:.+]] = icmp ule i9 %[[RHSE]], 8
|
||||
// CHECK: br i1 %[[CMP]]
|
||||
// CHECK: call void @__ubsan_handle_shift_out_of_bounds_abort
|
||||
|
||||
E << E;
|
||||
// CHECK: %[[LHSE:.+]] = load i9, i9*
|
||||
// CHECK: %[[RHSE:.+]] = load i9, i9*
|
||||
// CHECK: %[[CMP:.+]] = icmp ule i9 %[[RHSE]], 8
|
||||
// CHECK: br i1 %[[CMP]]
|
||||
// CHECK: %[[ZEROS:.+]] = sub nuw nsw i9 8, %[[RHSE]]
|
||||
// CHECK: %[[CHECK:.+]] = lshr i9 %[[LHSE]], %[[ZEROS]]
|
||||
// CHECK: %[[SKIPSIGN:.+]] = lshr i9 %[[CHECK]], 1
|
||||
// CHECK: %[[CHECK:.+]] = icmp eq i9 %[[SKIPSIGN]]
|
||||
// CHECK: %[[PHI:.+]] = phi i1 [ true, %{{.+}} ], [ %[[CHECK]], %{{.+}} ]
|
||||
// CHECK: and i1 %[[CMP]], %[[PHI]]
|
||||
// CHECK: call void @__ubsan_handle_shift_out_of_bounds_abort
|
||||
}
|
||||
|
||||
// CHECK: define void @_Z21SignedIntegerOverflowU7_ExtIntILi93EEiU7_ExtIntILi4EEiU7_ExtIntILi31EEi
|
||||
void SignedIntegerOverflow(_ExtInt(93) BiggestE,
|
||||
_ExtInt(4) SmallestE,
|
||||
_ExtInt(31) JustRightE) {
|
||||
BiggestE + BiggestE;
|
||||
// CHECK: %[[LOAD1:.+]] = load i93, i93*
|
||||
// CHECK: %[[LOAD2:.+]] = load i93, i93*
|
||||
// CHECK: %[[OFCALL:.+]] = call { i93, i1 } @llvm.sadd.with.overflow.i93(i93 %[[LOAD1]], i93 %[[LOAD2]])
|
||||
// CHECK: %[[EXRESULT:.+]] = extractvalue { i93, i1 } %[[OFCALL]], 0
|
||||
// CHECK: %[[OFRESULT:.+]] = extractvalue { i93, i1 } %[[OFCALL]], 1
|
||||
// CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
|
||||
// CHECK: br i1 %[[CHECK]]
|
||||
// CHECK: call void @__ubsan_handle_add_overflow_abort
|
||||
|
||||
SmallestE - SmallestE;
|
||||
// CHECK: %[[LOAD1:.+]] = load i4, i4*
|
||||
// CHECK: %[[LOAD2:.+]] = load i4, i4*
|
||||
// CHECK: %[[OFCALL:.+]] = call { i4, i1 } @llvm.ssub.with.overflow.i4(i4 %[[LOAD1]], i4 %[[LOAD2]])
|
||||
// CHECK: %[[EXRESULT:.+]] = extractvalue { i4, i1 } %[[OFCALL]], 0
|
||||
// CHECK: %[[OFRESULT:.+]] = extractvalue { i4, i1 } %[[OFCALL]], 1
|
||||
// CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
|
||||
// CHECK: br i1 %[[CHECK]]
|
||||
// CHECK: call void @__ubsan_handle_sub_overflow_abort
|
||||
|
||||
JustRightE * JustRightE;
|
||||
// CHECK: %[[LOAD1:.+]] = load i31, i31*
|
||||
// CHECK: %[[LOAD2:.+]] = load i31, i31*
|
||||
// CHECK: %[[OFCALL:.+]] = call { i31, i1 } @llvm.smul.with.overflow.i31(i31 %[[LOAD1]], i31 %[[LOAD2]])
|
||||
// CHECK: %[[EXRESULT:.+]] = extractvalue { i31, i1 } %[[OFCALL]], 0
|
||||
// CHECK: %[[OFRESULT:.+]] = extractvalue { i31, i1 } %[[OFCALL]], 1
|
||||
// CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
|
||||
// CHECK: br i1 %[[CHECK]]
|
||||
// CHECK: call void @__ubsan_handle_mul_overflow_abort
|
||||
}
|
||||
|
||||
// CHECK: define void @_Z23UnsignedIntegerOverflowjU7_ExtIntILi23EEjU7_ExtIntILi35EEj
|
||||
void UnsignedIntegerOverflow(unsigned u,
|
||||
unsigned _ExtInt(23) SmallE,
|
||||
unsigned _ExtInt(35) BigE) {
|
||||
u = SmallE + SmallE;
|
||||
// CHECK: %[[LOADE1:.+]] = load i23, i23*
|
||||
// CHECK: %[[LOADE2:.+]] = load i23, i23*
|
||||
// CHECK: %[[OFCALL:.+]] = call { i23, i1 } @llvm.uadd.with.overflow.i23(i23 %[[LOADE1]], i23 %[[LOADE2]])
|
||||
// CHECK: %[[EXRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 0
|
||||
// CHECK: %[[OFRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 1
|
||||
// CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
|
||||
// CHECK: br i1 %[[CHECK]]
|
||||
// CHECK: call void @__ubsan_handle_add_overflow_abort
|
||||
|
||||
SmallE = u + u;
|
||||
// CHECK: %[[LOADU1:.+]] = load i32, i32*
|
||||
// CHECK: %[[LOADU2:.+]] = load i32, i32*
|
||||
// CHECK: %[[OFCALL:.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %[[LOADU1]], i32 %[[LOADU2]])
|
||||
// CHECK: %[[EXRESULT:.+]] = extractvalue { i32, i1 } %[[OFCALL]], 0
|
||||
// CHECK: %[[OFRESULT:.+]] = extractvalue { i32, i1 } %[[OFCALL]], 1
|
||||
// CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
|
||||
// CHECK: br i1 %[[CHECK]]
|
||||
// CHECK: call void @__ubsan_handle_add_overflow_abort
|
||||
|
||||
SmallE = SmallE + SmallE;
|
||||
// CHECK: %[[LOADE1:.+]] = load i23, i23*
|
||||
// CHECK: %[[LOADE2:.+]] = load i23, i23*
|
||||
// CHECK: %[[OFCALL:.+]] = call { i23, i1 } @llvm.uadd.with.overflow.i23(i23 %[[LOADE1]], i23 %[[LOADE2]])
|
||||
// CHECK: %[[EXRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 0
|
||||
// CHECK: %[[OFRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 1
|
||||
// CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
|
||||
// CHECK: br i1 %[[CHECK]]
|
||||
// CHECK: call void @__ubsan_handle_add_overflow_abort
|
||||
|
||||
SmallE = BigE + BigE;
|
||||
// CHECK: %[[LOADE1:.+]] = load i35, i35*
|
||||
// CHECK: %[[LOADE2:.+]] = load i35, i35*
|
||||
// CHECK: %[[OFCALL:.+]] = call { i35, i1 } @llvm.uadd.with.overflow.i35(i35 %[[LOADE1]], i35 %[[LOADE2]])
|
||||
// CHECK: %[[EXRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 0
|
||||
// CHECK: %[[OFRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 1
|
||||
// CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
|
||||
// CHECK: br i1 %[[CHECK]]
|
||||
// CHECK: call void @__ubsan_handle_add_overflow_abort
|
||||
|
||||
BigE = BigE + BigE;
|
||||
// CHECK: %[[LOADE1:.+]] = load i35, i35*
|
||||
// CHECK: %[[LOADE2:.+]] = load i35, i35*
|
||||
// CHECK: %[[OFCALL:.+]] = call { i35, i1 } @llvm.uadd.with.overflow.i35(i35 %[[LOADE1]], i35 %[[LOADE2]])
|
||||
// CHECK: %[[EXRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 0
|
||||
// CHECK: %[[OFRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 1
|
||||
// CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
|
||||
// CHECK: br i1 %[[CHECK]]
|
||||
// CHECK: call void @__ubsan_handle_add_overflow_abort
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-gnu-linux -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK
|
||||
// RUN: %clang_cc1 -triple x86_64-windows-pc -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK
|
||||
|
||||
|
||||
void GenericTest(_ExtInt(3) a, unsigned _ExtInt(3) b, _ExtInt(4) c) {
|
||||
// CHECK: define {{.*}}void @GenericTest
|
||||
int which = _Generic(a, _ExtInt(3): 1, unsigned _ExtInt(3) : 2, _ExtInt(4) : 3);
|
||||
// CHECK: store i32 1
|
||||
int which2 = _Generic(b, _ExtInt(3): 1, unsigned _ExtInt(3) : 2, _ExtInt(4) : 3);
|
||||
// CHECK: store i32 2
|
||||
int which3 = _Generic(c, _ExtInt(3): 1, unsigned _ExtInt(3) : 2, _ExtInt(4) : 3);
|
||||
// CHECK: store i32 3
|
||||
}
|
||||
|
||||
void VLATest(_ExtInt(3) A, _ExtInt(99) B, _ExtInt(123456) C) {
|
||||
// CHECK: define {{.*}}void @VLATest
|
||||
int AR1[A];
|
||||
// CHECK: %[[A:.+]] = zext i3 %{{.+}} to i64
|
||||
// CHECK: %[[VLA1:.+]] = alloca i32, i64 %[[A]]
|
||||
int AR2[B];
|
||||
// CHECK: %[[B:.+]] = trunc i99 %{{.+}} to i64
|
||||
// CHECK: %[[VLA2:.+]] = alloca i32, i64 %[[B]]
|
||||
int AR3[C];
|
||||
// CHECK: %[[C:.+]] = trunc i123456 %{{.+}} to i64
|
||||
// CHECK: %[[VLA3:.+]] = alloca i32, i64 %[[C]]
|
||||
}
|
||||
|
||||
struct S {
|
||||
_ExtInt(17) A;
|
||||
_ExtInt(16777200) B;
|
||||
_ExtInt(17) C;
|
||||
};
|
||||
|
||||
void OffsetOfTest() {
|
||||
// CHECK: define {{.*}}void @OffsetOfTest
|
||||
int A = __builtin_offsetof(struct S,A);
|
||||
// CHECK: store i32 0, i32* %{{.+}}
|
||||
int B = __builtin_offsetof(struct S,B);
|
||||
// CHECK: store i32 8, i32* %{{.+}}
|
||||
int C = __builtin_offsetof(struct S,C);
|
||||
// CHECK: store i32 2097160, i32* %{{.+}}
|
||||
}
|
||||
|
||||
|
|
@ -1,432 +0,0 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-gnu-linux -O3 -disable-llvm-passes -I%S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,LIN,NoNewStructPathTBAA
|
||||
// RUN: %clang_cc1 -triple x86_64-gnu-linux -O3 -disable-llvm-passes -I%S -new-struct-path-tbaa -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,LIN,NewStructPathTBAA
|
||||
|
||||
// RUN: %clang_cc1 -triple x86_64-windows-pc -O3 -disable-llvm-passes -I%S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WIN,NoNewStructPathTBAA
|
||||
// RUN: %clang_cc1 -triple x86_64-windows-pc -O3 -disable-llvm-passes -I%S -new-struct-path-tbaa -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WIN,NewStructPathTBAA
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
// Ensure that the layout for these structs is the same as the normal bitfield
|
||||
// layouts.
|
||||
struct BitFieldsByte {
|
||||
_ExtInt(7) A : 3;
|
||||
_ExtInt(7) B : 3;
|
||||
_ExtInt(7) C : 2;
|
||||
};
|
||||
// CHECK: %struct.BitFieldsByte = type { i8 }
|
||||
|
||||
struct BitFieldsShort {
|
||||
_ExtInt(15) A : 3;
|
||||
_ExtInt(15) B : 3;
|
||||
_ExtInt(15) C : 2;
|
||||
};
|
||||
// LIN: %struct.BitFieldsShort = type { i8, i8 }
|
||||
// WIN: %struct.BitFieldsShort = type { i16 }
|
||||
|
||||
struct BitFieldsInt {
|
||||
_ExtInt(31) A : 3;
|
||||
_ExtInt(31) B : 3;
|
||||
_ExtInt(31) C : 2;
|
||||
};
|
||||
// LIN: %struct.BitFieldsInt = type { i8, [3 x i8] }
|
||||
// WIN: %struct.BitFieldsInt = type { i32 }
|
||||
|
||||
struct BitFieldsLong {
|
||||
_ExtInt(63) A : 3;
|
||||
_ExtInt(63) B : 3;
|
||||
_ExtInt(63) C : 2;
|
||||
};
|
||||
// LIN: %struct.BitFieldsLong = type { i8, [7 x i8] }
|
||||
// WIN: %struct.BitFieldsLong = type { i64 }
|
||||
|
||||
struct HasExtIntFirst {
|
||||
_ExtInt(35) A;
|
||||
int B;
|
||||
};
|
||||
// CHECK: %struct.HasExtIntFirst = type { i35, i32 }
|
||||
|
||||
struct HasExtIntLast {
|
||||
int A;
|
||||
_ExtInt(35) B;
|
||||
};
|
||||
// CHECK: %struct.HasExtIntLast = type { i32, i35 }
|
||||
|
||||
struct HasExtIntMiddle {
|
||||
int A;
|
||||
_ExtInt(35) B;
|
||||
int C;
|
||||
};
|
||||
// CHECK: %struct.HasExtIntMiddle = type { i32, i35, i32 }
|
||||
|
||||
// Force emitting of the above structs.
|
||||
void StructEmit() {
|
||||
BitFieldsByte A;
|
||||
BitFieldsShort B;
|
||||
BitFieldsInt C;
|
||||
BitFieldsLong D;
|
||||
|
||||
HasExtIntFirst E;
|
||||
HasExtIntLast F;
|
||||
HasExtIntMiddle G;
|
||||
}
|
||||
|
||||
void BitfieldAssignment() {
|
||||
// LIN: define void @_Z18BitfieldAssignmentv
|
||||
// WIN: define dso_local void @"?BitfieldAssignment@@YAXXZ"
|
||||
BitFieldsByte B;
|
||||
B.A = 3;
|
||||
B.B = 2;
|
||||
B.C = 1;
|
||||
// First one is used for the lifetime start, skip that.
|
||||
// CHECK: bitcast %struct.BitFieldsByte*
|
||||
// CHECK: %[[BFType:.+]] = bitcast %struct.BitFieldsByte*
|
||||
// CHECK: %[[LOADA:.+]] = load i8, i8* %[[BFType]]
|
||||
// CHECK: %[[CLEARA:.+]] = and i8 %[[LOADA]], -8
|
||||
// CHECK: %[[SETA:.+]] = or i8 %[[CLEARA]], 3
|
||||
// CHECK: %[[BFType:.+]] = bitcast %struct.BitFieldsByte*
|
||||
// CHECK: %[[LOADB:.+]] = load i8, i8* %[[BFType]]
|
||||
// CHECK: %[[CLEARB:.+]] = and i8 %[[LOADB]], -57
|
||||
// CHECK: %[[SETB:.+]] = or i8 %[[CLEARB]], 16
|
||||
// CHECK: %[[BFType:.+]] = bitcast %struct.BitFieldsByte*
|
||||
// CHECK: %[[LOADC:.+]] = load i8, i8* %[[BFType]]
|
||||
// CHECK: %[[CLEARC:.+]] = and i8 %[[LOADC]], 63
|
||||
// CHECK: %[[SETC:.+]] = or i8 %[[CLEARC]], 64
|
||||
}
|
||||
|
||||
enum AsEnumUnderlyingType : _ExtInt(9) {
|
||||
A,B,C
|
||||
};
|
||||
|
||||
void UnderlyingTypeUsage(AsEnumUnderlyingType Param) {
|
||||
// LIN: define void @_Z19UnderlyingTypeUsage20AsEnumUnderlyingType(i9 %
|
||||
// WIN: define dso_local void @"?UnderlyingTypeUsage@@YAXW4AsEnumUnderlyingType@@@Z"(i9 %
|
||||
AsEnumUnderlyingType Var;
|
||||
// CHECK: alloca i9, align 2
|
||||
// CHECK: store i9 %{{.*}}, align 2
|
||||
}
|
||||
|
||||
unsigned _ExtInt(33) ManglingTestRetParam(unsigned _ExtInt(33) Param) {
|
||||
// LIN: define i33 @_Z20ManglingTestRetParamU7_ExtIntILi33EEj(i33 %
|
||||
// WIN: define dso_local i33 @"?ManglingTestRetParam@@YAU?$_UExtInt@$0CB@@__clang@@U12@@Z"(i33
|
||||
return 0;
|
||||
}
|
||||
|
||||
_ExtInt(33) ManglingTestRetParam(_ExtInt(33) Param) {
|
||||
// LIN: define i33 @_Z20ManglingTestRetParamU7_ExtIntILi33EEi(i33 %
|
||||
// WIN: define dso_local i33 @"?ManglingTestRetParam@@YAU?$_ExtInt@$0CB@@__clang@@U12@@Z"(i33
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ManglingTestTemplateParam(T&);
|
||||
template<_ExtInt(99) T>
|
||||
void ManglingTestNTTP();
|
||||
|
||||
void ManglingInstantiator() {
|
||||
// LIN: define void @_Z20ManglingInstantiatorv()
|
||||
// WIN: define dso_local void @"?ManglingInstantiator@@YAXXZ"()
|
||||
_ExtInt(93) A;
|
||||
ManglingTestTemplateParam(A);
|
||||
// LIN: call void @_Z25ManglingTestTemplateParamIU7_ExtIntILi93EEiEvRT_(i93*
|
||||
// WIN: call void @"??$ManglingTestTemplateParam@U?$_ExtInt@$0FN@@__clang@@@@YAXAEAU?$_ExtInt@$0FN@@__clang@@@Z"(i93*
|
||||
constexpr _ExtInt(93) B = 993;
|
||||
ManglingTestNTTP<38>();
|
||||
// LIN: call void @_Z16ManglingTestNTTPILU7_ExtIntILi99EEi38EEvv()
|
||||
// WIN: call void @"??$ManglingTestNTTP@$0CG@@@YAXXZ"()
|
||||
ManglingTestNTTP<B>();
|
||||
// LIN: call void @_Z16ManglingTestNTTPILU7_ExtIntILi99EEi993EEvv()
|
||||
// WIN: call void @"??$ManglingTestNTTP@$0DOB@@@YAXXZ"()
|
||||
}
|
||||
|
||||
void TakesVarargs(int i, ...) {
|
||||
// LIN: define void @_Z12TakesVarargsiz(i32 %i, ...)
|
||||
// WIN: define dso_local void @"?TakesVarargs@@YAXHZZ"(i32 %i, ...)
|
||||
|
||||
__builtin_va_list args;
|
||||
// LIN: %[[ARGS:.+]] = alloca [1 x %struct.__va_list_tag]
|
||||
// WIN: %[[ARGS:.+]] = alloca i8*
|
||||
__builtin_va_start(args, i);
|
||||
// LIN: %[[STARTAD:.+]] = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %[[ARGS]]
|
||||
// LIN: %[[STARTAD1:.+]] = bitcast %struct.__va_list_tag* %[[STARTAD]] to i8*
|
||||
// LIN: call void @llvm.va_start(i8* %[[STARTAD1]])
|
||||
// WIN: %[[ARGSLLIFETIMESTART:.+]] = bitcast i8** %[[ARGS]] to i8*
|
||||
// WIN: %[[ARGSSTART:.+]] = bitcast i8** %[[ARGS]] to i8*
|
||||
// WIN: call void @llvm.va_start(i8* %[[ARGSSTART]])
|
||||
|
||||
_ExtInt(92) A = __builtin_va_arg(args, _ExtInt(92));
|
||||
// LIN: %[[AD1:.+]] = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %[[ARGS]]
|
||||
// LIN: %[[OFA_P1:.+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %[[AD1]], i32 0, i32 2
|
||||
// LIN: %[[OFA1:.+]] = load i8*, i8** %[[OFA_P1]]
|
||||
// LIN: %[[BC1:.+]] = bitcast i8* %[[OFA1]] to i92*
|
||||
// LIN: %[[OFANEXT1:.+]] = getelementptr i8, i8* %[[OFA1]], i32 16
|
||||
// LIN: store i8* %[[OFANEXT1]], i8** %[[OFA_P1]]
|
||||
// LIN: %[[LOAD1:.+]] = load i92, i92* %[[BC1]]
|
||||
// LIN: store i92 %[[LOAD1]], i92*
|
||||
// WIN: %[[CUR1:.+]] = load i8*, i8** %[[ARGS]]
|
||||
// WIN: %[[NEXT1:.+]] = getelementptr inbounds i8, i8* %[[CUR1]], i64 16
|
||||
// WIN: store i8* %[[NEXT1]], i8** %[[ARGS]]
|
||||
// WIN: %[[BC1:.+]] = bitcast i8* %[[CUR1]] to i92*
|
||||
// WIN: %[[LOADV1:.+]] = load i92, i92* %[[BC1]]
|
||||
// WIN: store i92 %[[LOADV1]], i92*
|
||||
|
||||
_ExtInt(31) B = __builtin_va_arg(args, _ExtInt(31));
|
||||
// LIN: %[[AD2:.+]] = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %[[ARGS]]
|
||||
// LIN: %[[OFA_P2:.+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %[[AD2]], i32 0, i32 2
|
||||
// LIN: %[[OFA2:.+]] = load i8*, i8** %[[OFA_P2]]
|
||||
// LIN: %[[BC2:.+]] = bitcast i8* %[[OFA2]] to i31*
|
||||
// LIN: %[[OFANEXT2:.+]] = getelementptr i8, i8* %[[OFA2]], i32 8
|
||||
// LIN: store i8* %[[OFANEXT2]], i8** %[[OFA_P2]]
|
||||
// LIN: %[[LOAD2:.+]] = load i31, i31* %[[BC2]]
|
||||
// LIN: store i31 %[[LOAD2]], i31*
|
||||
// WIN: %[[CUR2:.+]] = load i8*, i8** %[[ARGS]]
|
||||
// WIN: %[[NEXT2:.+]] = getelementptr inbounds i8, i8* %[[CUR2]], i64 8
|
||||
// WIN: store i8* %[[NEXT2]], i8** %[[ARGS]]
|
||||
// WIN: %[[BC2:.+]] = bitcast i8* %[[CUR2]] to i31*
|
||||
// WIN: %[[LOADV2:.+]] = load i31, i31* %[[BC2]]
|
||||
// WIN: store i31 %[[LOADV2]], i31*
|
||||
|
||||
_ExtInt(16) C = __builtin_va_arg(args, _ExtInt(16));
|
||||
// LIN: %[[AD3:.+]] = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %[[ARGS]]
|
||||
// LIN: %[[OFA_P3:.+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %[[AD3]], i32 0, i32 2
|
||||
// LIN: %[[OFA3:.+]] = load i8*, i8** %[[OFA_P3]]
|
||||
// LIN: %[[BC3:.+]] = bitcast i8* %[[OFA3]] to i16*
|
||||
// LIN: %[[OFANEXT3:.+]] = getelementptr i8, i8* %[[OFA3]], i32 8
|
||||
// LIN: store i8* %[[OFANEXT3]], i8** %[[OFA_P3]]
|
||||
// LIN: %[[LOAD3:.+]] = load i16, i16* %[[BC3]]
|
||||
// LIN: store i16 %[[LOAD3]], i16*
|
||||
// WIN: %[[CUR3:.+]] = load i8*, i8** %[[ARGS]]
|
||||
// WIN: %[[NEXT3:.+]] = getelementptr inbounds i8, i8* %[[CUR3]], i64 8
|
||||
// WIN: store i8* %[[NEXT3]], i8** %[[ARGS]]
|
||||
// WIN: %[[BC3:.+]] = bitcast i8* %[[CUR3]] to i16*
|
||||
// WIN: %[[LOADV3:.+]] = load i16, i16* %[[BC3]]
|
||||
// WIN: store i16 %[[LOADV3]], i16*
|
||||
|
||||
_ExtInt(129) D = __builtin_va_arg(args, _ExtInt(129));
|
||||
// LIN: %[[AD4:.+]] = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %[[ARGS]]
|
||||
// LIN: %[[OFA_P4:.+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %[[AD4]], i32 0, i32 2
|
||||
// LIN: %[[OFA4:.+]] = load i8*, i8** %[[OFA_P4]]
|
||||
// LIN: %[[BC4:.+]] = bitcast i8* %[[OFA4]] to i129*
|
||||
// LIN: %[[OFANEXT4:.+]] = getelementptr i8, i8* %[[OFA4]], i32 24
|
||||
// LIN: store i8* %[[OFANEXT4]], i8** %[[OFA_P4]]
|
||||
// LIN: %[[LOAD4:.+]] = load i129, i129* %[[BC4]]
|
||||
// LIN: store i129 %[[LOAD4]], i129*
|
||||
// WIN: %[[CUR4:.+]] = load i8*, i8** %[[ARGS]]
|
||||
// WIN: %[[NEXT4:.+]] = getelementptr inbounds i8, i8* %[[CUR4]], i64 24
|
||||
// WIN: store i8* %[[NEXT4]], i8** %[[ARGS]]
|
||||
// WIN: %[[BC4:.+]] = bitcast i8* %[[CUR4]] to i129*
|
||||
// WIN: %[[LOADV4:.+]] = load i129, i129* %[[BC4]]
|
||||
// WIN: store i129 %[[LOADV4]], i129*
|
||||
|
||||
_ExtInt(16777200) E = __builtin_va_arg(args, _ExtInt(16777200));
|
||||
// LIN: %[[AD5:.+]] = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %[[ARGS]]
|
||||
// LIN: %[[OFA_P5:.+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %[[AD5]], i32 0, i32 2
|
||||
// LIN: %[[OFA5:.+]] = load i8*, i8** %[[OFA_P5]]
|
||||
// LIN: %[[BC5:.+]] = bitcast i8* %[[OFA5]] to i16777200*
|
||||
// LIN: %[[OFANEXT5:.+]] = getelementptr i8, i8* %[[OFA5]], i32 2097152
|
||||
// LIN: store i8* %[[OFANEXT5]], i8** %[[OFA_P5]]
|
||||
// LIN: %[[LOAD5:.+]] = load i16777200, i16777200* %[[BC5]]
|
||||
// LIN: store i16777200 %[[LOAD5]], i16777200*
|
||||
// WIN: %[[CUR5:.+]] = load i8*, i8** %[[ARGS]]
|
||||
// WIN: %[[NEXT5:.+]] = getelementptr inbounds i8, i8* %[[CUR5]], i64 2097152
|
||||
// WIN: store i8* %[[NEXT5]], i8** %[[ARGS]]
|
||||
// WIN: %[[BC5:.+]] = bitcast i8* %[[CUR5]] to i16777200*
|
||||
// WIN: %[[LOADV5:.+]] = load i16777200, i16777200* %[[BC5]]
|
||||
// WIN: store i16777200 %[[LOADV5]], i16777200*
|
||||
|
||||
__builtin_va_end(args);
|
||||
// LIN: %[[ENDAD:.+]] = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %[[ARGS]]
|
||||
// LIN: %[[ENDAD1:.+]] = bitcast %struct.__va_list_tag* %[[ENDAD]] to i8*
|
||||
// LIN: call void @llvm.va_end(i8* %[[ENDAD1]])
|
||||
// WIN: %[[ARGSEND:.+]] = bitcast i8** %[[ARGS]] to i8*
|
||||
// WIN: call void @llvm.va_end(i8* %[[ARGSEND]])
|
||||
}
|
||||
void typeid_tests() {
|
||||
// LIN: define void @_Z12typeid_testsv()
|
||||
// WIN: define dso_local void @"?typeid_tests@@YAXXZ"()
|
||||
unsigned _ExtInt(33) U33_1, U33_2;
|
||||
_ExtInt(33) S33_1, S33_2;
|
||||
_ExtInt(32) S32_1, S32_2;
|
||||
|
||||
auto A = typeid(U33_1);
|
||||
// LIN: call void @_ZNSt9type_infoC1ERKS_(%"class.std::type_info"* %{{.+}}, %"class.std::type_info"* dereferenceable(16) bitcast ({ i8*, i8* }* @_ZTIU7_ExtIntILi33EEj to %"class.std::type_info"*))
|
||||
// WIN: call %"class.std::type_info"* @"??0type_info@std@@QEAA@AEBV01@@Z"(%"class.std::type_info"* %{{.+}}, %"class.std::type_info"* dereferenceable(16) bitcast (%rtti.TypeDescriptor28* @"??_R0U?$_UExtInt@$0CB@@__clang@@@8" to %"class.std::type_info"*))
|
||||
auto B = typeid(U33_2);
|
||||
// LIN: call void @_ZNSt9type_infoC1ERKS_(%"class.std::type_info"* %{{.+}}, %"class.std::type_info"* dereferenceable(16) bitcast ({ i8*, i8* }* @_ZTIU7_ExtIntILi33EEj to %"class.std::type_info"*))
|
||||
// WIN: call %"class.std::type_info"* @"??0type_info@std@@QEAA@AEBV01@@Z"(%"class.std::type_info"* %{{.+}}, %"class.std::type_info"* dereferenceable(16) bitcast (%rtti.TypeDescriptor28* @"??_R0U?$_UExtInt@$0CB@@__clang@@@8" to %"class.std::type_info"*))
|
||||
auto C = typeid(S33_1);
|
||||
// LIN: call void @_ZNSt9type_infoC1ERKS_(%"class.std::type_info"* %{{.+}}, %"class.std::type_info"* dereferenceable(16) bitcast ({ i8*, i8* }* @_ZTIU7_ExtIntILi33EEi to %"class.std::type_info"*))
|
||||
// WIN: call %"class.std::type_info"* @"??0type_info@std@@QEAA@AEBV01@@Z"(%"class.std::type_info"* %{{.+}}, %"class.std::type_info"* dereferenceable(16) bitcast (%rtti.TypeDescriptor27* @"??_R0U?$_ExtInt@$0CB@@__clang@@@8" to %"class.std::type_info"*))
|
||||
auto D = typeid(S33_2);
|
||||
// LIN: call void @_ZNSt9type_infoC1ERKS_(%"class.std::type_info"* %{{.+}}, %"class.std::type_info"* dereferenceable(16) bitcast ({ i8*, i8* }* @_ZTIU7_ExtIntILi33EEi to %"class.std::type_info"*))
|
||||
// WIN: call %"class.std::type_info"* @"??0type_info@std@@QEAA@AEBV01@@Z"(%"class.std::type_info"* %{{.+}}, %"class.std::type_info"* dereferenceable(16) bitcast (%rtti.TypeDescriptor27* @"??_R0U?$_ExtInt@$0CB@@__clang@@@8" to %"class.std::type_info"*))
|
||||
auto E = typeid(S32_1);
|
||||
// LIN: call void @_ZNSt9type_infoC1ERKS_(%"class.std::type_info"* %{{.+}}, %"class.std::type_info"* dereferenceable(16) bitcast ({ i8*, i8* }* @_ZTIU7_ExtIntILi32EEi to %"class.std::type_info"*))
|
||||
// WIN: call %"class.std::type_info"* @"??0type_info@std@@QEAA@AEBV01@@Z"(%"class.std::type_info"* %{{.+}}, %"class.std::type_info"* dereferenceable(16) bitcast (%rtti.TypeDescriptor27* @"??_R0U?$_ExtInt@$0CA@@__clang@@@8" to %"class.std::type_info"*))
|
||||
auto F = typeid(S32_2);
|
||||
// LIN: call void @_ZNSt9type_infoC1ERKS_(%"class.std::type_info"* %{{.+}}, %"class.std::type_info"* dereferenceable(16) bitcast ({ i8*, i8* }* @_ZTIU7_ExtIntILi32EEi to %"class.std::type_info"*))
|
||||
// WIN: call %"class.std::type_info"* @"??0type_info@std@@QEAA@AEBV01@@Z"(%"class.std::type_info"* %{{.+}}, %"class.std::type_info"* dereferenceable(16) bitcast (%rtti.TypeDescriptor27* @"??_R0U?$_ExtInt@$0CA@@__clang@@@8" to %"class.std::type_info"*))
|
||||
}
|
||||
|
||||
void ExplicitCasts() {
|
||||
// LIN: define void @_Z13ExplicitCastsv()
|
||||
// WIN: define dso_local void @"?ExplicitCasts@@YAXXZ"()
|
||||
|
||||
_ExtInt(33) a;
|
||||
_ExtInt(31) b;
|
||||
int i;
|
||||
|
||||
a = i;
|
||||
// CHECK: %[[CONV:.+]] = sext i32 %{{.+}} to i33
|
||||
b = i;
|
||||
// CHECK: %[[CONV:.+]] = trunc i32 %{{.+}} to i31
|
||||
i = a;
|
||||
// CHECK: %[[CONV:.+]] = trunc i33 %{{.+}} to i32
|
||||
i = b;
|
||||
// CHECK: %[[CONV:.+]] = sext i31 %{{.+}} to i32
|
||||
}
|
||||
|
||||
struct S {
|
||||
_ExtInt(17) A;
|
||||
_ExtInt(16777200) B;
|
||||
_ExtInt(17) C;
|
||||
};
|
||||
|
||||
void OffsetOfTest() {
|
||||
// LIN: define void @_Z12OffsetOfTestv()
|
||||
// WIN: define dso_local void @"?OffsetOfTest@@YAXXZ"()
|
||||
|
||||
auto A = __builtin_offsetof(S,A);
|
||||
// CHECK: store i64 0, i64* %{{.+}}
|
||||
auto B = __builtin_offsetof(S,B);
|
||||
// CHECK: store i64 8, i64* %{{.+}}
|
||||
auto C = __builtin_offsetof(S,C);
|
||||
// CHECK: store i64 2097160, i64* %{{.+}}
|
||||
}
|
||||
|
||||
|
||||
void ShiftExtIntByConstant(_ExtInt(28) Ext) {
|
||||
// LIN: define void @_Z21ShiftExtIntByConstantU7_ExtIntILi28EEi
|
||||
// WIN: define dso_local void @"?ShiftExtIntByConstant@@YAXU?$_ExtInt@$0BM@@__clang@@@Z"
|
||||
Ext << 7;
|
||||
// CHECK: shl i28 %{{.+}}, 7
|
||||
Ext >> 7;
|
||||
// CHECK: ashr i28 %{{.+}}, 7
|
||||
Ext << -7;
|
||||
// CHECK: shl i28 %{{.+}}, -7
|
||||
Ext >> -7;
|
||||
// CHECK: ashr i28 %{{.+}}, -7
|
||||
|
||||
// UB in C/C++, Defined in OpenCL.
|
||||
Ext << 29;
|
||||
// CHECK: shl i28 %{{.+}}, 29
|
||||
Ext >> 29;
|
||||
// CHECK: ashr i28 %{{.+}}, 29
|
||||
}
|
||||
|
||||
void ConstantShiftByExtInt(_ExtInt(28) Ext, _ExtInt(65) LargeExt) {
|
||||
// LIN: define void @_Z21ConstantShiftByExtIntU7_ExtIntILi28EEiU7_ExtIntILi65EEi
|
||||
// WIN: define dso_local void @"?ConstantShiftByExtInt@@YAXU?$_ExtInt@$0BM@@__clang@@U?$_ExtInt@$0EB@@2@@Z"
|
||||
10 << Ext;
|
||||
// CHECK: %[[PROMO:.+]] = zext i28 %{{.+}} to i32
|
||||
// CHECK: shl i32 10, %[[PROMO]]
|
||||
10 >> Ext;
|
||||
// CHECK: %[[PROMO:.+]] = zext i28 %{{.+}} to i32
|
||||
// CHECK: ashr i32 10, %[[PROMO]]
|
||||
10 << LargeExt;
|
||||
// CHECK: %[[PROMO:.+]] = trunc i65 %{{.+}} to i32
|
||||
// CHECK: shl i32 10, %[[PROMO]]
|
||||
10 >> LargeExt;
|
||||
// CHECK: %[[PROMO:.+]] = trunc i65 %{{.+}} to i32
|
||||
// CHECK: ashr i32 10, %[[PROMO]]
|
||||
}
|
||||
|
||||
void Shift(_ExtInt(28) Ext, _ExtInt(65) LargeExt, int i) {
|
||||
// LIN: define void @_Z5ShiftU7_ExtIntILi28EEiU7_ExtIntILi65EEii
|
||||
// WIN: define dso_local void @"?Shift@@YAXU?$_ExtInt@$0BM@@__clang@@U?$_ExtInt@$0EB@@2@H@Z"
|
||||
i << Ext;
|
||||
// CHECK: %[[PROMO:.+]] = zext i28 %{{.+}} to i32
|
||||
// CHECK: shl i32 {{.+}}, %[[PROMO]]
|
||||
i >> Ext;
|
||||
// CHECK: %[[PROMO:.+]] = zext i28 %{{.+}} to i32
|
||||
// CHECK: ashr i32 {{.+}}, %[[PROMO]]
|
||||
|
||||
i << LargeExt;
|
||||
// CHECK: %[[PROMO:.+]] = trunc i65 %{{.+}} to i32
|
||||
// CHECK: shl i32 {{.+}}, %[[PROMO]]
|
||||
i >> LargeExt;
|
||||
// CHECK: %[[PROMO:.+]] = trunc i65 %{{.+}} to i32
|
||||
// CHECK: ashr i32 {{.+}}, %[[PROMO]]
|
||||
|
||||
Ext << i;
|
||||
// CHECK: %[[PROMO:.+]] = trunc i32 %{{.+}} to i28
|
||||
// CHECK: shl i28 {{.+}}, %[[PROMO]]
|
||||
Ext >> i;
|
||||
// CHECK: %[[PROMO:.+]] = trunc i32 %{{.+}} to i28
|
||||
// CHECK: ashr i28 {{.+}}, %[[PROMO]]
|
||||
|
||||
LargeExt << i;
|
||||
// CHECK: %[[PROMO:.+]] = zext i32 %{{.+}} to i65
|
||||
// CHECK: shl i65 {{.+}}, %[[PROMO]]
|
||||
LargeExt >> i;
|
||||
// CHECK: %[[PROMO:.+]] = zext i32 %{{.+}} to i65
|
||||
// CHECK: ashr i65 {{.+}}, %[[PROMO]]
|
||||
|
||||
Ext << LargeExt;
|
||||
// CHECK: %[[PROMO:.+]] = trunc i65 %{{.+}} to i28
|
||||
// CHECK: shl i28 {{.+}}, %[[PROMO]]
|
||||
Ext >> LargeExt;
|
||||
// CHECK: %[[PROMO:.+]] = trunc i65 %{{.+}} to i28
|
||||
// CHECK: ashr i28 {{.+}}, %[[PROMO]]
|
||||
|
||||
LargeExt << Ext;
|
||||
// CHECK: %[[PROMO:.+]] = zext i28 %{{.+}} to i65
|
||||
// CHECK: shl i65 {{.+}}, %[[PROMO]]
|
||||
LargeExt >> Ext;
|
||||
// CHECK: %[[PROMO:.+]] = zext i28 %{{.+}} to i65
|
||||
// CHECK: ashr i65 {{.+}}, %[[PROMO]]
|
||||
}
|
||||
|
||||
void ComplexTest(_Complex _ExtInt(12) first,
|
||||
_Complex _ExtInt(33) second) {
|
||||
// LIN: define void @_Z11ComplexTestCU7_ExtIntILi12EEiCU7_ExtIntILi33EEi
|
||||
// WIN: define dso_local void @"?ComplexTest@@YAXU?$_Complex@U?$_ExtInt@$0M@@__clang@@@__clang@@U?$_Complex@U?$_ExtInt@$0CB@@__clang@@@2@@Z"
|
||||
first + second;
|
||||
// CHECK: %[[FIRST_REALP:.+]] = getelementptr inbounds { i12, i12 }, { i12, i12 }* %{{.+}}, i32 0, i32 0
|
||||
// CHECK: %[[FIRST_REAL:.+]] = load i12, i12* %[[FIRST_REALP]]
|
||||
// CHECK: %[[FIRST_IMAGP:.+]] = getelementptr inbounds { i12, i12 }, { i12, i12 }* %{{.+}}, i32 0, i32 1
|
||||
// CHECK: %[[FIRST_IMAG:.+]] = load i12, i12* %[[FIRST_IMAGP]]
|
||||
// CHECK: %[[FIRST_REAL_CONV:.+]] = sext i12 %[[FIRST_REAL]]
|
||||
// CHECK: %[[FIRST_IMAG_CONV:.+]] = sext i12 %[[FIRST_IMAG]]
|
||||
// CHECK: %[[SECOND_REALP:.+]] = getelementptr inbounds { i33, i33 }, { i33, i33 }* %{{.+}}, i32 0, i32 0
|
||||
// CHECK: %[[SECOND_REAL:.+]] = load i33, i33* %[[SECOND_REALP]]
|
||||
// CHECK: %[[SECOND_IMAGP:.+]] = getelementptr inbounds { i33, i33 }, { i33, i33 }* %{{.+}}, i32 0, i32 1
|
||||
// CHECK: %[[SECOND_IMAG:.+]] = load i33, i33* %[[SECOND_IMAGP]]
|
||||
// CHECK: %[[REAL:.+]] = add i33 %[[FIRST_REAL_CONV]], %[[SECOND_REAL]]
|
||||
// CHECK: %[[IMAG:.+]] = add i33 %[[FIRST_IMAG_CONV]], %[[SECOND_IMAG]]
|
||||
}
|
||||
|
||||
// Ensure that these types don't alias the normal int types.
|
||||
void TBAATest(_ExtInt(sizeof(int) * 8) ExtInt,
|
||||
unsigned _ExtInt(sizeof(int) * 8) ExtUInt,
|
||||
_ExtInt(6) Other) {
|
||||
// CHECK-DAG: store i32 %{{.+}}, i32* %{{.+}}, align 4, !tbaa ![[EXTINT_TBAA:.+]]
|
||||
// CHECK-DAG: store i32 %{{.+}}, i32* %{{.+}}, align 4, !tbaa ![[EXTINT_TBAA]]
|
||||
// CHECK-DAG: store i6 %{{.+}}, i6* %{{.+}}, align 1, !tbaa ![[EXTINT6_TBAA:.+]]
|
||||
ExtInt = 5;
|
||||
ExtUInt = 5;
|
||||
Other = 5;
|
||||
}
|
||||
|
||||
// NoNewStructPathTBAA-DAG: ![[CHAR_TBAA_ROOT:.+]] = !{!"omnipotent char", ![[TBAA_ROOT:.+]], i64 0}
|
||||
// NoNewStructPathTBAA-DAG: ![[TBAA_ROOT]] = !{!"Simple C++ TBAA"}
|
||||
// NoNewStructPathTBAA-DAG: ![[EXTINT_TBAA]] = !{![[EXTINT_TBAA_ROOT:.+]], ![[EXTINT_TBAA_ROOT]], i64 0}
|
||||
// NoNewStructPathTBAA-DAG: ![[EXTINT_TBAA_ROOT]] = !{!"_ExtInt(32)", ![[CHAR_TBAA_ROOT]], i64 0}
|
||||
// NoNewStructPathTBAA-DAG: ![[EXTINT6_TBAA]] = !{![[EXTINT6_TBAA_ROOT:.+]], ![[EXTINT6_TBAA_ROOT]], i64 0}
|
||||
// NoNewStructPathTBAA-DAG: ![[EXTINT6_TBAA_ROOT]] = !{!"_ExtInt(6)", ![[CHAR_TBAA_ROOT]], i64 0}
|
||||
|
||||
// NewStructPathTBAA-DAG: ![[CHAR_TBAA_ROOT:.+]] = !{![[TBAA_ROOT:.+]], i64 1, !"omnipotent char"}
|
||||
// NewStructPathTBAA-DAG: ![[TBAA_ROOT]] = !{!"Simple C++ TBAA"}
|
||||
// NewStructPathTBAA-DAG: ![[EXTINT_TBAA]] = !{![[EXTINT_TBAA_ROOT:.+]], ![[EXTINT_TBAA_ROOT]], i64 0, i64 4}
|
||||
// NewStructPathTBAA-DAG: ![[EXTINT_TBAA_ROOT]] = !{![[CHAR_TBAA_ROOT]], i64 4, !"_ExtInt(32)"}
|
||||
// NewStructPathTBAA-DAG: ![[EXTINT6_TBAA]] = !{![[EXTINT6_TBAA_ROOT:.+]], ![[EXTINT6_TBAA_ROOT]], i64 0, i64 1}
|
||||
// NewStructPathTBAA-DAG: ![[EXTINT6_TBAA_ROOT]] = !{![[CHAR_TBAA_ROOT]], i64 1, !"_ExtInt(6)"}
|
|
@ -1,21 +0,0 @@
|
|||
// RUN: %clang -cc1 -triple x86_64-linux-pc -O3 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s
|
||||
|
||||
void Shifts(_ExtInt(12) E, int i) {
|
||||
E << 99;
|
||||
// CHECK: shl i12 %{{.+}}, 3
|
||||
|
||||
77 << E;
|
||||
// CHECK: %[[PROM:.+]] = zext i12 %{{.+}} to i32
|
||||
// CHECK: %[[MASK:.+]] = and i32 %[[PROM]], 31
|
||||
// CHECK: shl i32 77, %[[MASK]]
|
||||
|
||||
E << i;
|
||||
// CHECK: %[[PROM:.+]] = trunc i32 %{{.+}} to i12
|
||||
// CHECK: %[[MASK:.+]] = urem i12 %[[PROM]], 12
|
||||
// CHECK: shl i12 %{{.+}}, %[[MASK]]
|
||||
|
||||
i << E;
|
||||
// CHECK: %[[PROM:.+]] = zext i12 %{{.+}} to i32
|
||||
// CHECK: %[[MASK:.+]] = and i32 %[[PROM]], 31
|
||||
// CHECK: shl i32 %{{.+}}, %[[MASK]]
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
// expected-error@+5{{expected ')'}}
|
||||
// expected-note@+4{{to match this '('}}
|
||||
// expected-error@+3{{expected unqualified-id}}
|
||||
// expected-error@+2{{extraneous closing brace}}
|
||||
// expected-error@+1{{C++ requires a type specifier for all declarations}}
|
||||
_ExtInt(32} a;
|
||||
// expected-error@+2{{expected expression}}
|
||||
// expected-error@+1{{C++ requires a type specifier for all declarations}}
|
||||
_ExtInt(32* ) b;
|
||||
// expected-error@+3{{expected '('}}
|
||||
// expected-error@+2{{expected unqualified-id}}
|
||||
// expected-error@+1{{C++ requires a type specifier for all declarations}}
|
||||
_ExtInt{32} c;
|
|
@ -1,278 +0,0 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s -Wimplicit-int-conversion
|
||||
|
||||
template<int Bounds>
|
||||
struct HasExtInt {
|
||||
_ExtInt(Bounds) b;
|
||||
unsigned _ExtInt(Bounds) b2;
|
||||
};
|
||||
|
||||
// Delcaring variables:
|
||||
_ExtInt(33) Declarations(_ExtInt(48) &Param) { // Useable in params and returns.
|
||||
short _ExtInt(43) a; // expected-error {{'short _ExtInt' is invalid}}
|
||||
_ExtInt(43) long b; // expected-error {{'long _ExtInt' is invalid}}
|
||||
|
||||
// These should all be fine:
|
||||
const _ExtInt(5) c = 3;
|
||||
const unsigned _ExtInt(5) d; // expected-error {{default initialization of an object of const type 'const unsigned _ExtInt(5)'}}
|
||||
unsigned _ExtInt(5) e = 5;
|
||||
_ExtInt(5) unsigned f;
|
||||
|
||||
_ExtInt(-3) g; // expected-error{{signed _ExtInt must have a bit size of at least 2}}
|
||||
_ExtInt(0) h; // expected-error{{signed _ExtInt must have a bit size of at least 2}}
|
||||
_ExtInt(1) i; // expected-error{{signed _ExtInt must have a bit size of at least 2}}
|
||||
_ExtInt(2) j;;
|
||||
unsigned _ExtInt(0) k;// expected-error{{unsigned _ExtInt must have a bit size of at least 1}}
|
||||
unsigned _ExtInt(1) l;
|
||||
signed _ExtInt(1) m; // expected-error{{signed _ExtInt must have a bit size of at least 2}}
|
||||
|
||||
constexpr _ExtInt(6) n = 33; // expected-warning{{implicit conversion from 'int' to 'const _ExtInt(6)' changes value from 33 to -31}}
|
||||
constexpr _ExtInt(7) o = 33;
|
||||
|
||||
// Check LLVM imposed max size.
|
||||
_ExtInt(0xFFFFFFFFFF) p; // expected-error {{signed _ExtInt of bit sizes greater than 16777215 not supported}}
|
||||
unsigned _ExtInt(0xFFFFFFFFFF) q; // expected-error {{unsigned _ExtInt of bit sizes greater than 16777215 not supported}}
|
||||
|
||||
// Ensure template params are instantiated correctly.
|
||||
// expected-error@5{{signed _ExtInt must have a bit size of at least 2}}
|
||||
// expected-error@6{{unsigned _ExtInt must have a bit size of at least 1}}
|
||||
// expected-note@+1{{in instantiation of template class }}
|
||||
HasExtInt<-1> r;
|
||||
// expected-error@5{{signed _ExtInt must have a bit size of at least 2}}
|
||||
// expected-error@6{{unsigned _ExtInt must have a bit size of at least 1}}
|
||||
// expected-note@+1{{in instantiation of template class }}
|
||||
HasExtInt<0> s;
|
||||
// expected-error@5{{signed _ExtInt must have a bit size of at least 2}}
|
||||
// expected-note@+1{{in instantiation of template class }}
|
||||
HasExtInt<1> t;
|
||||
HasExtInt<2> u;
|
||||
|
||||
_ExtInt(-3.0) v; // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'double'}}
|
||||
_ExtInt(3.0) x; // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'double'}}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <_ExtInt(5) I>
|
||||
struct ExtIntTemplParam {
|
||||
static constexpr _ExtInt(5) Var = I;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void deduced_whole_type(T){}
|
||||
template<int I>
|
||||
void deduced_bound(_ExtInt(I)){}
|
||||
|
||||
// Ensure ext-int can be used in template places.
|
||||
void Templates() {
|
||||
ExtIntTemplParam<13> a;
|
||||
constexpr _ExtInt(3) b = 1;
|
||||
ExtIntTemplParam<b> c;
|
||||
constexpr _ExtInt(9) d = 1;
|
||||
ExtIntTemplParam<b> e;
|
||||
|
||||
deduced_whole_type(b);
|
||||
deduced_bound(b);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
struct is_same {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
template <typename T>
|
||||
struct is_same<T,T> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
// Reject vector types:
|
||||
// expected-error@+1{{invalid vector element type '_ExtInt(32)'}}
|
||||
typedef _ExtInt(32) __attribute__((vector_size(16))) VecTy;
|
||||
|
||||
// Allow _Complex:
|
||||
_Complex _ExtInt(3) Cmplx;
|
||||
|
||||
// Reject cases of _Atomic:
|
||||
// expected-error@+1{{_Atomic cannot be applied to integer type '_ExtInt(4)' with less than 1 byte of precision}}
|
||||
_Atomic _ExtInt(4) TooSmallAtomic;
|
||||
// expected-error@+1{{_Atomic cannot be applied to integer type '_ExtInt(9)' with a non power of 2 precision}}
|
||||
_Atomic _ExtInt(9) NotPow2Atomic;
|
||||
_Atomic _ExtInt(128) JustRightAtomic;
|
||||
|
||||
// Test result types of Unary/Bitwise/Binary Operations:
|
||||
void Ops() {
|
||||
_ExtInt(43) x43_s = 1, y43_s = 1;
|
||||
_ExtInt(sizeof(int) * 8) x32_s = 1, y32_s = 1;
|
||||
unsigned _ExtInt(sizeof(unsigned) * 8) x32_u = 1, y32_u = 1;
|
||||
_ExtInt(4) x4_s = 1, y4_s = 1;
|
||||
unsigned _ExtInt(43) x43_u = 1, y43_u = 1;
|
||||
unsigned _ExtInt(4) x4_u = 1, y4_u = 1;
|
||||
int x_int = 1, y_int = 1;
|
||||
unsigned x_uint = 1, y_uint = 1;
|
||||
bool b;
|
||||
|
||||
// Disabling mixed conversions:
|
||||
// Signed/unsigned mixed.
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_u + y43_s;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x4_s - y4_u;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_s * y43_u;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x4_u / y4_s;
|
||||
|
||||
// Different Sizes.
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_s + y4_s;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_s - y4_u;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_u * y4_u;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x4_u / y43_u;
|
||||
|
||||
// Mixed with standard types.
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_s + x_int;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_u - x_int;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x32_s * x_int;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x32_u / x_int;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x32_s * x_uint;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x32_u / x_uint;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x4_s + x_int;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x4_u - x_int;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x4_s + b;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x4_u - b;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_s + b;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_u - b;
|
||||
|
||||
// Bitwise checks.
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_s % y4_u;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_u % y4_s;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x4_s | y43_u;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x4_u | y43_s;
|
||||
|
||||
// compassign.
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_s += 33;
|
||||
|
||||
// Comparisons.
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x43_s > 33;
|
||||
// expected-error@+1{{invalid operands to binary expression}}
|
||||
x4_s > 33;
|
||||
|
||||
// Same size/sign ops don't change type.
|
||||
static_assert(is_same<decltype(x43_s + y43_s), _ExtInt(43)>::value,"");
|
||||
static_assert(is_same<decltype(x4_s - y4_s), _ExtInt(4)>::value,"");
|
||||
static_assert(is_same<decltype(x43_u * y43_u), unsigned _ExtInt(43)>::value,"");
|
||||
static_assert(is_same<decltype(x4_u / y4_u), unsigned _ExtInt(4)>::value,"");
|
||||
|
||||
// Unary ops shouldn't go through integer promotions.
|
||||
static_assert(is_same<decltype(~x43_s), _ExtInt(43)>::value,"");
|
||||
static_assert(is_same<decltype(~x4_s), _ExtInt(4)>::value,"");
|
||||
static_assert(is_same<decltype(+x43_s), _ExtInt(43)>::value,"");
|
||||
static_assert(is_same<decltype(+x4_s), _ExtInt(4)>::value,"");
|
||||
static_assert(is_same<decltype(-x43_u), unsigned _ExtInt(43)>::value,"");
|
||||
static_assert(is_same<decltype(-x4_u), unsigned _ExtInt(4)>::value,"");
|
||||
// expected-warning@+1{{expression with side effects has no effect in an unevaluated context}}
|
||||
static_assert(is_same<decltype(++x43_s), _ExtInt(43)&>::value,"");
|
||||
// expected-warning@+1{{expression with side effects has no effect in an unevaluated context}}
|
||||
static_assert(is_same<decltype(--x4_s), _ExtInt(4)&>::value,"");
|
||||
// expected-warning@+1{{expression with side effects has no effect in an unevaluated context}}
|
||||
static_assert(is_same<decltype(x43_s--), _ExtInt(43)>::value,"");
|
||||
// expected-warning@+1{{expression with side effects has no effect in an unevaluated context}}
|
||||
static_assert(is_same<decltype(x4_s++), _ExtInt(4)>::value,"");
|
||||
static_assert(is_same<decltype(x4_s >> 1), _ExtInt(4)>::value,"");
|
||||
static_assert(is_same<decltype(x4_u << 1), unsigned _ExtInt(4)>::value,"");
|
||||
|
||||
static_assert(sizeof(x43_s) == 8, "");
|
||||
static_assert(sizeof(x4_s) == 1, "");
|
||||
|
||||
static_assert(sizeof(_ExtInt(3340)) == 424, ""); // 424 * 8 == 3392.
|
||||
static_assert(sizeof(_ExtInt(1049)) == 136, ""); // 136 * 8 == 1088.
|
||||
|
||||
static_assert(alignof(decltype(x43_s)) == 8, "");
|
||||
static_assert(alignof(decltype(x4_s)) == 1, "");
|
||||
|
||||
static_assert(alignof(_ExtInt(3340)) == 8, "");
|
||||
static_assert(alignof(_ExtInt(1049)) == 8, "");
|
||||
}
|
||||
|
||||
constexpr int func() { return 42;}
|
||||
|
||||
void ConstexprBitsize() {
|
||||
_ExtInt(func()) F;
|
||||
static_assert(is_same<decltype(F), _ExtInt(42)>::value, "");
|
||||
}
|
||||
|
||||
// Useable as an underlying type.
|
||||
enum AsEnumUnderlyingType : _ExtInt(33) {
|
||||
};
|
||||
|
||||
void overloaded(int);
|
||||
void overloaded(_ExtInt(32));
|
||||
void overloaded(_ExtInt(33));
|
||||
void overloaded(short);
|
||||
//expected-note@+1{{candidate function}}
|
||||
void overloaded2(_ExtInt(32));
|
||||
//expected-note@+1{{candidate function}}
|
||||
void overloaded2(_ExtInt(33));
|
||||
//expected-note@+1{{candidate function}}
|
||||
void overloaded2(short);
|
||||
|
||||
void overload_use() {
|
||||
int i;
|
||||
_ExtInt(32) i32;
|
||||
_ExtInt(33) i33;
|
||||
short s;
|
||||
|
||||
// All of these get their corresponding exact matches.
|
||||
overloaded(i);
|
||||
overloaded(i32);
|
||||
overloaded(i33);
|
||||
overloaded(s);
|
||||
|
||||
overloaded2(i); // expected-error{{call to 'overloaded2' is ambiguous}}
|
||||
|
||||
overloaded2(i32);
|
||||
|
||||
overloaded2(s);
|
||||
}
|
||||
|
||||
// no errors expected, this should 'just work'.
|
||||
struct UsedAsBitField {
|
||||
_ExtInt(3) F : 3;
|
||||
_ExtInt(3) G : 3;
|
||||
_ExtInt(3) H : 3;
|
||||
};
|
||||
|
||||
// expected-error@+1{{mode attribute only supported for integer and floating-point types}}
|
||||
typedef _ExtInt(33) IllegalMode __attribute__((mode(DI)));
|
||||
|
||||
void ImplicitCasts(_ExtInt(31) s31, _ExtInt(33) s33, int i) {
|
||||
// expected-warning@+1{{implicit conversion loses integer precision}}
|
||||
s31 = i;
|
||||
// expected-warning@+1{{implicit conversion loses integer precision}}
|
||||
s31 = s33;
|
||||
s33 = i;
|
||||
s33 = s31;
|
||||
i = s31;
|
||||
// expected-warning@+1{{implicit conversion loses integer precision}}
|
||||
i = s33;
|
||||
}
|
||||
|
|
@ -1793,8 +1793,6 @@ DEFAULT_TYPELOC_IMPL(Enum, TagType)
|
|||
DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
|
||||
DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
|
||||
DEFAULT_TYPELOC_IMPL(Auto, Type)
|
||||
DEFAULT_TYPELOC_IMPL(ExtInt, Type)
|
||||
DEFAULT_TYPELOC_IMPL(DependentExtInt, Type)
|
||||
|
||||
bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
|
||||
// Visit the nested-name-specifier, if present.
|
||||
|
|
Loading…
Reference in New Issue