Temporarily revert 114929 114925 114924 114921. It looked like they (or at least

one of them) was causing a series of failures:

http://google1.osuosl.org:8011/builders/clang-x86_64-darwin10-selfhost/builds/4518

svn merge -c -114929 https://llvm.org/svn/llvm-project/cfe/trunk
--- Reverse-merging r114929 into '.':
U    include/clang/Sema/Sema.h
U    include/clang/AST/DeclCXX.h
U    lib/Sema/SemaDeclCXX.cpp
U    lib/Sema/SemaTemplateInstantiateDecl.cpp
U    lib/Sema/SemaDecl.cpp
U    lib/Sema/SemaTemplateInstantiate.cpp
U    lib/AST/DeclCXX.cpp
svn merge -c -114925 https://llvm.org/svn/llvm-project/cfe/trunk
--- Reverse-merging r114925 into '.':
G    include/clang/AST/DeclCXX.h
G    lib/Sema/SemaDeclCXX.cpp
G    lib/AST/DeclCXX.cpp
svn merge -c -114924 https://llvm.org/svn/llvm-project/cfe/trunk
--- Reverse-merging r114924 into '.':
G    include/clang/AST/DeclCXX.h
G    lib/Sema/SemaDeclCXX.cpp
G    lib/Sema/SemaDecl.cpp
G    lib/AST/DeclCXX.cpp
U    lib/AST/ASTContext.cpp
svn merge -c -114921 https://llvm.org/svn/llvm-project/cfe/trunk
--- Reverse-merging r114921 into '.':
G    include/clang/AST/DeclCXX.h
G    lib/Sema/SemaDeclCXX.cpp
G    lib/Sema/SemaDecl.cpp
G    lib/AST/DeclCXX.cpp



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114933 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2010-09-28 01:09:49 +00:00
Родитель e10288c1e9
Коммит 2a674e8e44
11 изменённых файлов: 259 добавлений и 231 удалений

Просмотреть файл

@ -688,22 +688,40 @@ public:
/// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1).
bool isAggregate() const { return data().Aggregate; }
/// setAggregate - Set whether this class is an aggregate (C++
/// [dcl.init.aggr]).
void setAggregate(bool Agg) { data().Aggregate = Agg; }
/// setMethodAsVirtual - Make input method virtual and set the necesssary
/// special function bits and other bits accordingly.
void setMethodAsVirtual(FunctionDecl *Method);
/// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class
/// that is an aggregate that has no non-static non-POD data members, no
/// reference data members, no user-defined copy assignment operator and no
/// user-defined destructor.
bool isPOD() const { return data().PlainOldData; }
/// setPOD - Set whether this class is a POD-type (C++ [class]p4).
void setPOD(bool POD) { data().PlainOldData = POD; }
/// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which
/// means it has a virtual function, virtual base, data member (other than
/// 0-width bit-field) or inherits from a non-empty class. Does NOT include
/// a check for union-ness.
bool isEmpty() const { return data().Empty; }
/// Set whether this class is empty (C++0x [meta.unary.prop])
void setEmpty(bool Emp) { data().Empty = Emp; }
/// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]),
/// which means that the class contains or inherits a virtual function.
bool isPolymorphic() const { return data().Polymorphic; }
/// setPolymorphic - Set whether this class is polymorphic (C++
/// [class.virtual]).
void setPolymorphic(bool Poly) { data().Polymorphic = Poly; }
/// isAbstract - Whether this class is abstract (C++ [class.abstract]),
/// which means that the class contains or inherits a pure virtual function.
bool isAbstract() const { return data().Abstract; }
@ -715,22 +733,42 @@ public:
// (C++ [class.ctor]p5)
bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
// setHasTrivialConstructor - Set whether this class has a trivial constructor
// (C++ [class.ctor]p5)
void setHasTrivialConstructor(bool TC) { data().HasTrivialConstructor = TC; }
// hasTrivialCopyConstructor - Whether this class has a trivial copy
// constructor (C++ [class.copy]p6)
bool hasTrivialCopyConstructor() const {
return data().HasTrivialCopyConstructor;
}
// setHasTrivialCopyConstructor - Set whether this class has a trivial
// copy constructor (C++ [class.copy]p6)
void setHasTrivialCopyConstructor(bool TC) {
data().HasTrivialCopyConstructor = TC;
}
// hasTrivialCopyAssignment - Whether this class has a trivial copy
// assignment operator (C++ [class.copy]p11)
bool hasTrivialCopyAssignment() const {
return data().HasTrivialCopyAssignment;
}
// setHasTrivialCopyAssignment - Set whether this class has a
// trivial copy assignment operator (C++ [class.copy]p11)
void setHasTrivialCopyAssignment(bool TC) {
data().HasTrivialCopyAssignment = TC;
}
// hasTrivialDestructor - Whether this class has a trivial destructor
// (C++ [class.dtor]p3)
bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
// setHasTrivialDestructor - Set whether this class has a trivial destructor
// (C++ [class.dtor]p3)
void setHasTrivialDestructor(bool TC) { data().HasTrivialDestructor = TC; }
/// \brief If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
///

