From: Nate Begeman Date: Tue, 25 Mar 2008 18:36:32 +0000 (+0000) Subject: Extend QualType::getAddressSpace to do the right thing for array types, and in X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8e7dafec4b70303dfaff95151cd06bfc5532720c;p=clang Extend QualType::getAddressSpace to do the right thing for array types, and in the future, RecordTypes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48784 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index e434ea2c0b..60cbfc83ad 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -1087,7 +1087,11 @@ public: // FIXME: This predicate is a helper to QualType/Type. It needs to // recursively check all fields for const-ness. If any field is declared // const, it needs to return false. - bool hasConstFields() const { return false; } + bool hasConstFields() const { return false; } + + // FIXME: RecordType needs to check when it is created that all fields are in + // the same address space, and return that. + unsigned getAddressSpace() const { return 0; } static bool classof(const Type *T); static bool classof(const RecordType *) { return true; } @@ -1114,6 +1118,10 @@ inline QualType QualType::getUnqualifiedType() const { /// getAddressSpace - Return the address space of this type. inline unsigned QualType::getAddressSpace() const { + if (const ArrayType *AT = dyn_cast(getCanonicalType())) + return AT->getBaseType().getAddressSpace(); + if (const RecordType *RT = dyn_cast(getCanonicalType())) + return RT->getAddressSpace(); if (const ASQualType *ASQT = dyn_cast(getCanonicalType())) return ASQT->getAddressSpace(); return 0; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 02b5f31c87..eea285cf41 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -808,14 +808,9 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { // This includes arrays of objects with address space qualifiers, but not // automatic variables that point to other address spaces. // ISO/IEC TR 18037 S5.1.2 - if (NewVD->hasLocalStorage()) { - QualType AutoTy = NewVD->getCanonicalType(); - if (const ArrayType *AT = AutoTy->getAsArrayType()) - AutoTy = AT->getElementType().getCanonicalType(); - if (AutoTy.getAddressSpace() != 0) { - Diag(D.getIdentifierLoc(), diag::err_as_qualified_auto_decl); - InvalidDecl = true; - } + if (NewVD->hasLocalStorage() && (NewVD->getType().getAddressSpace() != 0)) { + Diag(D.getIdentifierLoc(), diag::err_as_qualified_auto_decl); + InvalidDecl = true; } // Merge the decl with the existing one if appropriate. If the decl is // in an outer scope, it isn't the same thing. diff --git a/test/Sema/address_spaces.c b/test/Sema/address_spaces.c index 002ba13088..eda7b8a106 100644 --- a/test/Sema/address_spaces.c +++ b/test/Sema/address_spaces.c @@ -12,7 +12,8 @@ void foo(_AS3 float *a) { int *_AS1 _AS2 *Z; // expected-error {{multiple address spaces specified for type}} _AS1 int local; // expected-error {{automatic variable qualified with an address space}} - _AS1 int array[50]; // expected-error {{automatic variable qualified with an address space}} + _AS1 int array[5]; // expected-error {{automatic variable qualified with an address space}} + _AS1 int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}} *a = 5.0f; }