Dependent Address Space Support
This patch relates to: https://reviews.llvm.org/D33666 This adds support
for template parameters to be passed to the address_space attribute.
The main goal is to add further flexibility to the attribute and allow
for it to be used easily with templates.
The main additions are a new type (DependentAddressSpaceType) alongside
its TypeLoc and its mangling. As well as the logic required to support
dependent address spaces which mainly resides in TreeTransform.h and
SemaType.cpp.
llvm-svn: 314649
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 2a60799..a657eed 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2302,6 +2302,27 @@
return getExtQualType(TypeNode, Quals);
}
+QualType ASTContext::removeAddrSpaceQualType(QualType T) const {
+ // If we are composing extended qualifiers together, merge together
+ // into one ExtQuals node.
+ QualifierCollector Quals;
+ const Type *TypeNode = Quals.strip(T);
+
+ // If the qualifier doesn't have an address space just return it.
+ if (!Quals.hasAddressSpace())
+ return T;
+
+ Quals.removeAddressSpace();
+
+ // Removal of the address space can mean there are no longer any
+ // non-fast qualifiers, so creating an ExtQualType isn't possible (asserts)
+ // or required.
+ if (Quals.hasNonFastQualifiers())
+ return getExtQualType(TypeNode, Quals);
+ else
+ return QualType(TypeNode, Quals.getFastQualifiers());
+}
+
QualType ASTContext::getObjCGCQualType(QualType T,
Qualifiers::GC GCAttr) const {
QualType CanT = getCanonicalType(T);
@@ -2752,6 +2773,7 @@
case Type::Vector:
case Type::ExtVector:
case Type::DependentSizedExtVector:
+ case Type::DependentAddressSpace:
case Type::ObjCObject:
case Type::ObjCInterface:
case Type::ObjCObjectPointer:
@@ -3100,6 +3122,41 @@
return QualType(New, 0);
}
+QualType ASTContext::getDependentAddressSpaceType(QualType PointeeType,
+ Expr *AddrSpaceExpr,
+ SourceLocation AttrLoc) const {
+ assert(AddrSpaceExpr->isInstantiationDependent());
+
+ QualType canonPointeeType = getCanonicalType(PointeeType);
+
+ void *insertPos = nullptr;
+ llvm::FoldingSetNodeID ID;
+ DependentAddressSpaceType::Profile(ID, *this, canonPointeeType,
+ AddrSpaceExpr);
+
+ DependentAddressSpaceType *canonTy =
+ DependentAddressSpaceTypes.FindNodeOrInsertPos(ID, insertPos);
+
+ if (!canonTy) {
+ canonTy = new (*this, TypeAlignment)
+ DependentAddressSpaceType(*this, canonPointeeType,
+ QualType(), AddrSpaceExpr, AttrLoc);
+ DependentAddressSpaceTypes.InsertNode(canonTy, insertPos);
+ Types.push_back(canonTy);
+ }
+
+ if (canonPointeeType == PointeeType &&
+ canonTy->getAddrSpaceExpr() == AddrSpaceExpr)
+ return QualType(canonTy, 0);
+
+ DependentAddressSpaceType *sugaredType
+ = new (*this, TypeAlignment)
+ DependentAddressSpaceType(*this, PointeeType, QualType(canonTy, 0),
+ AddrSpaceExpr, AttrLoc);
+ Types.push_back(sugaredType);
+ return QualType(sugaredType, 0);
+}
+
/// \brief Determine whether \p T is canonical as the result type of a function.
static bool isCanonicalResultType(QualType T) {
return T.isCanonical() &&