summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-04-30 17:32:17 +0000
committerDouglas Gregor <dgregor@apple.com>2009-04-30 17:32:17 +0000
commitef462e6bb0651f2a8b8df29134e43a59476522f8 (patch)
tree1cd7003e0fb5935341bb80e6b826861848764e02 /clang/lib/AST/ASTContext.cpp
parentf45e07d7663d4663472ff1ab64b41008ea10dbcd (diff)
downloadbcm5719-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.cpp50
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);
OpenPOWER on IntegriCloud