Просмотреть файл

@ -2584,6 +2584,13 @@ public:
bool Virtual, AccessSpecifier Access,
TypeSourceInfo *TInfo);
/// SetClassDeclAttributesFromBase - Copies class decl traits
/// (such as whether the class has a trivial constructor,
/// trivial destructor etc) from the given base class.
void SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
const CXXRecordDecl *BaseClass,
bool BaseIsVirtual);
BaseResult ActOnBaseSpecifier(Decl *classdecl,
SourceRange SpecifierRange,
bool Virtual, AccessSpecifier Access,

Просмотреть файл

@ -3138,6 +3138,10 @@ QualType ASTContext::getObjCFastEnumerationStateType() {
Field->setAccess(AS_public);
ObjCFastEnumerationStateTypeDecl->addDecl(Field);
}
if (getLangOptions().CPlusPlus)
if (CXXRecordDecl *CXXRD =
dyn_cast<CXXRecordDecl>(ObjCFastEnumerationStateTypeDecl))
CXXRD->setEmpty(false);
ObjCFastEnumerationStateTypeDecl->completeDefinition();
}

Просмотреть файл

@ -97,25 +97,6 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
// C++ [dcl.init.aggr]p1:
// An aggregate is [...] a class with [...] no base classes [...].
data().Aggregate = false;
// C++ [class]p4:
// A POD-struct is an aggregate class...
data().PlainOldData = false;
// A class with a non-empty base class is not empty.
// FIXME: Standard ref?
if (!BaseClassDecl->isEmpty())
data().Empty = false;
// C++ [class.virtual]p1:
// A class that declares or inherits a virtual function is called a
// polymorphic class.
if (BaseClassDecl->isPolymorphic())
data().Polymorphic = true;
// Now go through all virtual bases of this base and add them.
for (CXXRecordDecl::base_class_iterator VBase =
BaseClassDecl->vbases_begin(),
@ -129,50 +110,8 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
// Add this base if it's not already in the list.
if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)))
VBases.push_back(Base);
// C++0x [meta.unary.prop] is_empty:
// T is a class type, but not a union type, with ... no virtual base
// classes
data().Empty = false;
// C++ [class.ctor]p5:
// A constructor is trivial if its class has no virtual base classes.
data().HasTrivialConstructor = false;
// C++ [class.copy]p6:
// A copy constructor is trivial if its class has no virtual base
// classes.
data().HasTrivialCopyConstructor = false;
// C++ [class.copy]p11:
// A copy assignment operator is trivial if its class has no virtual
// base classes.
data().HasTrivialCopyAssignment = false;
} else {
// C++ [class.ctor]p5:
// A constructor is trivial if all the direct base classes of its
// class have trivial constructors.
if (!BaseClassDecl->hasTrivialConstructor())
data().HasTrivialConstructor = false;
// C++ [class.copy]p6:
// A copy constructor is trivial if all the direct base classes of its
// class have trivial copy constructors.
if (!BaseClassDecl->hasTrivialCopyConstructor())
data().HasTrivialCopyConstructor = false;
// C++ [class.copy]p11:
// A copy assignment operator is trivial if all the direct base classes
// of its class have trivial copy assignment operators.
if (!BaseClassDecl->hasTrivialCopyAssignment())
data().HasTrivialCopyAssignment = false;
}
// C++ [class.ctor]p3:
// A destructor is trivial if all the direct base classes of its class
// have trivial destructors.
if (!BaseClassDecl->hasTrivialDestructor())
data().HasTrivialDestructor = false;
}
if (VBases.empty())
@ -329,33 +268,6 @@ CXXRecordDecl::addedMember(Decl *D) {
if (FunTmpl)
D = FunTmpl->getTemplatedDecl();
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
if (Method->isVirtual()) {
// C++ [dcl.init.aggr]p1:
// An aggregate is an array or a class with [...] no virtual functions.
data().Aggregate = false;
// C++ [class]p4:
// A POD-struct is an aggregate class...
data().PlainOldData = false;
// Virtual functions make the class non-empty.
// FIXME: Standard ref?
data().Empty = false;
// C++ [class.virtual]p1:
// A class that declares or inherits a virtual function is called a
// polymorphic class.
data().Polymorphic = true;
// None of the special member functions are trivial.
data().HasTrivialConstructor = false;
data().HasTrivialCopyConstructor = false;
data().HasTrivialCopyAssignment = false;
// FIXME: Destructor?
}
}
if (D->isImplicit()) {
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
// If this is the implicit default constructor, note that we have now
@ -422,19 +334,6 @@ CXXRecordDecl::addedMember(Decl *D) {
if (isa<CXXDestructorDecl>(D)) {
data().DeclaredDestructor = true;
data().UserDeclaredDestructor = true;
// C++ [class]p4:
// A POD-struct is an aggregate class that has [...] no user-defined
// destructor.
data().PlainOldData = false;
// C++ [class.dtor]p3:
// A destructor is trivial if it is an implicitly-declared destructor and
// [...].
//
// FIXME: C++0x: don't do this for "= default" destructors
data().HasTrivialDestructor = false;
return;
}
@ -483,57 +382,6 @@ CXXRecordDecl::addedMember(Decl *D) {
return;
}
// Handle non-static data members.
if (FieldDecl *Field = dyn_cast<FieldDecl>(D)) {
// C++ [dcl.init.aggr]p1:
// An aggregate is an array or a class (clause 9) with [...] no
// private or protected non-static data members (clause 11).
//
// A POD must be an aggregate.
if (D->getAccess() == AS_private || D->getAccess() == AS_protected) {
data().Aggregate = false;
data().PlainOldData = false;
}
// C++ [class]p9:
// A POD struct is a class that is both a trivial class and a
// standard-layout class, and has no non-static data members of type
// non-POD struct, non-POD union (or array of such types).
ASTContext &Context = getASTContext();
QualType T = Context.getBaseElementType(Field->getType());
if (!T->isPODType())
data().PlainOldData = false;
if (T->isReferenceType())
data().HasTrivialConstructor = false;
if (const RecordType *RecordTy = T->getAs<RecordType>()) {
CXXRecordDecl* FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl());
if (FieldRec->getDefinition()) {
if (!FieldRec->hasTrivialConstructor())
data().HasTrivialConstructor = false;
if (!FieldRec->hasTrivialCopyConstructor())
data().HasTrivialCopyConstructor = false;
if (!FieldRec->hasTrivialCopyAssignment())
data().HasTrivialCopyAssignment = false;
if (!FieldRec->hasTrivialDestructor())
data().HasTrivialDestructor = false;
}
}
// If this is not a zero-length bit-field, then the class is not empty.
if (data().Empty) {
if (!Field->getBitWidth())
data().Empty = false;
else if (!Field->getBitWidth()->isTypeDependent() &&
!Field->getBitWidth()->isValueDependent()) {
llvm::APSInt Bits;
if (Field->getBitWidth()->isIntegerConstantExpr(Bits, Context))
if (!!Bits)
data().Empty = false;
}
}
}
}
static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
@ -716,6 +564,17 @@ void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) {
llvm_unreachable("conversion not found in set!");
}
void CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) {
Method->setVirtualAsWritten(true);
setAggregate(false);
setPOD(false);
setEmpty(false);
setPolymorphic(true);
setHasTrivialConstructor(false);
setHasTrivialCopyConstructor(false);
setHasTrivialCopyAssignment(false);
}
CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());

