Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h (revision 54765) +++ include/clang/AST/Type.h (working copy) @@ -130,6 +130,8 @@ bool isRestrictQualified() const { return (ThePtr & Restrict) ? true : false; } + + bool isConstant() const; /// addConst/addVolatile/addRestrict - add the specified type qual to this /// QualType. @@ -347,7 +349,10 @@ const ReferenceType *getAsReferenceType() const; const RecordType *getAsRecordType() const; const RecordType *getAsStructureType() const; - /// NOTE: getAsArrayType* are methods on ASTContext. + const ArrayType *getAsArrayType() const; + const ConstantArrayType *getAsConstantArrayType() const; + const IncompleteArrayType *getAsIncompleteArrayType() const; + const VariableArrayType *getAsVariableArrayType() const; const TypedefType *getAsTypedefType() const; const RecordType *getAsUnionType() const; const EnumType *getAsEnumType() const; Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp (revision 54765) +++ lib/CodeGen/CodeGenModule.cpp (working copy) @@ -585,6 +585,7 @@ } GV->setInitializer(Init); + GV->setConstant(D->getType().isConstant()); // FIXME: This is silly; getTypeAlign should just work for incomplete arrays unsigned Align; Index: lib/AST/Type.cpp =================================================================== --- lib/AST/Type.cpp (revision 54765) +++ lib/AST/Type.cpp (working copy) @@ -19,6 +19,16 @@ #include using namespace clang; +bool QualType::isConstant() const { + if (isConstQualified()) + return true; + + if (getTypePtr()->isArrayType()) + return getTypePtr()->getAsArrayType()->getElementType().isConstant(); + + return false; +} + void Type::Destroy(ASTContext& C) { delete this; } void FunctionTypeProto::Destroy(ASTContext& C) { @@ -249,6 +259,36 @@ return getDesugaredType()->getAsReferenceType(); } +const ArrayType *Type::getAsArrayType() const { + // If this is directly an array type, return it. + if (const ArrayType *ATy = dyn_cast(this)) + return ATy; + + // If the canonical form of this type isn't the right kind, reject it. + if (!isa(CanonicalType)) { + // Look through type qualifiers + if (isa(CanonicalType.getUnqualifiedType())) + return CanonicalType.getUnqualifiedType()->getAsArrayType(); + return 0; + } + + // If this is a typedef for an array type, strip the typedef off without + // losing all typedef information. + return getDesugaredType()->getAsArrayType(); +} + +const ConstantArrayType *Type::getAsConstantArrayType() const { + return dyn_cast_or_null(getAsArrayType()); +} + +const IncompleteArrayType *Type::getAsIncompleteArrayType() const { + return dyn_cast_or_null(getAsArrayType()); +} + +const VariableArrayType *Type::getAsVariableArrayType() const { + return dyn_cast_or_null(getAsArrayType()); +} + /// isVariablyModifiedType (C99 6.7.5p3) - Return true for variable length /// array types and types that contain variable array types in their /// declarator