зеркало из https://github.com/microsoft/clang-1.git
Compress bit fields / enums from ReferenceType, BuiltinType, FunctionType, and
ObjCObjectType into Type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116472 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
008df5dce3
Коммит
71c3673d1e
|
@ -809,6 +809,8 @@ private:
|
|||
/// \brief FromAST - Whether this type comes from an AST file.
|
||||
mutable bool FromAST : 1;
|
||||
|
||||
unsigned SpareBit : 1;
|
||||
|
||||
/// \brief Set whether this type comes from an AST file.
|
||||
void setFromAST(bool V = true) const {
|
||||
FromAST = V;
|
||||
|
@ -818,8 +820,37 @@ protected:
|
|||
/// \brief Compute the linkage of this type along with the presence of
|
||||
/// any local or unnamed types.
|
||||
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||
|
||||
enum { BitsRemainingInType = 17 };
|
||||
|
||||
unsigned SubclassBits : 16;
|
||||
|
||||
#define BITFIELD(Name, Previous, N) \
|
||||
static unsigned Encode##Name(unsigned V) { \
|
||||
assert(!((V << Name##Offset) & ~Name##Mask) && \
|
||||
#Name " value out of range"); \
|
||||
return (V << Name##Offset); \
|
||||
} \
|
||||
static unsigned Decode##Name(unsigned Bits) { \
|
||||
return (Bits & Name##Mask) >> Name##Offset; \
|
||||
} \
|
||||
enum { \
|
||||
Name##Width = (N), \
|
||||
Name##Offset = Previous##Offset + Previous##Width, \
|
||||
Name##Mask = ((1 << (N)) - 1) << Name##Offset \
|
||||
}
|
||||
#define BOOL_BITFIELD(Name, Previous) \
|
||||
static unsigned Encode##Name(bool V) { \
|
||||
return (V ? Name##Mask : 0); \
|
||||
} \
|
||||
static bool Decode##Name(unsigned Bits) { \
|
||||
return (Bits & Name##Mask) != 0; \
|
||||
} \
|
||||
enum { \
|
||||
Name##Width = 1, \
|
||||
Name##Offset = Previous##Offset + Previous##Width, \
|
||||
Name##Mask = 1 << Name##Offset \
|
||||
}
|
||||
#define InitialBitfieldWidth 0
|
||||
#define InitialBitfieldOffset 0
|
||||
|
||||
// silence VC++ warning C4355: 'this' : used in base member initializer list
|
||||
Type *this_() { return this; }
|
||||
|
@ -1149,8 +1180,8 @@ public:
|
|||
|
||||
ObjCSel // This represents the ObjC 'SEL' type.
|
||||
};
|
||||
private:
|
||||
Kind TypeKind;
|
||||
|
||||
// SubclassBits stores a Kind.
|
||||
|
||||
protected:
|
||||
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||
|
@ -1158,37 +1189,38 @@ protected:
|
|||
public:
|
||||
BuiltinType(Kind K)
|
||||
: Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
|
||||
/*VariablyModified=*/false),
|
||||
TypeKind(K) {}
|
||||
/*VariablyModified=*/false) {
|
||||
SubclassBits = K;
|
||||
}
|
||||
|
||||
Kind getKind() const { return TypeKind; }
|
||||
Kind getKind() const { return static_cast<Kind>(SubclassBits); }
|
||||
const char *getName(const LangOptions &LO) const;
|
||||
|
||||
bool isSugared() const { return false; }
|
||||
QualType desugar() const { return QualType(this, 0); }
|
||||
|
||||
bool isInteger() const {
|
||||
return TypeKind >= Bool && TypeKind <= Int128;
|
||||
return getKind() >= Bool && getKind() <= Int128;
|
||||
}
|
||||
|
||||
bool isSignedInteger() const {
|
||||
return TypeKind >= Char_S && TypeKind <= Int128;
|
||||
return getKind() >= Char_S && getKind() <= Int128;
|
||||
}
|
||||
|
||||
bool isUnsignedInteger() const {
|
||||
return TypeKind >= Bool && TypeKind <= UInt128;
|
||||
return getKind() >= Bool && getKind() <= UInt128;
|
||||
}
|
||||
|
||||
bool isFloatingPoint() const {
|
||||
return TypeKind >= Float && TypeKind <= LongDouble;
|
||||
return getKind() >= Float && getKind() <= LongDouble;
|
||||
}
|
||||
|
||||
/// Determines whether this type is a "forbidden" placeholder type,
|
||||
/// i.e. a type which cannot appear in arbitrary positions in a
|
||||
/// fully-formed expression.
|
||||
bool isPlaceholderType() const {
|
||||
return TypeKind == Overload ||
|
||||
TypeKind == UndeducedAuto;
|
||||
return getKind() == Overload ||
|
||||
getKind() == UndeducedAuto;
|
||||
}
|
||||
|
||||
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
|
||||
|
@ -1313,38 +1345,38 @@ class ReferenceType : public Type, public llvm::FoldingSetNode {
|
|||
/// ref &&a; // lvalue, inner ref
|
||||
/// rvref &a; // lvalue, inner ref, spelled lvalue
|
||||
/// rvref &&a; // rvalue, inner ref
|
||||
bool SpelledAsLValue;
|
||||
BOOL_BITFIELD(SpelledAsLValue, InitialBitfield);
|
||||
|
||||
/// True if the inner type is a reference type. This only happens
|
||||
/// in non-canonical forms.
|
||||
bool InnerRef;
|
||||
BOOL_BITFIELD(InnerRef, SpelledAsLValue);
|
||||
|
||||
protected:
|
||||
ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
|
||||
bool SpelledAsLValue) :
|
||||
Type(tc, CanonicalRef, Referencee->isDependentType(),
|
||||
Referencee->isVariablyModifiedType()),
|
||||
PointeeType(Referencee), SpelledAsLValue(SpelledAsLValue),
|
||||
InnerRef(Referencee->isReferenceType()) {
|
||||
Referencee->isVariablyModifiedType()), PointeeType(Referencee) {
|
||||
SubclassBits = EncodeSpelledAsLValue(SpelledAsLValue) |
|
||||
EncodeInnerRef(Referencee->isReferenceType());
|
||||
}
|
||||
|
||||
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||
|
||||
public:
|
||||
bool isSpelledAsLValue() const { return SpelledAsLValue; }
|
||||
bool isInnerRef() const { return InnerRef; }
|
||||
bool isSpelledAsLValue() const { return SubclassBits & SpelledAsLValueMask; }
|
||||
bool isInnerRef() const { return SubclassBits & InnerRefMask; }
|
||||
|
||||
QualType getPointeeTypeAsWritten() const { return PointeeType; }
|
||||
QualType getPointeeType() const {
|
||||
// FIXME: this might strip inner qualifiers; okay?
|
||||
const ReferenceType *T = this;
|
||||
while (T->InnerRef)
|
||||
while (T->isInnerRef())
|
||||
T = T->PointeeType->getAs<ReferenceType>();
|
||||
return T->PointeeType;
|
||||
}
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, PointeeType, SpelledAsLValue);
|
||||
Profile(ID, PointeeType, isSpelledAsLValue());
|
||||
}
|
||||
static void Profile(llvm::FoldingSetNodeID &ID,
|
||||
QualType Referencee,
|
||||
|
@ -1464,13 +1496,12 @@ private:
|
|||
/// ElementType - The element type of the array.
|
||||
QualType ElementType;
|
||||
|
||||
// NOTE: VC++ treats enums as signed, avoid using the ArraySizeModifier enum
|
||||
/// NOTE: These fields are packed into the bitfields space in the Type class.
|
||||
unsigned SizeModifier : 2;
|
||||
// IndexTypeQuals - Capture qualifiers in declarations like:
|
||||
// 'int X[static restrict 4]'. For function parameters only.
|
||||
enum { IndexTypeQualsMask = 0x7 };
|
||||
|
||||
/// IndexTypeQuals - Capture qualifiers in declarations like:
|
||||
/// 'int X[static restrict 4]'. For function parameters only.
|
||||
unsigned IndexTypeQuals : 3;
|
||||
// NOTE: VC++ treats enums as signed, avoid using the ArraySizeModifier enum
|
||||
enum { SizeModifierMask = 0x18, SizeModifierOffset = 3 };
|
||||
|
||||
protected:
|
||||
// C++ [temp.dep.type]p1:
|
||||
|
@ -1482,7 +1513,9 @@ protected:
|
|||
ArraySizeModifier sm, unsigned tq)
|
||||
: Type(tc, can, et->isDependentType() || tc == DependentSizedArray,
|
||||
(tc == VariableArray || et->isVariablyModifiedType())),
|
||||
ElementType(et), SizeModifier(sm), IndexTypeQuals(tq) {}
|
||||
ElementType(et) {
|
||||
SubclassBits = tq | (static_cast<unsigned>(sm) << SizeModifierOffset);
|
||||
}
|
||||
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
|
||||
|
@ -1491,12 +1524,14 @@ protected:
|
|||
public:
|
||||
QualType getElementType() const { return ElementType; }
|
||||
ArraySizeModifier getSizeModifier() const {
|
||||
return ArraySizeModifier(SizeModifier);
|
||||
return ArraySizeModifier(SubclassBits >> SizeModifierOffset);
|
||||
}
|
||||
Qualifiers getIndexTypeQualifiers() const {
|
||||
return Qualifiers::fromCVRMask(IndexTypeQuals);
|
||||
return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers());
|
||||
}
|
||||
unsigned getIndexTypeCVRQualifiers() const {
|
||||
return SubclassBits & IndexTypeQualsMask;
|
||||
}
|
||||
unsigned getIndexTypeCVRQualifiers() const { return IndexTypeQuals; }
|
||||
|
||||
static bool classof(const Type *T) {
|
||||
return T->getTypeClass() == ConstantArray ||
|
||||
|
@ -1770,23 +1805,27 @@ protected:
|
|||
/// ElementType - The element type of the vector.
|
||||
QualType ElementType;
|
||||
|
||||
/// NumElements - The number of elements in the vector.
|
||||
unsigned NumElements;
|
||||
// NumElements - The number of elements in the vector.
|
||||
enum { NumElementsOffset = 2 };
|
||||
|
||||
AltiVecSpecific AltiVecSpec;
|
||||
// AltiVecSpec
|
||||
enum { AltiVecSpecMask = 0x3 };
|
||||
|
||||
VectorType(QualType vecType, unsigned nElements, QualType canonType,
|
||||
AltiVecSpecific altiVecSpec) :
|
||||
Type(Vector, canonType, vecType->isDependentType(),
|
||||
vecType->isVariablyModifiedType()),
|
||||
ElementType(vecType), NumElements(nElements), AltiVecSpec(altiVecSpec) {}
|
||||
vecType->isVariablyModifiedType()), ElementType(vecType) {
|
||||
SubclassBits = (nElements << NumElementsOffset) |
|
||||
static_cast<unsigned>(altiVecSpec);
|
||||
}
|
||||
|
||||
VectorType(TypeClass tc, QualType vecType, unsigned nElements,
|
||||
QualType canonType, AltiVecSpecific altiVecSpec)
|
||||
: Type(tc, canonType, vecType->isDependentType(),
|
||||
vecType->isVariablyModifiedType()),
|
||||
ElementType(vecType),
|
||||
NumElements(nElements), AltiVecSpec(altiVecSpec) {}
|
||||
vecType->isVariablyModifiedType()), ElementType(vecType) {
|
||||
SubclassBits = (nElements << NumElementsOffset) |
|
||||
static_cast<unsigned>(altiVecSpec);
|
||||
}
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
|
||||
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||
|
@ -1794,19 +1833,22 @@ protected:
|
|||
public:
|
||||
|
||||
QualType getElementType() const { return ElementType; }
|
||||
unsigned getNumElements() const { return NumElements; }
|
||||
unsigned getNumElements() const { return SubclassBits >> NumElementsOffset; }
|
||||
|
||||
bool isSugared() const { return false; }
|
||||
QualType desugar() const { return QualType(this, 0); }
|
||||
|
||||
AltiVecSpecific getAltiVecSpecific() const { return AltiVecSpec; }
|
||||
AltiVecSpecific getAltiVecSpecific() const {
|
||||
return AltiVecSpecific(SubclassBits & AltiVecSpecMask);
|
||||
}
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, getElementType(), getNumElements(), getTypeClass(), AltiVecSpec);
|
||||
Profile(ID, getElementType(), getNumElements(),
|
||||
getTypeClass(), getAltiVecSpecific());
|
||||
}
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
|
||||
unsigned NumElements, TypeClass TypeClass,
|
||||
unsigned AltiVecSpec) {
|
||||
AltiVecSpecific AltiVecSpec) {
|
||||
ID.AddPointer(ElementType.getAsOpaquePtr());
|
||||
ID.AddInteger(NumElements);
|
||||
ID.AddInteger(TypeClass);
|
||||
|
@ -1873,7 +1915,7 @@ public:
|
|||
|
||||
bool isAccessorWithinNumElements(char c) const {
|
||||
if (int idx = getAccessorIdx(c)+1)
|
||||
return unsigned(idx-1) < NumElements;
|
||||
return unsigned(idx-1) < getNumElements();
|
||||
return false;
|
||||
}
|
||||
bool isSugared() const { return false; }
|
||||
|
@ -1890,10 +1932,23 @@ public:
|
|||
///
|
||||
class FunctionType : public Type {
|
||||
virtual void ANCHOR(); // Key function for FunctionType.
|
||||
|
||||
/// SubClassData - This field is owned by the subclass, put here to pack
|
||||
/// tightly with the ivars in Type.
|
||||
bool SubClassData : 1;
|
||||
|
||||
/// CallConv - The calling convention used by the function, as specified via
|
||||
/// __attribute__((cdecl|stdcall|fastcall|thiscall|pascal)).
|
||||
BITFIELD(CallConv, InitialBitfield, 3);
|
||||
|
||||
/// NoReturn - Indicates if the function type has __attribute__((noreturn)).
|
||||
BOOL_BITFIELD(NoReturn, CallConv);
|
||||
|
||||
/// RegParm - How many arguments to pass inreg.
|
||||
/// The value passed to __attribute__((regparm(x)))
|
||||
BITFIELD(RegParm, NoReturn, 3);
|
||||
|
||||
BITFIELD(ExtInfo, InitialBitfield,
|
||||
CallConvWidth + NoReturnWidth + RegParmWidth);
|
||||
|
||||
/// SubclassInfo
|
||||
BOOL_BITFIELD(SubclassInfo, RegParm);
|
||||
|
||||
/// TypeQuals - Used only by FunctionProtoType, put here to pack with the
|
||||
/// other bitfields.
|
||||
|
@ -1901,17 +1956,7 @@ class FunctionType : public Type {
|
|||
///
|
||||
/// C++ 8.3.5p4: The return type, the parameter type list and the
|
||||
/// cv-qualifier-seq, [...], are part of the function type.
|
||||
///
|
||||
unsigned TypeQuals : 3;
|
||||
|
||||
/// NoReturn - Indicates if the function type is attribute noreturn.
|
||||
unsigned NoReturn : 1;
|
||||
|
||||
/// RegParm - How many arguments to pass inreg.
|
||||
unsigned RegParm : 3;
|
||||
|
||||
/// CallConv - The calling convention used by the function.
|
||||
unsigned CallConv : 3;
|
||||
BITFIELD(TypeQuals, SubclassInfo, 3);
|
||||
|
||||
// The type returned by the function.
|
||||
QualType ResultType;
|
||||
|
@ -1935,73 +1980,86 @@ class FunctionType : public Type {
|
|||
// * Codegen
|
||||
|
||||
class ExtInfo {
|
||||
/// Laid out the same way as they are on FunctionType.
|
||||
unsigned Bits;
|
||||
|
||||
ExtInfo(unsigned Bits) : Bits(Bits) {}
|
||||
|
||||
friend class FunctionType;
|
||||
|
||||
public:
|
||||
// Constructor with no defaults. Use this when you know that you
|
||||
// have all the elements (when reading an AST file for example).
|
||||
ExtInfo(bool noReturn, unsigned regParm, CallingConv cc) :
|
||||
NoReturn(noReturn), RegParm(regParm), CC(cc) {}
|
||||
ExtInfo(bool noReturn, unsigned regParm, CallingConv cc) {
|
||||
Bits = EncodeCallConv(cc) |
|
||||
EncodeNoReturn(noReturn) |
|
||||
EncodeRegParm(regParm);
|
||||
}
|
||||
|
||||
// Constructor with all defaults. Use when for example creating a
|
||||
// function know to use defaults.
|
||||
ExtInfo() : NoReturn(false), RegParm(0), CC(CC_Default) {}
|
||||
ExtInfo() : Bits(0) {}
|
||||
|
||||
bool getNoReturn() const { return NoReturn; }
|
||||
unsigned getRegParm() const { return RegParm; }
|
||||
CallingConv getCC() const { return CC; }
|
||||
bool getNoReturn() const { return DecodeNoReturn(Bits); }
|
||||
unsigned getRegParm() const { return DecodeRegParm(Bits); }
|
||||
CallingConv getCC() const { return CallingConv(DecodeCallConv(Bits)); }
|
||||
|
||||
bool operator==(const ExtInfo &Other) const {
|
||||
return getNoReturn() == Other.getNoReturn() &&
|
||||
getRegParm() == Other.getRegParm() &&
|
||||
getCC() == Other.getCC();
|
||||
bool operator==(ExtInfo Other) const {
|
||||
return Bits == Other.Bits;
|
||||
}
|
||||
bool operator!=(const ExtInfo &Other) const {
|
||||
return !(*this == Other);
|
||||
bool operator!=(ExtInfo Other) const {
|
||||
return Bits != Other.Bits;
|
||||
}
|
||||
|
||||
// Note that we don't have setters. That is by design, use
|
||||
// the following with methods instead of mutating these objects.
|
||||
|
||||
ExtInfo withNoReturn(bool noReturn) const {
|
||||
return ExtInfo(noReturn, getRegParm(), getCC());
|
||||
if (noReturn)
|
||||
return ExtInfo(Bits | NoReturnMask);
|
||||
else
|
||||
return ExtInfo(Bits & ~NoReturnMask);
|
||||
}
|
||||
|
||||
ExtInfo withRegParm(unsigned RegParm) const {
|
||||
return ExtInfo(getNoReturn(), RegParm, getCC());
|
||||
return ExtInfo((Bits & ~RegParmMask) | EncodeRegParm(RegParm));
|
||||
}
|
||||
|
||||
ExtInfo withCallingConv(CallingConv cc) const {
|
||||
return ExtInfo(getNoReturn(), getRegParm(), cc);
|
||||
return ExtInfo((Bits & ~CallConvMask) | EncodeCallConv(cc));
|
||||
}
|
||||
|
||||
private:
|
||||
// True if we have __attribute__((noreturn))
|
||||
bool NoReturn;
|
||||
// The value passed to __attribute__((regparm(x)))
|
||||
unsigned RegParm;
|
||||
// The calling convention as specified via
|
||||
// __attribute__((cdecl|stdcall|fastcall|thiscall|pascal))
|
||||
CallingConv CC;
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
ID.AddInteger(Bits);
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
FunctionType(TypeClass tc, QualType res, bool SubclassInfo,
|
||||
unsigned typeQuals, QualType Canonical, bool Dependent,
|
||||
bool VariablyModified, const ExtInfo &Info)
|
||||
: Type(tc, Canonical, Dependent, VariablyModified),
|
||||
SubClassData(SubclassInfo), TypeQuals(typeQuals),
|
||||
NoReturn(Info.getNoReturn()),
|
||||
RegParm(Info.getRegParm()), CallConv(Info.getCC()), ResultType(res) {}
|
||||
bool getSubClassData() const { return SubClassData; }
|
||||
unsigned getTypeQuals() const { return TypeQuals; }
|
||||
bool VariablyModified, ExtInfo Info)
|
||||
: Type(tc, Canonical, Dependent, VariablyModified), ResultType(res) {
|
||||
SubclassBits = EncodeExtInfo(Info.Bits) |
|
||||
EncodeSubclassInfo(SubclassInfo) |
|
||||
EncodeTypeQuals(typeQuals);
|
||||
}
|
||||
bool getSubClassData() const { return DecodeSubclassInfo(SubclassBits); }
|
||||
unsigned getTypeQuals() const { return DecodeTypeQuals(SubclassBits); }
|
||||
public:
|
||||
|
||||
QualType getResultType() const { return ResultType; }
|
||||
|
||||
unsigned getRegParmType() const { return RegParm; }
|
||||
bool getNoReturnAttr() const { return NoReturn; }
|
||||
CallingConv getCallConv() const { return (CallingConv)CallConv; }
|
||||
unsigned getRegParmType() const {
|
||||
return DecodeRegParm(SubclassBits);
|
||||
}
|
||||
bool getNoReturnAttr() const {
|
||||
return DecodeNoReturn(SubclassBits);
|
||||
}
|
||||
CallingConv getCallConv() const {
|
||||
return static_cast<CallingConv>(DecodeCallConv(SubclassBits));
|
||||
}
|
||||
ExtInfo getExtInfo() const {
|
||||
return ExtInfo(NoReturn, RegParm, (CallingConv)CallConv);
|
||||
return ExtInfo(DecodeExtInfo(SubclassBits));
|
||||
}
|
||||
|
||||
/// \brief Determine the type of an expression that calls a function of
|
||||
|
@ -2022,8 +2080,7 @@ public:
|
|||
/// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has
|
||||
/// no information available about its arguments.
|
||||
class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||
FunctionNoProtoType(QualType Result, QualType Canonical,
|
||||
const ExtInfo &Info)
|
||||
FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
|
||||
: FunctionType(FunctionNoProto, Result, false, 0, Canonical,
|
||||
/*Dependent=*/false, Result->isVariablyModifiedType(),
|
||||
Info) {}
|
||||
|
@ -2042,10 +2099,8 @@ public:
|
|||
Profile(ID, getResultType(), getExtInfo());
|
||||
}
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
|
||||
const ExtInfo &Info) {
|
||||
ID.AddInteger(Info.getCC());
|
||||
ID.AddInteger(Info.getRegParm());
|
||||
ID.AddInteger(Info.getNoReturn());
|
||||
ExtInfo Info) {
|
||||
Info.Profile(ID);
|
||||
ID.AddPointer(ResultType.getAsOpaquePtr());
|
||||
}
|
||||
|
||||
|
@ -2141,7 +2196,7 @@ public:
|
|||
bool isVariadic, unsigned TypeQuals,
|
||||
bool hasExceptionSpec, bool anyExceptionSpec,
|
||||
unsigned NumExceptions, exception_iterator Exs,
|
||||
const ExtInfo &ExtInfo);
|
||||
ExtInfo ExtInfo);
|
||||
};
|
||||
|
||||
|
||||
|
@ -2964,19 +3019,15 @@ public:
|
|||
/// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually
|
||||
/// this should get its own sugar class to better represent the source.
|
||||
class ObjCObjectType : public Type {
|
||||
// Pad the bit count up so that NumProtocols is 2-byte aligned
|
||||
unsigned : BitsRemainingInType - 16;
|
||||
|
||||
/// \brief The number of protocols stored after the
|
||||
/// ObjCObjectPointerType node.
|
||||
///
|
||||
/// These protocols are those written directly on the type. If
|
||||
/// protocol qualifiers ever become additive, the iterators will
|
||||
/// get kindof complicated.
|
||||
///
|
||||
/// In the canonical object type, these are sorted alphabetically
|
||||
/// and uniqued.
|
||||
unsigned NumProtocols : 16;
|
||||
// SubclassBits stores a count of number of protocols stored after
|
||||
// the ObjCObjectPointerType node.
|
||||
//
|
||||
// These protocols are those written directly on the type. If
|
||||
// protocol qualifiers ever become additive, the iterators will need
|
||||
// to get kindof complicated.
|
||||
//
|
||||
// In the canonical object type, these are sorted alphabetically
|
||||
// and uniqued.
|
||||
|
||||
/// Either a BuiltinType or an InterfaceType or sugar for either.
|
||||
QualType BaseType;
|
||||
|
@ -2994,8 +3045,9 @@ protected:
|
|||
enum Nonce_ObjCInterface { Nonce_ObjCInterface };
|
||||
ObjCObjectType(enum Nonce_ObjCInterface)
|
||||
: Type(ObjCInterface, QualType(), false, false),
|
||||
NumProtocols(0),
|
||||
BaseType(QualType(this_(), 0)) {}
|
||||
BaseType(QualType(this_(), 0)) {
|
||||
SubclassBits = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const; // key function
|
||||
|
@ -3040,7 +3092,7 @@ public:
|
|||
|
||||
/// getNumProtocols - Return the number of qualifying protocols in this
|
||||
/// interface type, or 0 if there are none.
|
||||
unsigned getNumProtocols() const { return NumProtocols; }
|
||||
unsigned getNumProtocols() const { return SubclassBits; }
|
||||
|
||||
/// \brief Fetch a protocol by index.
|
||||
ObjCProtocolDecl *getProtocol(unsigned I) const {
|
||||
|
@ -3712,4 +3764,8 @@ template <typename T> const T *Type::getAs() const {
|
|||
|
||||
} // end namespace clang
|
||||
|
||||
#undef BITFIELD
|
||||
#undef InitialBitfieldWidth
|
||||
#undef InitialBitfieldOffset
|
||||
|
||||
#endif
|
||||
|
|
|
@ -982,9 +982,8 @@ def err_cconv_knr : Error<
|
|||
def err_cconv_varargs : Error<
|
||||
"variadic function cannot use %0 calling convention">;
|
||||
def err_regparm_mismatch : Error<"function declared with with regparm(%0) "
|
||||
"attribute was previously declared %plural{0:without the regparm|1:"
|
||||
"with the regparm(1)|2:with the regparm(2)|3:with the regparm(3)|:with the"
|
||||
"regparm}1 attribute">;
|
||||
"attribute was previously declared "
|
||||
"%plural{0:without the regparm|:with the regparm(%1)}1 attribute">;
|
||||
def warn_label_attribute_not_unused : Warning<
|
||||
"The only valid attribute for labels is 'unused'">;
|
||||
|
||||
|
|
|
@ -311,9 +311,9 @@ ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
|
|||
ObjCProtocolDecl * const *Protocols,
|
||||
unsigned NumProtocols)
|
||||
: Type(ObjCObject, Canonical, false, false),
|
||||
NumProtocols(NumProtocols),
|
||||
BaseType(Base) {
|
||||
assert(this->NumProtocols == NumProtocols &&
|
||||
SubclassBits = NumProtocols;
|
||||
assert(getNumProtocols() == NumProtocols &&
|
||||
"bitfield overflow in protocol count");
|
||||
if (NumProtocols)
|
||||
memcpy(getProtocolStorage(), Protocols,
|
||||
|
@ -1026,7 +1026,7 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
|
|||
unsigned TypeQuals, bool hasExceptionSpec,
|
||||
bool anyExceptionSpec, unsigned NumExceptions,
|
||||
exception_iterator Exs,
|
||||
const FunctionType::ExtInfo &Info) {
|
||||
FunctionType::ExtInfo Info) {
|
||||
ID.AddPointer(Result.getAsOpaquePtr());
|
||||
for (unsigned i = 0; i != NumArgs; ++i)
|
||||
ID.AddPointer(ArgTys[i].getAsOpaquePtr());
|
||||
|
@ -1038,9 +1038,7 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
|
|||
for (unsigned i = 0; i != NumExceptions; ++i)
|
||||
ID.AddPointer(Exs[i].getAsOpaquePtr());
|
||||
}
|
||||
ID.AddInteger(Info.getNoReturn());
|
||||
ID.AddInteger(Info.getRegParm());
|
||||
ID.AddInteger(Info.getCC());
|
||||
Info.Profile(ID);
|
||||
}
|
||||
|
||||
void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче