Index: cfe/trunk/include/clang/AST/ASTContext.h =================================================================== --- cfe/trunk/include/clang/AST/ASTContext.h +++ cfe/trunk/include/clang/AST/ASTContext.h @@ -496,7 +496,7 @@ CXXABI *createCXXABI(const TargetInfo &T); /// \brief The logical -> physical address space map. - const LangAS::Map *AddrSpaceMap; + const LangASMap *AddrSpaceMap; /// \brief Address space map mangling must be used with language specific /// address spaces (e.g. OpenCL/CUDA) @@ -1070,7 +1070,7 @@ /// The resulting type has a union of the qualifiers from T and the address /// space. If T already has an address space specifier, it is silently /// replaced. - QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const; + QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const; /// \brief Remove any existing address space on the type and returns the type /// with qualifiers intact (or that's the idea anyway) @@ -2363,14 +2363,14 @@ return getTargetAddressSpace(Q.getAddressSpace()); } - unsigned getTargetAddressSpace(unsigned AS) const; + unsigned getTargetAddressSpace(LangAS AS) const; /// Get target-dependent integer value for null pointer which is used for /// constant folding. uint64_t getTargetNullPointerValue(QualType QT) const; - bool addressSpaceMapManglingFor(unsigned AS) const { - return AddrSpaceMapMangling || AS >= LangAS::FirstTargetAddressSpace; + bool addressSpaceMapManglingFor(LangAS AS) const { + return AddrSpaceMapMangling || isTargetAddressSpace(AS); } private: Index: cfe/trunk/include/clang/AST/Type.h =================================================================== --- cfe/trunk/include/clang/AST/Type.h +++ cfe/trunk/include/clang/AST/Type.h @@ -328,9 +328,11 @@ } bool hasAddressSpace() const { return Mask & AddressSpaceMask; } - unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; } + LangAS getAddressSpace() const { + return static_cast(Mask >> AddressSpaceShift); + } bool hasTargetSpecificAddressSpace() const { - return getAddressSpace() >= LangAS::FirstTargetAddressSpace; + return isTargetAddressSpace(getAddressSpace()); } /// Get the address space attribute value to be printed by diagnostics. unsigned getAddressSpaceAttributePrintValue() const { @@ -338,22 +340,22 @@ // This function is not supposed to be used with language specific // address spaces. If that happens, the diagnostic message should consider // printing the QualType instead of the address space value. - assert(Addr == 0 || hasTargetSpecificAddressSpace()); - if (Addr) - return Addr - LangAS::FirstTargetAddressSpace; + assert(Addr == LangAS::Default || hasTargetSpecificAddressSpace()); + if (Addr != LangAS::Default) + return toTargetAddressSpace(Addr); // TODO: The diagnostic messages where Addr may be 0 should be fixed // since it cannot differentiate the situation where 0 denotes the default // address space or user specified __attribute__((address_space(0))). return 0; } - void setAddressSpace(unsigned space) { - assert(space <= MaxAddressSpace); + void setAddressSpace(LangAS space) { + assert((unsigned)space <= MaxAddressSpace); Mask = (Mask & ~AddressSpaceMask) | (((uint32_t) space) << AddressSpaceShift); } - void removeAddressSpace() { setAddressSpace(0); } - void addAddressSpace(unsigned space) { - assert(space); + void removeAddressSpace() { setAddressSpace(LangAS::Default); } + void addAddressSpace(LangAS space) { + assert(space != LangAS::Default); setAddressSpace(space); } @@ -1005,7 +1007,7 @@ } /// Return the address space of this type. - inline unsigned getAddressSpace() const; + inline LangAS getAddressSpace() const; /// Returns gc attribute of this type. inline Qualifiers::GC getObjCGCAttr() const; @@ -1230,7 +1232,7 @@ } bool hasAddressSpace() const { return Quals.hasAddressSpace(); } - unsigned getAddressSpace() const { return Quals.getAddressSpace(); } + LangAS getAddressSpace() const { return Quals.getAddressSpace(); } const Type *getBaseType() const { return BaseType; } @@ -5654,7 +5656,7 @@ } /// Return the address space of this type. -inline unsigned QualType::getAddressSpace() const { +inline LangAS QualType::getAddressSpace() const { return getQualifiers().getAddressSpace(); } Index: cfe/trunk/include/clang/Basic/AddressSpaces.h =================================================================== --- cfe/trunk/include/clang/Basic/AddressSpaces.h +++ cfe/trunk/include/clang/Basic/AddressSpaces.h @@ -16,14 +16,14 @@ #ifndef LLVM_CLANG_BASIC_ADDRESSSPACES_H #define LLVM_CLANG_BASIC_ADDRESSSPACES_H -namespace clang { +#include -namespace LangAS { +namespace clang { /// \brief Defines the address space values used by the address space qualifier /// of QualType. /// -enum ID { +enum class LangAS : unsigned { // The default value 0 is the value used in QualType for the the situation // where there is no address space qualifier. Default = 0, @@ -51,9 +51,24 @@ /// The type of a lookup table which maps from language-specific address spaces /// to target-specific ones. -typedef unsigned Map[FirstTargetAddressSpace]; +typedef unsigned LangASMap[(unsigned)LangAS::FirstTargetAddressSpace]; + +/// \return whether \p AS is a target-specific address space rather than a +/// clang AST address space +inline bool isTargetAddressSpace(LangAS AS) { + return (unsigned)AS >= (unsigned)LangAS::FirstTargetAddressSpace; } +inline unsigned toTargetAddressSpace(LangAS AS) { + assert(isTargetAddressSpace(AS)); + return (unsigned)AS - (unsigned)LangAS::FirstTargetAddressSpace; } +inline LangAS getLangASFromTargetAS(unsigned TargetAS) { + return static_cast((TargetAS) + + (unsigned)LangAS::FirstTargetAddressSpace); +} + +} // namespace clang + #endif Index: cfe/trunk/include/clang/Basic/TargetInfo.h =================================================================== --- cfe/trunk/include/clang/Basic/TargetInfo.h +++ cfe/trunk/include/clang/Basic/TargetInfo.h @@ -86,7 +86,7 @@ *LongDoubleFormat, *Float128Format; unsigned char RegParmMax, SSERegParmMax; TargetCXXABI TheCXXABI; - const LangAS::Map *AddrSpaceMap; + const LangASMap *AddrSpaceMap; mutable StringRef PlatformName; mutable VersionTuple PlatformMinVersion; @@ -322,9 +322,7 @@ /// \brief Get integer value for null pointer. /// \param AddrSpace address space of pointee in source language. - virtual uint64_t getNullPointerValue(unsigned AddrSpace) const { - return 0; - } + virtual uint64_t getNullPointerValue(LangAS AddrSpace) const { return 0; } /// \brief Return the size of '_Bool' and C++ 'bool' for this target, in bits. unsigned getBoolWidth() const { return BoolWidth; } @@ -971,15 +969,13 @@ return nullptr; } - const LangAS::Map &getAddressSpaceMap() const { - return *AddrSpaceMap; - } + const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; } /// \brief Return an AST address space which can be used opportunistically /// for constant global memory. It must be possible to convert pointers into /// this address space to LangAS::Default. If no such address space exists, /// this may return None, and such optimizations will be disabled. - virtual llvm::Optional getConstantAddressSpace() const { + virtual llvm::Optional getConstantAddressSpace() const { return LangAS::Default; } @@ -1058,7 +1054,7 @@ } /// \brief Get address space for OpenCL type. - virtual LangAS::ID getOpenCLTypeAddrSpace(const Type *T) const; + virtual LangAS getOpenCLTypeAddrSpace(const Type *T) const; /// \returns Target specific vtbl ptr address space. virtual unsigned getVtblPtrAddressSpace() const { Index: cfe/trunk/lib/AST/ASTContext.cpp =================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp +++ cfe/trunk/lib/AST/ASTContext.cpp @@ -697,8 +697,8 @@ llvm_unreachable("Invalid CXXABI type!"); } -static const LangAS::Map *getAddressSpaceMap(const TargetInfo &T, - const LangOptions &LOpts) { +static const LangASMap *getAddressSpaceMap(const TargetInfo &T, + const LangOptions &LOpts) { if (LOpts.FakeAddressSpaceMap) { // The fake address space map must have a distinct entry for each // language-specific address space. @@ -2283,8 +2283,8 @@ return QualType(eq, fastQuals); } -QualType -ASTContext::getAddrSpaceQualType(QualType T, unsigned AddressSpace) const { +QualType ASTContext::getAddrSpaceQualType(QualType T, + LangAS AddressSpace) const { QualType CanT = getCanonicalType(T); if (CanT.getAddressSpace() == AddressSpace) return T; @@ -8870,8 +8870,8 @@ char *End; unsigned AddrSpace = strtoul(Str, &End, 10); if (End != Str && AddrSpace != 0) { - Type = Context.getAddrSpaceQualType( - Type, AddrSpace + LangAS::FirstTargetAddressSpace); + Type = Context.getAddrSpaceQualType(Type, + getLangASFromTargetAS(AddrSpace)); Str = End; } if (c == '*') @@ -9694,20 +9694,20 @@ } uint64_t ASTContext::getTargetNullPointerValue(QualType QT) const { - unsigned AS; + LangAS AS; if (QT->getUnqualifiedDesugaredType()->isNullPtrType()) - AS = 0; + AS = LangAS::Default; else AS = QT->getPointeeType().getAddressSpace(); return getTargetInfo().getNullPointerValue(AS); } -unsigned ASTContext::getTargetAddressSpace(unsigned AS) const { - if (AS >= LangAS::FirstTargetAddressSpace) - return AS - LangAS::FirstTargetAddressSpace; +unsigned ASTContext::getTargetAddressSpace(LangAS AS) const { + if (isTargetAddressSpace(AS)) + return toTargetAddressSpace(AS); else - return (*AddrSpaceMap)[AS]; + return (*AddrSpaceMap)[(unsigned)AS]; } // Explicitly instantiate this in case a Redeclarable is used from a TU that Index: cfe/trunk/lib/AST/ItaniumMangle.cpp =================================================================== --- cfe/trunk/lib/AST/ItaniumMangle.cpp +++ cfe/trunk/lib/AST/ItaniumMangle.cpp @@ -2222,7 +2222,7 @@ // ::= U SmallString<64> ASString; - unsigned AS = Quals.getAddressSpace(); + LangAS AS = Quals.getAddressSpace(); if (Context.getASTContext().addressSpaceMapManglingFor(AS)) { // ::= "AS" Index: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp =================================================================== --- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp +++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp @@ -1731,7 +1731,7 @@ const ArrayType* ATy = Context.getAsArrayType(D->getType()); FieldAlign = Context.getTypeAlignInChars(ATy->getElementType()); } else if (const ReferenceType *RT = D->getType()->getAs()) { - unsigned AS = RT->getPointeeType().getAddressSpace(); + unsigned AS = Context.getTargetAddressSpace(RT->getPointeeType()); FieldSize = Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(AS)); FieldAlign = Index: cfe/trunk/lib/AST/TypePrinter.cpp =================================================================== --- cfe/trunk/lib/AST/TypePrinter.cpp +++ cfe/trunk/lib/AST/TypePrinter.cpp @@ -1320,7 +1320,9 @@ default: llvm_unreachable("This attribute should have been handled already"); case AttributedType::attr_address_space: OS << "address_space("; - OS << T->getEquivalentType().getAddressSpace(); + // FIXME: printing the raw LangAS value is wrong. This should probably + // use the same code as Qualifiers::print() + OS << (unsigned)T->getEquivalentType().getAddressSpace(); OS << ')'; break; @@ -1645,7 +1647,7 @@ if (getCVRQualifiers()) return false; - if (getAddressSpace()) + if (getAddressSpace() != LangAS::Default) return false; if (getObjCGCAttr()) @@ -1676,7 +1678,8 @@ OS << "__unaligned"; addSpace = true; } - if (unsigned addrspace = getAddressSpace()) { + LangAS addrspace = getAddressSpace(); + if (addrspace != LangAS::Default) { if (addrspace != LangAS::opencl_private) { if (addSpace) OS << ' '; @@ -1704,9 +1707,8 @@ OS << "__shared"; break; default: - assert(addrspace >= LangAS::FirstTargetAddressSpace); OS << "__attribute__((address_space("; - OS << addrspace - LangAS::FirstTargetAddressSpace; + OS << toTargetAddressSpace(addrspace); OS << ")))"; } } Index: cfe/trunk/lib/Basic/TargetInfo.cpp =================================================================== --- cfe/trunk/lib/Basic/TargetInfo.cpp +++ cfe/trunk/lib/Basic/TargetInfo.cpp @@ -23,7 +23,7 @@ #include using namespace clang; -static const LangAS::Map DefaultAddrSpaceMap = { 0 }; +static const LangASMap DefaultAddrSpaceMap = {0}; // TargetInfo Constructor. TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { @@ -356,7 +356,7 @@ return true; } -LangAS::ID TargetInfo::getOpenCLTypeAddrSpace(const Type *T) const { +LangAS TargetInfo::getOpenCLTypeAddrSpace(const Type *T) const { auto BT = dyn_cast(T); if (!BT) { Index: cfe/trunk/lib/Basic/Targets/AMDGPU.h =================================================================== --- cfe/trunk/lib/Basic/Targets/AMDGPU.h +++ cfe/trunk/lib/Basic/Targets/AMDGPU.h @@ -258,7 +258,7 @@ } } - LangAS::ID getOpenCLTypeAddrSpace(const Type *T) const override { + LangAS getOpenCLTypeAddrSpace(const Type *T) const override { auto BT = dyn_cast(T); if (!BT) @@ -279,8 +279,8 @@ } } - llvm::Optional getConstantAddressSpace() const override { - return LangAS::FirstTargetAddressSpace + AS.Constant; + llvm::Optional getConstantAddressSpace() const override { + return getLangASFromTargetAS(AS.Constant); } /// \returns Target specific vtbl ptr address space. @@ -318,7 +318,7 @@ // In amdgcn target the null pointer in global, constant, and generic // address space has value 0 but in private and local address space has // value ~0. - uint64_t getNullPointerValue(unsigned AS) const override { + uint64_t getNullPointerValue(LangAS AS) const override { return AS == LangAS::opencl_local ? ~0 : 0; } }; Index: cfe/trunk/lib/Basic/Targets/AMDGPU.cpp =================================================================== --- cfe/trunk/lib/Basic/Targets/AMDGPU.cpp +++ cfe/trunk/lib/Basic/Targets/AMDGPU.cpp @@ -42,7 +42,7 @@ "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5"; -static const LangAS::Map AMDGPUPrivIsZeroDefIsGenMap = { +static const LangASMap AMDGPUPrivIsZeroDefIsGenMap = { 4, // Default 1, // opencl_global 3, // opencl_local @@ -54,7 +54,7 @@ 3 // cuda_shared }; -static const LangAS::Map AMDGPUGenIsZeroDefIsGenMap = { +static const LangASMap AMDGPUGenIsZeroDefIsGenMap = { 0, // Default 1, // opencl_global 3, // opencl_local @@ -66,7 +66,7 @@ 3 // cuda_shared }; -static const LangAS::Map AMDGPUPrivIsZeroDefIsPrivMap = { +static const LangASMap AMDGPUPrivIsZeroDefIsPrivMap = { 0, // Default 1, // opencl_global 3, // opencl_local @@ -78,7 +78,7 @@ 3 // cuda_shared }; -static const LangAS::Map AMDGPUGenIsZeroDefIsPrivMap = { +static const LangASMap AMDGPUGenIsZeroDefIsPrivMap = { 5, // Default 1, // opencl_global 3, // opencl_local Index: cfe/trunk/lib/CodeGen/CGBlocks.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGBlocks.cpp +++ cfe/trunk/lib/CodeGen/CGBlocks.cpp @@ -309,10 +309,12 @@ if (CGM.getLangOpts().OpenCL) { // The header is basically 'struct { int; int; generic void *; // custom_fields; }'. Assert that struct is packed. - auto GenPtrAlign = CharUnits::fromQuantity( - CGM.getTarget().getPointerAlign(LangAS::opencl_generic) / 8); - auto GenPtrSize = CharUnits::fromQuantity( - CGM.getTarget().getPointerWidth(LangAS::opencl_generic) / 8); + auto GenericAS = + CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic); + auto GenPtrAlign = + CharUnits::fromQuantity(CGM.getTarget().getPointerAlign(GenericAS) / 8); + auto GenPtrSize = + CharUnits::fromQuantity(CGM.getTarget().getPointerWidth(GenericAS) / 8); assert(CGM.getIntSize() <= GenPtrSize); assert(CGM.getIntAlign() <= GenPtrAlign); assert((2 * CGM.getIntSize()).isMultipleOf(GenPtrAlign)); @@ -775,9 +777,11 @@ bool IsOpenCL = CGM.getContext().getLangOpts().OpenCL; auto GenVoidPtrTy = IsOpenCL ? CGM.getOpenCLRuntime().getGenericVoidPointerType() : VoidPtrTy; - unsigned GenVoidPtrAddr = IsOpenCL ? LangAS::opencl_generic : LangAS::Default; + LangAS GenVoidPtrAddr = IsOpenCL ? LangAS::opencl_generic : LangAS::Default; auto GenVoidPtrSize = CharUnits::fromQuantity( - CGM.getTarget().getPointerWidth(GenVoidPtrAddr) / 8); + CGM.getTarget().getPointerWidth( + CGM.getContext().getTargetAddressSpace(GenVoidPtrAddr)) / + 8); // Using the computed layout, generate the actual block function. bool isLambdaConv = blockInfo.getBlockDecl()->isConversionFromLambda(); auto *InvokeFn = CodeGenFunction(CGM, true).GenerateBlockFunction( Index: cfe/trunk/lib/CodeGen/CGDecl.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGDecl.cpp +++ cfe/trunk/lib/CodeGen/CGDecl.cpp @@ -222,7 +222,7 @@ Name = getStaticDeclName(*this, D); llvm::Type *LTy = getTypes().ConvertTypeForMem(Ty); - unsigned AS = GetGlobalVarAddressSpace(&D); + LangAS AS = GetGlobalVarAddressSpace(&D); unsigned TargetAS = getContext().getTargetAddressSpace(AS); // Local address space cannot have an initializer. @@ -252,7 +252,7 @@ } // Make sure the result is of the correct type. - unsigned ExpectedAS = Ty.getAddressSpace(); + LangAS ExpectedAS = Ty.getAddressSpace(); llvm::Constant *Addr = GV; if (AS != ExpectedAS) { Addr = getTargetCodeGenInfo().performAddrSpaceCast( Index: cfe/trunk/lib/CodeGen/CGExprConstant.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp @@ -612,7 +612,7 @@ CGM.getAddrOfConstantCompoundLiteralIfEmitted(E)) return ConstantAddress(Addr, Align); - unsigned addressSpace = E->getType().getAddressSpace(); + LangAS addressSpace = E->getType().getAddressSpace(); ConstantEmitter emitter(CGM, CGF); llvm::Constant *C = emitter.tryEmitForInitializer(E->getInitializer(), @@ -725,8 +725,8 @@ case CK_AddressSpaceConversion: { auto C = Emitter.tryEmitPrivate(subExpr, subExpr->getType()); if (!C) return nullptr; - unsigned destAS = E->getType()->getPointeeType().getAddressSpace(); - unsigned srcAS = subExpr->getType()->getPointeeType().getAddressSpace(); + LangAS destAS = E->getType()->getPointeeType().getAddressSpace(); + LangAS srcAS = subExpr->getType()->getPointeeType().getAddressSpace(); llvm::Type *destTy = ConvertType(E->getType()); return CGM.getTargetCodeGenInfo().performAddrSpaceCast(CGM, C, srcAS, destAS, destTy); @@ -1184,14 +1184,14 @@ } llvm::Constant *ConstantEmitter::tryEmitForInitializer(const Expr *E, - unsigned destAddrSpace, + LangAS destAddrSpace, QualType destType) { initializeNonAbstract(destAddrSpace); return markIfFailed(tryEmitPrivateForMemory(E, destType)); } llvm::Constant *ConstantEmitter::emitForInitializer(const APValue &value, - unsigned destAddrSpace, + LangAS destAddrSpace, QualType destType) { initializeNonAbstract(destAddrSpace); auto C = tryEmitPrivateForMemory(value, destType); Index: cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -2253,7 +2253,7 @@ ArgType = CGM.getContext().getPointerType(PointeeTy); QC.addRestrict(); enum { NVPTX_local_addr = 5 }; - QC.addAddressSpace(NVPTX_local_addr); + QC.addAddressSpace(getLangASFromTargetAS(NVPTX_local_addr)); ArgType = QC.apply(CGM.getContext(), ArgType); return ImplicitParamDecl::Create( CGM.getContext(), /*DC=*/nullptr, NativeParam->getLocation(), @@ -2273,7 +2273,7 @@ const Type *NonQualTy = QC.strip(NativeParamType); QualType NativePointeeTy = cast(NonQualTy)->getPointeeType(); unsigned NativePointeeAddrSpace = - NativePointeeTy.getQualifiers().getAddressSpace(); + CGF.getContext().getTargetAddressSpace(NativePointeeTy); QualType TargetTy = TargetParam->getType(); llvm::Value *TargetAddr = CGF.EmitLoadOfScalar( LocalAddr, /*Volatile=*/false, TargetTy, SourceLocation()); Index: cfe/trunk/lib/CodeGen/CGValue.h =================================================================== --- cfe/trunk/lib/CodeGen/CGValue.h +++ cfe/trunk/lib/CodeGen/CGValue.h @@ -314,7 +314,7 @@ const Qualifiers &getQuals() const { return Quals; } Qualifiers &getQuals() { return Quals; } - unsigned getAddressSpace() const { return Quals.getAddressSpace(); } + LangAS getAddressSpace() const { return Quals.getAddressSpace(); } CharUnits getAlignment() const { return CharUnits::fromQuantity(Alignment); } void setAlignment(CharUnits A) { Alignment = A.getQuantity(); } Index: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp @@ -525,8 +525,8 @@ // for example in clGetKernelArgInfo() implementation between the address // spaces with targets without unique mapping to the OpenCL address spaces // (basically all single AS CPUs). -static unsigned ArgInfoAddressSpace(unsigned LangAS) { - switch (LangAS) { +static unsigned ArgInfoAddressSpace(LangAS AS) { + switch (AS) { case LangAS::opencl_global: return 1; case LangAS::opencl_constant: return 2; case LangAS::opencl_local: return 3; Index: cfe/trunk/lib/CodeGen/CodeGenModule.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.h +++ cfe/trunk/lib/CodeGen/CodeGenModule.h @@ -735,7 +735,7 @@ /// /// For languages without explicit address spaces, if D has default address /// space, target-specific global or constant address space may be returned. - unsigned GetGlobalVarAddressSpace(const VarDecl *D); + LangAS GetGlobalVarAddressSpace(const VarDecl *D); /// Return the llvm::Constant for the address of the given global variable. /// If Ty is non-null and if the global doesn't exist, then it will be created Index: cfe/trunk/lib/CodeGen/CodeGenModule.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp @@ -2493,10 +2493,9 @@ } } - auto ExpectedAS = + LangAS ExpectedAS = D ? D->getType().getAddressSpace() - : static_cast(LangOpts.OpenCL ? LangAS::opencl_global - : LangAS::Default); + : (LangOpts.OpenCL ? LangAS::opencl_global : LangAS::Default); assert(getContext().getTargetAddressSpace(ExpectedAS) == Ty->getPointerAddressSpace()); if (AddrSpace != ExpectedAS) @@ -2635,11 +2634,10 @@ getDataLayout().getTypeStoreSizeInBits(Ty)); } -unsigned CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) { - unsigned AddrSpace; +LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) { + LangAS AddrSpace = LangAS::Default; if (LangOpts.OpenCL) { - AddrSpace = D ? D->getType().getAddressSpace() - : static_cast(LangAS::opencl_global); + AddrSpace = D ? D->getType().getAddressSpace() : LangAS::opencl_global; assert(AddrSpace == LangAS::opencl_global || AddrSpace == LangAS::opencl_constant || AddrSpace == LangAS::opencl_local || @@ -3799,7 +3797,7 @@ !EvalResult.hasSideEffects()) Value = &EvalResult.Val; - unsigned AddrSpace = + LangAS AddrSpace = VD ? GetGlobalVarAddressSpace(VD) : MaterializedType.getAddressSpace(); Optional emitter; Index: cfe/trunk/lib/CodeGen/CodeGenTypeCache.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenTypeCache.h +++ cfe/trunk/lib/CodeGen/CodeGenTypeCache.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_LIB_CODEGEN_CODEGENTYPECACHE_H #include "clang/AST/CharUnits.h" +#include "clang/Basic/AddressSpaces.h" #include "llvm/IR/CallingConv.h" namespace llvm { @@ -94,7 +95,7 @@ unsigned char SizeAlignInBytes; }; - unsigned ASTAllocaAddressSpace; + LangAS ASTAllocaAddressSpace; CharUnits getSizeSize() const { return CharUnits::fromQuantity(SizeSizeInBytes); @@ -114,7 +115,7 @@ llvm::CallingConv::ID BuiltinCC; llvm::CallingConv::ID getBuiltinCC() const { return BuiltinCC; } - unsigned getASTAllocaAddressSpace() const { return ASTAllocaAddressSpace; } + LangAS getASTAllocaAddressSpace() const { return ASTAllocaAddressSpace; } }; } // end namespace CodeGen Index: cfe/trunk/lib/CodeGen/ConstantEmitter.h =================================================================== --- cfe/trunk/lib/CodeGen/ConstantEmitter.h +++ cfe/trunk/lib/CodeGen/ConstantEmitter.h @@ -40,7 +40,7 @@ /// The AST address space where this (non-abstract) initializer is going. /// Used for generating appropriate placeholders. - unsigned DestAddressSpace; + LangAS DestAddressSpace; llvm::SmallVector, 4> PlaceholderAddresses; @@ -68,11 +68,9 @@ /// Try to emit the initiaizer of the given declaration as an abstract /// constant. If this succeeds, the emission must be finalized. llvm::Constant *tryEmitForInitializer(const VarDecl &D); - llvm::Constant *tryEmitForInitializer(const Expr *E, - unsigned destAddrSpace, + llvm::Constant *tryEmitForInitializer(const Expr *E, LangAS destAddrSpace, QualType destType); - llvm::Constant *emitForInitializer(const APValue &value, - unsigned destAddrSpace, + llvm::Constant *emitForInitializer(const APValue &value, LangAS destAddrSpace, QualType destType); void finalize(llvm::GlobalVariable *global); @@ -151,7 +149,7 @@ llvm::GlobalValue *placeholder); private: - void initializeNonAbstract(unsigned destAS) { + void initializeNonAbstract(LangAS destAS) { assert(!InitializedNonAbstract); InitializedNonAbstract = true; DestAddressSpace = destAS; Index: cfe/trunk/lib/CodeGen/TargetInfo.h =================================================================== --- cfe/trunk/lib/CodeGen/TargetInfo.h +++ cfe/trunk/lib/CodeGen/TargetInfo.h @@ -236,11 +236,11 @@ /// other than OpenCL and CUDA. /// If \p D is nullptr, returns the default target favored address space /// for global variable. - virtual unsigned getGlobalVarAddressSpace(CodeGenModule &CGM, - const VarDecl *D) const; + virtual LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, + const VarDecl *D) const; /// Get the AST address space for alloca. - virtual unsigned getASTAllocaAddressSpace() const { return LangAS::Default; } + virtual LangAS getASTAllocaAddressSpace() const { return LangAS::Default; } /// Perform address space cast of an expression of pointer type. /// \param V is the LLVM value to be casted to another address space. @@ -249,9 +249,8 @@ /// \param DestTy is the destination LLVM pointer type. /// \param IsNonNull is the flag indicating \p V is known to be non null. virtual llvm::Value *performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, - llvm::Value *V, unsigned SrcAddr, - unsigned DestAddr, - llvm::Type *DestTy, + llvm::Value *V, LangAS SrcAddr, + LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull = false) const; /// Perform address space cast of a constant expression of pointer type. @@ -259,9 +258,10 @@ /// \param SrcAddr is the language address space of \p V. /// \param DestAddr is the targeted language address space. /// \param DestTy is the destination LLVM pointer type. - virtual llvm::Constant * - performAddrSpaceCast(CodeGenModule &CGM, llvm::Constant *V, unsigned SrcAddr, - unsigned DestAddr, llvm::Type *DestTy) const; + virtual llvm::Constant *performAddrSpaceCast(CodeGenModule &CGM, + llvm::Constant *V, + LangAS SrcAddr, LangAS DestAddr, + llvm::Type *DestTy) const; /// Get the syncscope used in LLVM IR. virtual llvm::SyncScope::ID getLLVMSyncScopeID(SyncScope S, Index: cfe/trunk/lib/CodeGen/TargetInfo.cpp =================================================================== --- cfe/trunk/lib/CodeGen/TargetInfo.cpp +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp @@ -423,18 +423,17 @@ return llvm::ConstantPointerNull::get(T); } -unsigned TargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM, - const VarDecl *D) const { +LangAS TargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM, + const VarDecl *D) const { assert(!CGM.getLangOpts().OpenCL && !(CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) && "Address space agnostic languages only"); - return D ? D->getType().getAddressSpace() - : static_cast(LangAS::Default); + return D ? D->getType().getAddressSpace() : LangAS::Default; } llvm::Value *TargetCodeGenInfo::performAddrSpaceCast( - CodeGen::CodeGenFunction &CGF, llvm::Value *Src, unsigned SrcAddr, - unsigned DestAddr, llvm::Type *DestTy, bool isNonNull) const { + CodeGen::CodeGenFunction &CGF, llvm::Value *Src, LangAS SrcAddr, + LangAS DestAddr, llvm::Type *DestTy, bool isNonNull) const { // Since target may map different address spaces in AST to the same address // space, an address space conversion may end up as a bitcast. if (auto *C = dyn_cast(Src)) @@ -444,7 +443,7 @@ llvm::Constant * TargetCodeGenInfo::performAddrSpaceCast(CodeGenModule &CGM, llvm::Constant *Src, - unsigned SrcAddr, unsigned DestAddr, + LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy) const { // Since target may map different address spaces in AST to the same address // space, an address space conversion may end up as a bitcast. @@ -7611,12 +7610,12 @@ llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM, llvm::PointerType *T, QualType QT) const override; - unsigned getASTAllocaAddressSpace() const override { - return LangAS::FirstTargetAddressSpace + - getABIInfo().getDataLayout().getAllocaAddrSpace(); + LangAS getASTAllocaAddressSpace() const override { + return getLangASFromTargetAS( + getABIInfo().getDataLayout().getAllocaAddrSpace()); } - unsigned getGlobalVarAddressSpace(CodeGenModule &CGM, - const VarDecl *D) const override; + LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, + const VarDecl *D) const override; llvm::SyncScope::ID getLLVMSyncScopeID(SyncScope S, llvm::LLVMContext &C) const override; llvm::Function * @@ -7707,21 +7706,19 @@ llvm::ConstantPointerNull::get(NPT), PT); } -unsigned +LangAS AMDGPUTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D) const { assert(!CGM.getLangOpts().OpenCL && !(CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) && "Address space agnostic languages only"); - unsigned DefaultGlobalAS = - LangAS::FirstTargetAddressSpace + - CGM.getContext().getTargetAddressSpace(LangAS::opencl_global); + LangAS DefaultGlobalAS = getLangASFromTargetAS( + CGM.getContext().getTargetAddressSpace(LangAS::opencl_global)); if (!D) return DefaultGlobalAS; - unsigned AddrSpace = D->getType().getAddressSpace(); - assert(AddrSpace == LangAS::Default || - AddrSpace >= LangAS::FirstTargetAddressSpace); + LangAS AddrSpace = D->getType().getAddressSpace(); + assert(AddrSpace == LangAS::Default || isTargetAddressSpace(AddrSpace)); if (AddrSpace != LangAS::Default) return AddrSpace; Index: cfe/trunk/lib/Sema/SemaChecking.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaChecking.cpp +++ cfe/trunk/lib/Sema/SemaChecking.cpp @@ -3140,7 +3140,7 @@ // Treat this argument as _Nonnull as we want to show a warning if // NULL is passed into it. CheckNonNullArgument(*this, ValArg, DRE->getLocStart()); - unsigned AS = 0; + LangAS AS = LangAS::Default; // Keep address space of non-atomic pointer type. if (const PointerType *PtrTy = ValArg->getType()->getAs()) { Index: cfe/trunk/lib/Sema/SemaDecl.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp +++ cfe/trunk/lib/Sema/SemaDecl.cpp @@ -7332,8 +7332,8 @@ // 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 (!getLangOpts().OpenCL - && NewVD->hasLocalStorage() && T.getAddressSpace() != 0) { + if (!getLangOpts().OpenCL && NewVD->hasLocalStorage() && + T.getAddressSpace() != LangAS::Default) { Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl) << 0; NewVD->setInvalidDecl(); return; @@ -8833,7 +8833,7 @@ if (getLangOpts().OpenCL) { // OpenCL v1.1 s6.5: Using an address space qualifier in a function return // type declaration will generate a compilation error. - unsigned AddressSpace = NewFD->getReturnType().getAddressSpace(); + LangAS AddressSpace = NewFD->getReturnType().getAddressSpace(); if (AddressSpace != LangAS::Default) { Diag(NewFD->getLocation(), diag::err_opencl_return_value_with_address_space); Index: cfe/trunk/lib/Sema/SemaDeclAttr.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp @@ -4385,7 +4385,7 @@ static bool isValidSwiftContextType(QualType type) { if (!type->hasPointerRepresentation()) return type->isDependentType(); - return type->getPointeeType().getAddressSpace() == 0; + return type->getPointeeType().getAddressSpace() == LangAS::Default; } /// Pointers and references in the default address space. @@ -4397,7 +4397,7 @@ } else { return type->isDependentType(); } - return type.getAddressSpace() == 0; + return type.getAddressSpace() == LangAS::Default; } /// Pointers and references to pointers in the default address space. Index: cfe/trunk/lib/Sema/SemaDeclObjC.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaDeclObjC.cpp +++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp @@ -4688,7 +4688,7 @@ // duration shall not be qualified by an address-space qualifier." // Since all parameters have automatic store duration, they can not have // an address space. - if (T.getAddressSpace() != 0) { + if (T.getAddressSpace() != LangAS::Default) { Diag(IdLoc, diag::err_arg_with_address_space); Invalid = true; } Index: cfe/trunk/lib/Sema/SemaExpr.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp +++ cfe/trunk/lib/Sema/SemaExpr.cpp @@ -5064,7 +5064,7 @@ } NeedsNewDecl = true; - unsigned AS = ArgType->getPointeeType().getQualifiers().getAddressSpace(); + LangAS AS = ArgType->getPointeeType().getAddressSpace(); QualType PointeeType = ParamType->getPointeeType(); PointeeType = Context.getAddrSpaceQualType(PointeeType, AS); @@ -5760,8 +5760,8 @@ case Type::STK_ObjCObjectPointer: switch (DestTy->getScalarTypeKind()) { case Type::STK_CPointer: { - unsigned SrcAS = SrcTy->getPointeeType().getAddressSpace(); - unsigned DestAS = DestTy->getPointeeType().getAddressSpace(); + LangAS SrcAS = SrcTy->getPointeeType().getAddressSpace(); + LangAS DestAS = DestTy->getPointeeType().getAddressSpace(); if (SrcAS != DestAS) return CK_AddressSpaceConversion; return CK_BitCast; @@ -6365,9 +6365,9 @@ Qualifiers lhQual = lhptee.getQualifiers(); Qualifiers rhQual = rhptee.getQualifiers(); - unsigned ResultAddrSpace = 0; - unsigned LAddrSpace = lhQual.getAddressSpace(); - unsigned RAddrSpace = rhQual.getAddressSpace(); + LangAS ResultAddrSpace = LangAS::Default; + LangAS LAddrSpace = lhQual.getAddressSpace(); + LangAS RAddrSpace = rhQual.getAddressSpace(); if (S.getLangOpts().OpenCL) { // OpenCL v1.1 s6.5 - Conversion between pointers to distinct address // spaces is disallowed. @@ -7649,8 +7649,8 @@ if (const PointerType *LHSPointer = dyn_cast(LHSType)) { // U* -> T* if (isa(RHSType)) { - unsigned AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace(); - unsigned AddrSpaceR = RHSType->getPointeeType().getAddressSpace(); + LangAS AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace(); + LangAS AddrSpaceR = RHSType->getPointeeType().getAddressSpace(); Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast; return checkPointerTypesForAssignment(*this, LHSType, RHSType); } @@ -7685,10 +7685,10 @@ // U^ -> void* if (RHSType->getAs()) { if (LHSPointer->getPointeeType()->isVoidType()) { - unsigned AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace(); - unsigned AddrSpaceR = RHSType->getAs() - ->getPointeeType() - .getAddressSpace(); + LangAS AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace(); + LangAS AddrSpaceR = RHSType->getAs() + ->getPointeeType() + .getAddressSpace(); Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast; return Compatible; @@ -7702,12 +7702,12 @@ if (isa(LHSType)) { // U^ -> T^ if (RHSType->isBlockPointerType()) { - unsigned AddrSpaceL = LHSType->getAs() - ->getPointeeType() - .getAddressSpace(); - unsigned AddrSpaceR = RHSType->getAs() - ->getPointeeType() - .getAddressSpace(); + LangAS AddrSpaceL = LHSType->getAs() + ->getPointeeType() + .getAddressSpace(); + LangAS AddrSpaceR = RHSType->getAs() + ->getPointeeType() + .getAddressSpace(); Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast; return checkBlockPointerTypesForAssignment(*this, LHSType, RHSType); } @@ -9804,8 +9804,8 @@ << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); } } - unsigned AddrSpaceL = LCanPointeeTy.getAddressSpace(); - unsigned AddrSpaceR = RCanPointeeTy.getAddressSpace(); + LangAS AddrSpaceL = LCanPointeeTy.getAddressSpace(); + LangAS AddrSpaceR = RCanPointeeTy.getAddressSpace(); CastKind Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast; if (LHSIsNull && !RHSIsNull) Index: cfe/trunk/lib/Sema/SemaExprCXX.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp @@ -2113,7 +2113,7 @@ else if (AllocType->isVariablyModifiedType()) return Diag(Loc, diag::err_variably_modified_new_type) << AllocType; - else if (AllocType.getAddressSpace()) + else if (AllocType.getAddressSpace() != LangAS::Default) return Diag(Loc, diag::err_address_space_qualified_new) << AllocType.getUnqualifiedType() << AllocType.getQualifiers().getAddressSpaceAttributePrintValue(); @@ -3185,7 +3185,7 @@ QualType Pointee = Type->getAs()->getPointeeType(); QualType PointeeElem = Context.getBaseElementType(Pointee); - if (Pointee.getAddressSpace()) + if (Pointee.getAddressSpace() != LangAS::Default) return Diag(Ex.get()->getLocStart(), diag::err_address_space_qualified_delete) << Pointee.getUnqualifiedType() Index: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp @@ -1870,11 +1870,10 @@ Deduced); } - if (Arg.getAddressSpace() >= LangAS::FirstTargetAddressSpace) { + if (isTargetAddressSpace(Arg.getAddressSpace())) { llvm::APSInt ArgAddressSpace(S.Context.getTypeSize(S.Context.IntTy), false); - ArgAddressSpace = - (Arg.getAddressSpace() - LangAS::FirstTargetAddressSpace); + ArgAddressSpace = toTargetAddressSpace(Arg.getAddressSpace()); // Perform deduction on the pointer types. if (Sema::TemplateDeductionResult Result = Index: cfe/trunk/lib/Sema/SemaType.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp +++ cfe/trunk/lib/Sema/SemaType.cpp @@ -5631,7 +5631,7 @@ // If this type is already address space qualified, reject it. // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified // by qualifiers for two or more different address spaces." - if (T.getAddressSpace()) { + if (T.getAddressSpace() != LangAS::Default) { Diag(AttrLoc, diag::err_attribute_address_multiple_qualifiers); return QualType(); } @@ -5655,15 +5655,16 @@ } llvm::APSInt max(addrSpace.getBitWidth()); - max = Qualifiers::MaxAddressSpace - LangAS::FirstTargetAddressSpace; + max = + Qualifiers::MaxAddressSpace - (unsigned)LangAS::FirstTargetAddressSpace; if (addrSpace > max) { Diag(AttrLoc, diag::err_attribute_address_space_too_high) << (unsigned)max.getZExtValue() << AddrSpace->getSourceRange(); return QualType(); } - unsigned ASIdx = static_cast(addrSpace.getZExtValue()) + - LangAS::FirstTargetAddressSpace; + LangAS ASIdx = + getLangASFromTargetAS(static_cast(addrSpace.getZExtValue())); return Context.getAddrSpaceQualType(T, ASIdx); } @@ -5689,7 +5690,7 @@ // If this type is already address space qualified, reject it. // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified by // qualifiers for two or more different address spaces." - if (Type.getAddressSpace()) { + if (Type.getAddressSpace() != LangAS::Default) { S.Diag(Attr.getLoc(), diag::err_attribute_address_multiple_qualifiers); Attr.setInvalid(); return; @@ -5703,7 +5704,7 @@ return; } - unsigned ASIdx; + LangAS ASIdx; if (Attr.getKind() == AttributeList::AT_AddressSpace) { // Check the attribute arguments. @@ -7036,7 +7037,7 @@ (T->isVoidType() && !IsPointee)) return; - unsigned ImpAddr; + LangAS ImpAddr; // Put OpenCL automatic variable in private address space. // OpenCL v1.2 s6.5: // The default address space name for arguments to a function in a Index: cfe/trunk/tools/libclang/CXType.cpp =================================================================== --- cfe/trunk/tools/libclang/CXType.cpp +++ cfe/trunk/tools/libclang/CXType.cpp @@ -403,7 +403,10 @@ if (T.getAddressSpace() >= LangAS::FirstTargetAddressSpace) { return T.getQualifiers().getAddressSpaceAttributePrintValue(); } - return T.getAddressSpace(); + // FIXME: this function returns either a LangAS or a target AS + // Those values can overlap which makes this function rather unpredictable + // for any caller + return (unsigned)T.getAddressSpace(); } CXString clang_getTypedefName(CXType CT) {