forked from OSchip/llvm-project
Add a big test case for I-C-Es in C++, and a fix to make it work. The fix might not be the right way to do it.
llvm-svn: 72490
This commit is contained in:
parent
eed3d4c73e
commit
a81b0b7ef5
|
@ -48,7 +48,10 @@ class ASTRecordLayout {
|
|||
}
|
||||
|
||||
/// Finalize record layout. Adjust record size based on the alignment.
|
||||
void FinalizeLayout() {
|
||||
void FinalizeLayout(bool ForceNonEmpty = false) {
|
||||
// In C++, records cannot be of size 0.
|
||||
if (ForceNonEmpty && Size == 0)
|
||||
Size = 8;
|
||||
// Finally, round the size of the record up to the alignment of the
|
||||
// record itself.
|
||||
Size = (Size + (Alignment-1)) & ~(Alignment-1);
|
||||
|
|
|
@ -360,6 +360,7 @@ ASTContext::getTypeInfo(const Type *T) {
|
|||
case BuiltinType::NullPtr:
|
||||
Width = Target.getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t)
|
||||
Align = Target.getPointerAlign(0); // == sizeof(void*)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Type::FixedWidthInt:
|
||||
|
@ -768,7 +769,7 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
|
|||
|
||||
// Finally, round the size of the total struct up to the alignment of the
|
||||
// struct itself.
|
||||
NewEntry->FinalizeLayout();
|
||||
NewEntry->FinalizeLayout(getLangOptions().CPlusPlus);
|
||||
return *NewEntry;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify -std=c++98 %s
|
||||
|
||||
// C++ [expr.const]p1:
|
||||
// In several places, C++ requires expressions that evaluate to an integral
|
||||
// or enumeration constant: as array bounds, as case expressions, as
|
||||
// bit-field lengths, as enumerator initializers, as static member
|
||||
// initializers, and as integral or enumeration non-type template arguments.
|
||||
// An integral constant-expression can involve only literals, enumerators,
|
||||
// const variables or static data members of integral or enumeration types
|
||||
// initialized with constant expressions, and sizeof expressions. Floating
|
||||
// literals can appear only if they are cast to integral or enumeration types.
|
||||
|
||||
enum Enum { eval = 1 };
|
||||
const int cval = 2;
|
||||
const Enum ceval = eval;
|
||||
struct Struct {
|
||||
static const int sval = 3;
|
||||
static const Enum seval = eval;
|
||||
};
|
||||
|
||||
template <int itval, Enum etval> struct C {
|
||||
enum E {
|
||||
v1 = 1,
|
||||
v2 = eval,
|
||||
v3 = cval,
|
||||
v4 = ceval,
|
||||
v5 = Struct::sval,
|
||||
v6 = Struct::seval,
|
||||
v7 = itval,
|
||||
v8 = etval,
|
||||
v9 = (int)1.5,
|
||||
v10 = sizeof(Struct),
|
||||
v11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
|
||||
};
|
||||
unsigned
|
||||
b1 : 1,
|
||||
b2 : eval,
|
||||
b3 : cval,
|
||||
b4 : ceval,
|
||||
b5 : Struct::sval,
|
||||
b6 : Struct::seval,
|
||||
b7 : itval,
|
||||
b8 : etval,
|
||||
b9 : (int)1.5,
|
||||
b10 : sizeof(Struct),
|
||||
b11 : true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
|
||||
;
|
||||
static const int
|
||||
i1 = 1,
|
||||
i2 = eval,
|
||||
i3 = cval,
|
||||
i4 = ceval,
|
||||
i5 = Struct::sval,
|
||||
i6 = Struct::seval,
|
||||
i7 = itval,
|
||||
i8 = etval,
|
||||
i9 = (int)1.5,
|
||||
i10 = sizeof(Struct),
|
||||
i11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
|
||||
;
|
||||
void f() {
|
||||
switch(0) {
|
||||
case 0 + 1:
|
||||
case 100 + eval:
|
||||
case 200 + cval:
|
||||
case 300 + ceval:
|
||||
case 400 + Struct::sval:
|
||||
case 500 + Struct::seval:
|
||||
case 600 + itval:
|
||||
case 700 + etval:
|
||||
case 800 + (int)1.5:
|
||||
case 900 + sizeof(Struct):
|
||||
case 1000 + (true? 1 + cval * Struct::sval ^
|
||||
itval / (int)1.5 - sizeof(Struct) : 0):
|
||||
;
|
||||
}
|
||||
}
|
||||
typedef C<itval, etval> T0;
|
||||
};
|
||||
|
||||
template struct C<1, eval>;
|
||||
//template struct C<cval, ceval>;
|
||||
//template struct C<Struct::sval, Struct::seval>;
|
Loading…
Reference in New Issue