forked from OSchip/llvm-project
Revert 131377, 131369 and 131365.
131365 caused PR9927. llvm-svn: 131401
This commit is contained in:
parent
d6f1518cc9
commit
c0d4cb17c1
|
@ -1568,13 +1568,7 @@ private:
|
|||
bool ExpandStructures,
|
||||
const FieldDecl *Field,
|
||||
bool OutermostType = false,
|
||||
bool EncodingProperty = false,
|
||||
bool StructField = false) const;
|
||||
|
||||
// Adds the encoding of the structure's members.
|
||||
void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
|
||||
const FieldDecl *Field,
|
||||
bool includeVBases = true) const;
|
||||
bool EncodingProperty = false) const;
|
||||
|
||||
const ASTRecordLayout &
|
||||
getObjCLayout(const ObjCInterfaceDecl *D,
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "CXXABI.h"
|
||||
#include <map>
|
||||
|
||||
using namespace clang;
|
||||
|
||||
|
@ -4153,8 +4152,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
|
|||
bool ExpandStructures,
|
||||
const FieldDecl *FD,
|
||||
bool OutermostType,
|
||||
bool EncodingProperty,
|
||||
bool StructField) const {
|
||||
bool EncodingProperty) const {
|
||||
if (T->getAs<BuiltinType>()) {
|
||||
if (FD && FD->isBitField())
|
||||
return EncodeBitField(this, S, T, FD);
|
||||
|
@ -4239,7 +4237,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
|
|||
if (const ArrayType *AT =
|
||||
// Ignore type qualifiers etc.
|
||||
dyn_cast<ArrayType>(T->getCanonicalTypeInternal())) {
|
||||
if (isa<IncompleteArrayType>(AT) && !StructField) {
|
||||
if (isa<IncompleteArrayType>(AT)) {
|
||||
// Incomplete arrays are encoded as a pointer to the array element.
|
||||
S += '^';
|
||||
|
||||
|
@ -4248,15 +4246,11 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
|
|||
} else {
|
||||
S += '[';
|
||||
|
||||
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
|
||||
if (getTypeSize(CAT->getElementType()) == 0)
|
||||
S += '0';
|
||||
else
|
||||
S += llvm::utostr(CAT->getSize().getZExtValue());
|
||||
} else {
|
||||
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
|
||||
S += llvm::utostr(CAT->getSize().getZExtValue());
|
||||
else {
|
||||
//Variable length arrays are encoded as a regular array with 0 elements.
|
||||
assert((isa<VariableArrayType>(AT) || isa<IncompleteArrayType>(AT)) &&
|
||||
"Unknown array type!");
|
||||
assert(isa<VariableArrayType>(AT) && "Unknown array type!");
|
||||
S += '0';
|
||||
}
|
||||
|
||||
|
@ -4294,30 +4288,24 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
|
|||
}
|
||||
if (ExpandStructures) {
|
||||
S += '=';
|
||||
if (!RDecl->isUnion()) {
|
||||
getObjCEncodingForStructureImpl(RDecl, S, FD);
|
||||
} else {
|
||||
for (RecordDecl::field_iterator Field = RDecl->field_begin(),
|
||||
FieldEnd = RDecl->field_end();
|
||||
Field != FieldEnd; ++Field) {
|
||||
if (FD) {
|
||||
S += '"';
|
||||
S += Field->getNameAsString();
|
||||
S += '"';
|
||||
}
|
||||
for (RecordDecl::field_iterator Field = RDecl->field_begin(),
|
||||
FieldEnd = RDecl->field_end();
|
||||
Field != FieldEnd; ++Field) {
|
||||
if (FD) {
|
||||
S += '"';
|
||||
S += Field->getNameAsString();
|
||||
S += '"';
|
||||
}
|
||||
|
||||
// Special case bit-fields.
|
||||
if (Field->isBitField()) {
|
||||
getObjCEncodingForTypeImpl(Field->getType(), S, false, true,
|
||||
(*Field));
|
||||
} else {
|
||||
QualType qt = Field->getType();
|
||||
getLegacyIntegralTypeEncoding(qt);
|
||||
getObjCEncodingForTypeImpl(qt, S, false, true,
|
||||
FD, /*OutermostType*/false,
|
||||
/*EncodingProperty*/false,
|
||||
/*StructField*/true);
|
||||
}
|
||||
// Special case bit-fields.
|
||||
if (Field->isBitField()) {
|
||||
getObjCEncodingForTypeImpl(Field->getType(), S, false, true,
|
||||
(*Field));
|
||||
} else {
|
||||
QualType qt = Field->getType();
|
||||
getLegacyIntegralTypeEncoding(qt);
|
||||
getObjCEncodingForTypeImpl(qt, S, false, true,
|
||||
FD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4438,134 +4426,6 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
|
|||
assert(0 && "@encode for type not implemented!");
|
||||
}
|
||||
|
||||
void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
|
||||
std::string &S,
|
||||
const FieldDecl *FD,
|
||||
bool includeVBases) const {
|
||||
assert(RDecl && "Expected non-null RecordDecl");
|
||||
assert(!RDecl->isUnion() && "Should not be called for unions");
|
||||
if (!RDecl->getDefinition())
|
||||
return;
|
||||
|
||||
CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(RDecl);
|
||||
std::multimap<uint64_t, NamedDecl *> FieldOrBaseOffsets;
|
||||
const ASTRecordLayout &layout = getASTRecordLayout(RDecl);
|
||||
|
||||
if (CXXRec) {
|
||||
for (CXXRecordDecl::base_class_iterator
|
||||
BI = CXXRec->bases_begin(),
|
||||
BE = CXXRec->bases_end(); BI != BE; ++BI) {
|
||||
if (!BI->isVirtual()) {
|
||||
CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
|
||||
uint64_t offs = layout.getBaseClassOffsetInBits(base);
|
||||
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
|
||||
std::make_pair(offs, base));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned i = 0;
|
||||
for (RecordDecl::field_iterator Field = RDecl->field_begin(),
|
||||
FieldEnd = RDecl->field_end();
|
||||
Field != FieldEnd; ++Field, ++i) {
|
||||
uint64_t offs = layout.getFieldOffset(i);
|
||||
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
|
||||
std::make_pair(offs, *Field));
|
||||
}
|
||||
|
||||
if (CXXRec && includeVBases) {
|
||||
for (CXXRecordDecl::base_class_iterator
|
||||
BI = CXXRec->vbases_begin(),
|
||||
BE = CXXRec->vbases_end(); BI != BE; ++BI) {
|
||||
CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
|
||||
uint64_t offs = layout.getVBaseClassOffsetInBits(base);
|
||||
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
|
||||
std::make_pair(offs, base));
|
||||
}
|
||||
}
|
||||
|
||||
CharUnits size;
|
||||
if (CXXRec) {
|
||||
size = includeVBases ? layout.getSize() : layout.getNonVirtualSize();
|
||||
} else {
|
||||
size = layout.getSize();
|
||||
}
|
||||
|
||||
uint64_t CurOffs = 0;
|
||||
std::multimap<uint64_t, NamedDecl *>::iterator
|
||||
CurLayObj = FieldOrBaseOffsets.begin();
|
||||
|
||||
if (CurLayObj != FieldOrBaseOffsets.end() && CurLayObj->first != 0) {
|
||||
assert(CXXRec && CXXRec->isDynamicClass() &&
|
||||
"Offset 0 was empty but no VTable ?");
|
||||
if (FD) {
|
||||
S += "\"_vptr$";
|
||||
std::string recname = CXXRec->getNameAsString();
|
||||
if (recname.empty()) recname = "?";
|
||||
S += recname;
|
||||
S += '"';
|
||||
}
|
||||
S += "^^?";
|
||||
CurOffs += getTypeSize(VoidPtrTy);
|
||||
}
|
||||
|
||||
if (!RDecl->hasFlexibleArrayMember()) {
|
||||
// Mark the end of the structure.
|
||||
uint64_t offs = toBits(size);
|
||||
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
|
||||
std::make_pair(offs, (NamedDecl*)0));
|
||||
}
|
||||
|
||||
for (; CurLayObj != FieldOrBaseOffsets.end(); ++CurLayObj) {
|
||||
assert(CurOffs <= CurLayObj->first);
|
||||
|
||||
if (CurOffs < CurLayObj->first) {
|
||||
uint64_t padding = CurLayObj->first - CurOffs;
|
||||
// FIXME: There doesn't seem to be a way to indicate in the encoding that
|
||||
// packing/alignment of members is different that normal, in which case
|
||||
// the encoding will be out-of-sync with the real layout.
|
||||
// If the runtime switches to just consider the size of types without
|
||||
// taking into account alignment, we could make padding explicit in the
|
||||
// encoding (e.g. using arrays of chars). The encoding strings would be
|
||||
// longer then though.
|
||||
CurOffs += padding;
|
||||
}
|
||||
|
||||
NamedDecl *dcl = CurLayObj->second;
|
||||
if (dcl == 0)
|
||||
break; // reached end of structure.
|
||||
|
||||
if (CXXRecordDecl *base = dyn_cast<CXXRecordDecl>(dcl)) {
|
||||
// We expand the bases without their virtual bases since those are going
|
||||
// in the initial structure. Note that this differs from gcc which
|
||||
// expands virtual bases each time one is encountered in the hierarchy,
|
||||
// making the encoding type bigger than it really is.
|
||||
getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false);
|
||||
CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize());
|
||||
} else {
|
||||
FieldDecl *field = cast<FieldDecl>(dcl);
|
||||
if (FD) {
|
||||
S += '"';
|
||||
S += field->getNameAsString();
|
||||
S += '"';
|
||||
}
|
||||
|
||||
if (field->isBitField()) {
|
||||
EncodeBitField(this, S, field->getType(), field);
|
||||
CurOffs += field->getBitWidth()->EvaluateAsInt(*this).getZExtValue();
|
||||
} else {
|
||||
QualType qt = field->getType();
|
||||
getLegacyIntegralTypeEncoding(qt);
|
||||
getObjCEncodingForTypeImpl(qt, S, false, true, FD,
|
||||
/*OutermostType*/false,
|
||||
/*EncodingProperty*/false,
|
||||
/*StructField*/true);
|
||||
CurOffs += getTypeSize(field->getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
|
||||
std::string& S) const {
|
||||
if (QT & Decl::OBJC_TQ_In)
|
||||
|
|
|
@ -144,20 +144,3 @@ struct s8 {
|
|||
long double x;
|
||||
};
|
||||
const char g8[] = @encode(struct s8);
|
||||
|
||||
// CHECK: @g9 = constant [11 x i8] c"{S9=i[0i]}\00"
|
||||
struct S9 {
|
||||
int x;
|
||||
int flex[];
|
||||
};
|
||||
const char g9[] = @encode(struct S9);
|
||||
|
||||
struct f
|
||||
{
|
||||
int i;
|
||||
struct{} g[4];
|
||||
int tt;
|
||||
};
|
||||
|
||||
// CHECK: @g10 = constant [14 x i8] c"{f=i[0{?=}]i}\00"
|
||||
const char g10[] = @encode(struct f);
|
||||
|
|
|
@ -62,60 +62,3 @@ typedef float HGVec4f __attribute__ ((vector_size(16)));
|
|||
@implementation RedBalloonHGXFormWrapper
|
||||
@end
|
||||
|
||||
// rdar://9357400
|
||||
namespace rdar9357400 {
|
||||
template<int Dim1 = -1, int Dim2 = -1> struct fixed {
|
||||
template<int D> struct rebind { typedef fixed<D> other; };
|
||||
};
|
||||
|
||||
template<typename Element, int Size>
|
||||
class fixed_1D
|
||||
{
|
||||
public:
|
||||
typedef Element value_type;
|
||||
typedef value_type array_impl[Size];
|
||||
protected:
|
||||
array_impl m_data;
|
||||
};
|
||||
|
||||
template<typename Element, typename Alloc>
|
||||
class vector;
|
||||
|
||||
template<typename Element, int Size>
|
||||
class vector< Element, fixed<Size> >
|
||||
: public fixed_1D<Element,Size> { };
|
||||
|
||||
typedef vector< float, fixed<4> > vector4f;
|
||||
|
||||
// CHECK: @_ZN11rdar9357400L2ggE = internal constant [49 x i8] c"{vector<float, rdar9357400::fixed<4, -1> >=[4f]}\00"
|
||||
const char gg[] = @encode(vector4f);
|
||||
}
|
||||
|
||||
struct Base1 {
|
||||
char x;
|
||||
};
|
||||
|
||||
struct DBase : public Base1 {
|
||||
double x;
|
||||
virtual ~DBase();
|
||||
};
|
||||
|
||||
struct Sub_with_virt : virtual DBase {
|
||||
long x;
|
||||
};
|
||||
|
||||
struct Sub2 : public Sub_with_virt, public Base1, virtual DBase {
|
||||
float x;
|
||||
};
|
||||
|
||||
// CHECK: @_ZL2g1 = internal constant [10 x i8] c"{Base1=c}\00"
|
||||
const char g1[] = @encode(Base1);
|
||||
|
||||
// CHECK: @_ZL2g2 = internal constant [14 x i8] c"{DBase=^^?cd}\00"
|
||||
const char g2[] = @encode(DBase);
|
||||
|
||||
// CHECK: @_ZL2g3 = internal constant [26 x i8] c"{Sub_with_virt=^^?q^^?cd}\00"
|
||||
const char g3[] = @encode(Sub_with_virt);
|
||||
|
||||
// CHECK: @_ZL2g4 = internal constant [19 x i8] c"{Sub2=^^?qcf^^?cd}\00"
|
||||
const char g4[] = @encode(Sub2);
|
||||
|
|
Loading…
Reference in New Issue