diff options
| author | Douglas Gregor <dgregor@apple.com> | 2009-04-30 17:32:17 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2009-04-30 17:32:17 +0000 |
| commit | ef462e6bb0651f2a8b8df29134e43a59476522f8 (patch) | |
| tree | 1cd7003e0fb5935341bb80e6b826861848764e02 /clang/lib/AST/ASTContext.cpp | |
| parent | f45e07d7663d4663472ff1ab64b41008ea10dbcd (diff) | |
| download | bcm5719-llvm-ef462e6bb0651f2a8b8df29134e43a59476522f8.tar.gz bcm5719-llvm-ef462e6bb0651f2a8b8df29134e43a59476522f8.zip | |
Properly compute the alignment of typedefs that make use of the
"aligned" attribute. Previously, we were skipping over these
attributes when we jumped directly to the canonical type. Now,
ASTContext::getTypeInfo walks through typedefs and other
"non-canonical" types manually, looking for "aligned" attributes on
typedefs.
As part of this change, I moved the GNU-specific logic (such as
determining the alignment of void or of a function pointer) out of the
expression evaluator and into ASTContext::getTypeInfo.
llvm-svn: 70497
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 5f97df904cc..b88149ad41e 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -334,24 +334,30 @@ unsigned ASTContext::getDeclAlignInBytes(const Decl *D) { /// does not work on incomplete types. std::pair<uint64_t, unsigned> ASTContext::getTypeInfo(const Type *T) { - T = getCanonicalType(T); uint64_t Width=0; unsigned Align=8; switch (T->getTypeClass()) { #define TYPE(Class, Base) #define ABSTRACT_TYPE(Class, Base) -#define NON_CANONICAL_TYPE(Class, Base) case Type::Class: +#define NON_CANONICAL_TYPE(Class, Base) #define DEPENDENT_TYPE(Class, Base) case Type::Class: #include "clang/AST/TypeNodes.def" - assert(false && "Should not see non-canonical or dependent types"); + assert(false && "Should not see dependent types"); break; case Type::FunctionNoProto: case Type::FunctionProto: + // GCC extension: alignof(function) = 32 bits + Width = 0; + Align = 32; + break; + case Type::IncompleteArray: - assert(0 && "Incomplete types have no size!"); case Type::VariableArray: - assert(0 && "VLAs not implemented yet!"); + Width = 0; + Align = getTypeAlign(cast<ArrayType>(T)->getElementType()); + break; + case Type::ConstantArray: { const ConstantArrayType *CAT = cast<ConstantArrayType>(T); @@ -377,7 +383,11 @@ ASTContext::getTypeInfo(const Type *T) { switch (cast<BuiltinType>(T)->getKind()) { default: assert(0 && "Unknown builtin type!"); case BuiltinType::Void: - assert(0 && "Incomplete types have no size!"); + // GCC extension: alignof(void) = 8 bits. + Width = 0; + Align = 8; + break; + case BuiltinType::Bool: Width = Target.getBoolWidth(); Align = Target.getBoolAlign(); @@ -517,10 +527,34 @@ ASTContext::getTypeInfo(const Type *T) { break; } - case Type::TemplateSpecialization: - assert(false && "Dependent types have no size"); + case Type::Typedef: { + const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl(); + if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) { + Align = Aligned->getAlignment(); + Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr()); + } else + return getTypeInfo(Typedef->getUnderlyingType().getTypePtr()); break; } + + case Type::TypeOfExpr: + return getTypeInfo(cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType() + .getTypePtr()); + + case Type::TypeOf: + return getTypeInfo(cast<TypeOfType>(T)->getUnderlyingType().getTypePtr()); + + case Type::QualifiedName: + return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr()); + + case Type::TemplateSpecialization: + assert(getCanonicalType(T) != T && + "Cannot request the size of a dependent type"); + // FIXME: this is likely to be wrong once we support template + // aliases, since a template alias could refer to a typedef that + // has an __aligned__ attribute on it. + return getTypeInfo(getCanonicalType(T)); + } assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2"); return std::make_pair(Width, Align); |

