bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID) { // OpenCL 1.1 6.8g: "The extern, static, auto and register storage-class // specifiers are not supported." // It seems sensible to prohibit private_extern too // The cl_clang_storage_class_specifiers extension enables support for // these storage-class specifiers. if (S.getLangOptions().OpenCL && !S.getOpenCLOptions().cl_clang_storage_class_specifiers) { switch (SC) { case SCS_extern: case SCS_private_extern: case SCS_auto: case SCS_register: case SCS_static: DiagID = diag::err_not_opencl_storage_class_specifier; PrevSpec = getSpecifierName(SC); return true; default: break; } } if (StorageClassSpec != SCS_unspecified) { // Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode. bool isInvalid = true; if (TypeSpecType == TST_unspecified && S.getLangOptions().CPlusPlus) { if (SC == SCS_auto) return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID); if (StorageClassSpec == SCS_auto) { isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc, PrevSpec, DiagID); assert(!isInvalid && "auto SCS -> TST recovery failed"); } } // Changing storage class is allowed only if the previous one // was the 'extern' that is part of a linkage specification and // the new storage class is 'typedef'. if (isInvalid && !(SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern && SC == SCS_typedef)) return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID); } StorageClassSpec = SC; StorageClassSpecLoc = Loc; assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield"); return false; }