Просмотреть файл

@ -1869,6 +1869,33 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
}
}
llvm::Value *
CodeGenFunction::BuildVector(const llvm::SmallVectorImpl<llvm::Value*> &Ops) {
assert((Ops.size() & (Ops.size() - 1)) == 0 &&
"Not a power-of-two sized vector!");
bool AllConstants = true;
for (unsigned I = 0, E = Ops.size(); I != E && AllConstants; ++I)
AllConstants &= isa<Constant>(Ops[I]);
// If this is a constant vector, create a ConstantVector.
if (AllConstants) {
std::vector<Constant*> CstOps;
for (unsigned I = 0, E = Ops.size(); I != E; ++I)
CstOps.push_back(cast<Constant>(Ops[I]));
return ConstantVector::get(CstOps);
}
// Otherwise, insertelement the values to build the vector.
Value *Result =
llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size()));
for (unsigned I = 0, E = Ops.size(); I != E; ++I)
Result = Builder.CreateInsertElement(Result, Ops[I],
llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), I));
return Result;
}
Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
@ -1986,6 +2013,11 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
llvm::Function *F = CGM.getIntrinsic(ID);
return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
}
case X86::BI__builtin_ia32_vec_init_v8qi:
case X86::BI__builtin_ia32_vec_init_v4hi:
case X86::BI__builtin_ia32_vec_init_v2si:
return Builder.CreateBitCast(BuildVector(Ops),
llvm::Type::getX86_MMXTy(VMContext));
case X86::BI__builtin_ia32_cmpps: {
llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps);
return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpps");
@ -2035,37 +2067,6 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
return Builder.CreateStore(Ops[1], Ops[0]);
}
case X86::BI__builtin_ia32_palignr: {
unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
// If palignr is shifting the pair of input vectors less than 9 bytes,
// emit a shuffle instruction.
if (shiftVal <= 8) {
llvm::SmallVector<llvm::Constant*, 8> Indices;
for (unsigned i = 0; i != 8; ++i)
Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i));
Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size());
return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr");
}
// If palignr is shifting the pair of input vectors more than 8 but less
// than 16 bytes, emit a logical right shift of the destination.
if (shiftVal < 16) {
// MMX has these as 1 x i64 vectors for some odd optimization reasons.
const llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 1);
Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast");
Ops[1] = llvm::ConstantInt::get(VecTy, (shiftVal-8) * 8);
// create i32 constant
llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_mmx_psrl_q);
return Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr");
}
// If palignr is shifting the pair of vectors more than 32 bytes, emit zero.
return llvm::Constant::getNullValue(ConvertType(E->getType()));
}
case X86::BI__builtin_ia32_palignr128: {
unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();

Просмотреть файл

@ -536,6 +536,9 @@ public:
llvm::BasicBlock *getInvokeDestImpl();
// Build a vector out of the supplied Values.
llvm::Value *BuildVector(const llvm::SmallVectorImpl<llvm::Value*> &Ops);
public:
/// ObjCEHValueStack - Stack of Objective-C exception values, used for
/// rethrows.

Просмотреть файл

@ -43,14 +43,13 @@ _mm_empty(void)
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_cvtsi32_si64(int __i)
{
return (__m64)(__v2si){__i, 0};
return (__m64)__builtin_ia32_vec_init_v2si(__i, 0);
}
static __inline__ int __attribute__((__always_inline__, __nodebug__))
_mm_cvtsi64_si32(__m64 __m)
{
__v2si __mmx_var2 = (__v2si)__m;
return __mmx_var2[0];
return __builtin_ia32_vec_ext_v2si((__v2si)__m, 0);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
@ -86,59 +85,55 @@ _mm_packs_pu16(__m64 __m1, __m64 __m2)
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_unpackhi_pi8(__m64 __m1, __m64 __m2)
{
return (__m64)__builtin_shufflevector((__v8qi)__m1, (__v8qi)__m2, 4, 8+4, 5,
8+5, 6, 8+6, 7, 8+7);
return (__m64)__builtin_ia32_punpckhbw((__v8qi)__m1, (__v8qi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_unpackhi_pi16(__m64 __m1, __m64 __m2)
{
return (__m64)__builtin_shufflevector((__v4hi)__m1, (__v4hi)__m2, 2, 4+2, 3,
4+3);
return (__m64)__builtin_ia32_punpckhwd((__v4hi)__m1, (__v4hi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_unpackhi_pi32(__m64 __m1, __m64 __m2)
{
return (__m64)__builtin_shufflevector((__v2si)__m1, (__v2si)__m2, 1, 2+1);
return (__m64)__builtin_ia32_punpckhdq((__v2si)__m1, (__v2si)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_unpacklo_pi8(__m64 __m1, __m64 __m2)
{
return (__m64)__builtin_shufflevector((__v8qi)__m1, (__v8qi)__m2, 0, 8+0, 1,
8+1, 2, 8+2, 3, 8+3);
return (__m64)__builtin_ia32_punpcklbw((__v8qi)__m1, (__v8qi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_unpacklo_pi16(__m64 __m1, __m64 __m2)
{
return (__m64)__builtin_shufflevector((__v4hi)__m1, (__v4hi)__m2, 0, 4+0, 1,
4+1);
return (__m64)__builtin_ia32_punpcklwd((__v4hi)__m1, (__v4hi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_unpacklo_pi32(__m64 __m1, __m64 __m2)
{
return (__m64)__builtin_shufflevector((__v2si)__m1, (__v2si)__m2, 0, 2+0);
return (__m64)__builtin_ia32_punpckldq((__v2si)__m1, (__v2si)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_add_pi8(__m64 __m1, __m64 __m2)
{
return (__m64)((__v8qi)__m1 + (__v8qi)__m2);
return (__m64)__builtin_ia32_paddb((__v8qi)__m1, (__v8qi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_add_pi16(__m64 __m1, __m64 __m2)
{
return (__m64)((__v4hi)__m1 + (__v4hi)__m2);
return (__m64)__builtin_ia32_paddw((__v4hi)__m1, (__v4hi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_add_pi32(__m64 __m1, __m64 __m2)
{
return (__m64)((__v2si)__m1 + (__v2si)__m2);
return (__m64)__builtin_ia32_paddd((__v2si)__m1, (__v2si)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
@ -168,19 +163,19 @@ _mm_adds_pu16(__m64 __m1, __m64 __m2)
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_sub_pi8(__m64 __m1, __m64 __m2)
{
return (__m64)((__v8qi)__m1 - (__v8qi)__m2);
return (__m64)__builtin_ia32_psubb((__v8qi)__m1, (__v8qi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_sub_pi16(__m64 __m1, __m64 __m2)
{
return (__m64)((__v4hi)__m1 - (__v4hi)__m2);
return (__m64)__builtin_ia32_psubw((__v4hi)__m1, (__v4hi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_sub_pi32(__m64 __m1, __m64 __m2)
{
return (__m64)((__v2si)__m1 - (__v2si)__m2);
return (__m64)__builtin_ia32_psubd((__v2si)__m1, (__v2si)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
@ -222,7 +217,7 @@ _mm_mulhi_pi16(__m64 __m1, __m64 __m2)
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_mullo_pi16(__m64 __m1, __m64 __m2)
{
return (__m64)((__v4hi)__m1 * (__v4hi)__m2);
return (__m64)__builtin_ia32_pmullw((__v4hi)__m1, (__v4hi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
@ -252,13 +247,13 @@ _mm_slli_pi32(__m64 __m, int __count)
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_sll_si64(__m64 __m, __m64 __count)
{
return __builtin_ia32_psllq(__m, __count);
return (__m64)__builtin_ia32_psllq(__m, __count);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_slli_si64(__m64 __m, int __count)
{
return __builtin_ia32_psllqi(__m, __count);
return (__m64)__builtin_ia32_psllqi(__m, __count);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
@ -318,67 +313,67 @@ _mm_srl_si64(__m64 __m, __m64 __count)
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_srli_si64(__m64 __m, int __count)
{
return __builtin_ia32_psrlqi(__m, __count);
return (__m64)__builtin_ia32_psrlqi(__m, __count);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_and_si64(__m64 __m1, __m64 __m2)
{
return __m1 & __m2;
return __builtin_ia32_pand(__m1, __m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_andnot_si64(__m64 __m1, __m64 __m2)
{
return ~__m1 & __m2;
return __builtin_ia32_pandn(__m1, __m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_or_si64(__m64 __m1, __m64 __m2)
{
return __m1 | __m2;
return __builtin_ia32_por(__m1, __m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_xor_si64(__m64 __m1, __m64 __m2)
{
return __m1 ^ __m2;
return __builtin_ia32_pxor(__m1, __m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_cmpeq_pi8(__m64 __m1, __m64 __m2)
{
return (__m64)((__v8qi)__m1 == (__v8qi)__m2);
return (__m64)__builtin_ia32_pcmpeqb((__v8qi)__m1, (__v8qi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_cmpeq_pi16(__m64 __m1, __m64 __m2)
{
return (__m64)((__v4hi)__m1 == (__v4hi)__m2);
return (__m64)__builtin_ia32_pcmpeqw((__v4hi)__m1, (__v4hi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_cmpeq_pi32(__m64 __m1, __m64 __m2)
{
return (__m64)((__v2si)__m1 == (__v2si)__m2);
return (__m64)__builtin_ia32_pcmpeqd((__v2si)__m1, (__v2si)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_cmpgt_pi8(__m64 __m1, __m64 __m2)
{
return (__m64)((__v8qi)__m1 > (__v8qi)__m2);
return (__m64)__builtin_ia32_pcmpgtb((__v8qi)__m1, (__v8qi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_cmpgt_pi16(__m64 __m1, __m64 __m2)
{
return (__m64)((__v4hi)__m1 > (__v4hi)__m2);
return (__m64)__builtin_ia32_pcmpgtw((__v4hi)__m1, (__v4hi)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_cmpgt_pi32(__m64 __m1, __m64 __m2)
{
return (__m64)((__v2si)__m1 > (__v2si)__m2);
return (__m64)__builtin_ia32_pcmpgtd((__v2si)__m1, (__v2si)__m2);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
@ -390,57 +385,58 @@ _mm_setzero_si64(void)
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_set_pi32(int __i1, int __i0)
{
return (__m64)(__v2si){ __i0, __i1 };
return (__m64)__builtin_ia32_vec_init_v2si(__i0, __i1);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_set_pi16(short __s3, short __s2, short __s1, short __s0)
{
return (__m64)(__v4hi){ __s0, __s1, __s2, __s3 };
return (__m64)__builtin_ia32_vec_init_v4hi(__s0, __s1, __s2, __s3);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_set_pi8(char __b7, char __b6, char __b5, char __b4, char __b3, char __b2,
char __b1, char __b0)
{
return (__m64)(__v8qi){ __b0, __b1, __b2, __b3, __b4, __b5, __b6, __b7 };
return (__m64)__builtin_ia32_vec_init_v8qi(__b0, __b1, __b2, __b3,
__b4, __b5, __b6, __b7);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_set1_pi32(int __i)
{
return (__m64)(__v2si){ __i, __i };
return _mm_set_pi32(__i, __i);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_set1_pi16(short __s)
_mm_set1_pi16(short __w)
{
return (__m64)(__v4hi){ __s, __s, __s, __s };
return _mm_set_pi16(__w, __w, __w, __w);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_set1_pi8(char __b)
{
return (__m64)(__v8qi){ __b, __b, __b, __b, __b, __b, __b, __b };
return _mm_set_pi8(__b, __b, __b, __b, __b, __b, __b, __b);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_setr_pi32(int __i1, int __i0)
{
return (__m64)(__v2si){ __i1, __i0 };
return _mm_set_pi32(__i1, __i0);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_setr_pi16(short __s3, short __s2, short __s1, short __s0)
_mm_setr_pi16(short __w3, short __w2, short __w1, short __w0)
{
return (__m64)(__v4hi){ __s3, __s2, __s1, __s0 };
return _mm_set_pi16(__w3, __w2, __w1, __w0);
}
static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
_mm_setr_pi8(char __b7, char __b6, char __b5, char __b4, char __b3, char __b2,
char __b1, char __b0)
{
return (__m64)(__v8qi){ __b7, __b6, __b5, __b4, __b3, __b2, __b1, __b0 };
return _mm_set_pi8(__b7, __b6, __b5, __b4, __b3, __b2, __b1, __b0);
}

Просмотреть файл

@ -1958,8 +1958,11 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
TInfo,
/*BitWidth=*/0, /*Mutable=*/false);
Anon->setAccess(AS);
if (getLangOptions().CPlusPlus)
if (getLangOptions().CPlusPlus) {
FieldCollector->Add(cast<FieldDecl>(Anon));
if (!cast<CXXRecordDecl>(Record)->isEmpty())
cast<CXXRecordDecl>(OwningClass)->setEmpty(false);
}
} else {
DeclSpec::SCS SCSpec = DS.getStorageClassSpec();
assert(SCSpec != DeclSpec::SCS_typedef &&
@ -3425,7 +3428,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
<< FixItHint::CreateRemoval(D.getDeclSpec().getVirtualSpecLoc());
} else {
// Okay: Add virtual to the method.
NewFD->setVirtualAsWritten(true);
CXXRecordDecl *CurClass = cast<CXXRecordDecl>(DC);
CurClass->setMethodAsVirtual(NewFD);
}
}
@ -3926,6 +3930,15 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
return NewFD->setInvalidDecl();
}
}
// C++ [class]p4: A POD-struct is an aggregate class that has [...] no
// user-defined destructor.
Record->setPOD(false);
// C++ [class.dtor]p3: A destructor is trivial if it is an implicitly-
// declared destructor.
// FIXME: C++0x: don't do this for "= default" destructors
Record->setHasTrivialDestructor(false);
} else if (CXXConversionDecl *Conversion
= dyn_cast<CXXConversionDecl>(NewFD)) {
ActOnConversionDeclarator(Conversion);
@ -6179,9 +6192,27 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
}
if (!InvalidDecl && getLangOptions().CPlusPlus) {
CXXRecordDecl* CXXRecord = cast<CXXRecordDecl>(Record);
if (!T->isPODType())
CXXRecord->setPOD(false);
if (!ZeroWidth)
CXXRecord->setEmpty(false);
if (T->isReferenceType())
CXXRecord->setHasTrivialConstructor(false);
if (const RecordType *RT = EltTy->getAs<RecordType>()) {
CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
if (RDecl->getDefinition()) {
if (!RDecl->hasTrivialConstructor())
CXXRecord->setHasTrivialConstructor(false);
if (!RDecl->hasTrivialCopyConstructor())
CXXRecord->setHasTrivialCopyConstructor(false);
if (!RDecl->hasTrivialCopyAssignment())
CXXRecord->setHasTrivialCopyAssignment(false);
if (!RDecl->hasTrivialDestructor())
CXXRecord->setHasTrivialDestructor(false);
// C++ 9.5p1: An object of a class with a non-trivial
// constructor, a non-trivial copy constructor, a non-trivial
// destructor, or a non-trivial copy assignment operator
@ -6204,6 +6235,18 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
Diag(Loc, diag::warn_attribute_weak_on_field);
NewFD->setAccess(AS);
// C++ [dcl.init.aggr]p1:
// An aggregate is an array or a class (clause 9) with [...] no
// private or protected non-static data members (clause 11).
// A POD must be an aggregate.
if (getLangOptions().CPlusPlus &&
(AS == AS_private || AS == AS_protected)) {
CXXRecordDecl *CXXRecord = cast<CXXRecordDecl>(Record);
CXXRecord->setAggregate(false);
CXXRecord->setPOD(false);
}
return NewFD;
}

Просмотреть файл

@ -502,6 +502,8 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
return 0;
}
SetClassDeclAttributesFromBase(Class, CXXBaseDecl, Virtual);
if (BaseDecl->isInvalidDecl())
Class->setInvalidDecl();
@ -511,6 +513,73 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
Access, TInfo);
}
void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
const CXXRecordDecl *BaseClass,
bool BaseIsVirtual) {
// A class with a non-empty base class is not empty.
// FIXME: Standard ref?
if (!BaseClass->isEmpty())
Class->setEmpty(false);
// C++ [class.virtual]p1:
// A class that [...] inherits a virtual function is called a polymorphic
// class.
if (BaseClass->isPolymorphic())
Class->setPolymorphic(true);
// C++ [dcl.init.aggr]p1:
// An aggregate is [...] a class with [...] no base classes [...].
Class->setAggregate(false);
// C++ [class]p4:
// A POD-struct is an aggregate class...
Class->setPOD(false);
if (BaseIsVirtual) {
// C++ [class.ctor]p5:
// A constructor is trivial if its class has no virtual base classes.
Class->setHasTrivialConstructor(false);
// C++ [class.copy]p6:
// A copy constructor is trivial if its class has no virtual base classes.
Class->setHasTrivialCopyConstructor(false);
// C++ [class.copy]p11:
// A copy assignment operator is trivial if its class has no virtual
// base classes.
Class->setHasTrivialCopyAssignment(false);
// C++0x [meta.unary.prop] is_empty:
// T is a class type, but not a union type, with ... no virtual base
// classes
Class->setEmpty(false);
} else {
// C++ [class.ctor]p5:
// A constructor is trivial if all the direct base classes of its
// class have trivial constructors.
if (!BaseClass->hasTrivialConstructor())
Class->setHasTrivialConstructor(false);
// C++ [class.copy]p6:
// A copy constructor is trivial if all the direct base classes of its
// class have trivial copy constructors.
if (!BaseClass->hasTrivialCopyConstructor())
Class->setHasTrivialCopyConstructor(false);
// C++ [class.copy]p11:
// A copy assignment operator is trivial if all the direct base classes
// of its class have trivial copy assignment operators.
if (!BaseClass->hasTrivialCopyAssignment())
Class->setHasTrivialCopyAssignment(false);
}
// C++ [class.ctor]p3:
// A destructor is trivial if all the direct base classes of its class
// have trivial destructors.
if (!BaseClass->hasTrivialDestructor())
Class->setHasTrivialDestructor(false);
}
/// ActOnBaseSpecifier - Parsed a base specifier. A base specifier is
/// one entry in the base class list of a class specifier, for
/// example:

Просмотреть файл

@ -1091,6 +1091,13 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
Base = Pattern->bases_begin(), BaseEnd = Pattern->bases_end();
Base != BaseEnd; ++Base) {
if (!Base->getType()->isDependentType()) {
const CXXRecordDecl *BaseDecl =
cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
// Make sure to set the attributes from the base.
SetClassDeclAttributesFromBase(Instantiation, BaseDecl,
Base->isVirtual());
InstantiatedBases.push_back(new (Context) CXXBaseSpecifier(*Base));
continue;
}

Просмотреть файл

@ -1996,9 +1996,10 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
if (InitFunctionInstantiation(New, Tmpl))
return true;
CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
New->setAccess(Tmpl->getAccess());
if (Tmpl->isVirtualAsWritten())
New->setVirtualAsWritten(true);
Record->setMethodAsVirtual(New);
// FIXME: attributes
// FIXME: New needs a pointer to Tmpl