Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit d27ee8f

Browse files
committed
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@314649 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 783c352 commit d27ee8f

21 files changed

+591
-45
lines changed

include/clang/AST/ASTContext.h

+13
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
143143
mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
144144
mutable llvm::FoldingSet<DependentSizedExtVectorType>
145145
DependentSizedExtVectorTypes;
146+
mutable llvm::FoldingSet<DependentAddressSpaceType>
147+
DependentAddressSpaceTypes;
146148
mutable llvm::FoldingSet<VectorType> VectorTypes;
147149
mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
148150
mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
@@ -1070,6 +1072,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
10701072
/// replaced.
10711073
QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const;
10721074

1075+
/// \brief Remove any existing address space on the type and returns the type
1076+
/// with qualifiers intact (or that's the idea anyway)
1077+
///
1078+
/// The return type should be T with all prior qualifiers minus the address
1079+
/// space.
1080+
QualType removeAddrSpaceQualType(QualType T) const;
1081+
10731082
/// \brief Apply Objective-C protocol qualifiers to the given type.
10741083
/// \param allowOnPointerType specifies if we can apply protocol
10751084
/// qualifiers on ObjCObjectPointerType. It can be set to true when
@@ -1270,6 +1279,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
12701279
Expr *SizeExpr,
12711280
SourceLocation AttrLoc) const;
12721281

1282+
QualType getDependentAddressSpaceType(QualType PointeeType,
1283+
Expr *AddrSpaceExpr,
1284+
SourceLocation AttrLoc) const;
1285+
12731286
/// \brief Return a K&R style C function type like 'int()'.
12741287
QualType getFunctionNoProtoType(QualType ResultTy,
12751288
const FunctionType::ExtInfo &Info) const;

include/clang/AST/RecursiveASTVisitor.h

+10
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,11 @@ DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
988988
TRY_TO(TraverseStmt(T->getSizeExpr()));
989989
})
990990

991+
DEF_TRAVERSE_TYPE(DependentAddressSpaceType, {
992+
TRY_TO(TraverseStmt(T->getAddrSpaceExpr()));
993+
TRY_TO(TraverseType(T->getPointeeType()));
994+
})
995+
991996
DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
992997
if (T->getSizeExpr())
993998
TRY_TO(TraverseStmt(T->getSizeExpr()));
@@ -1198,6 +1203,11 @@ DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
11981203
return TraverseArrayTypeLocHelper(TL);
11991204
})
12001205

1206+
DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, {
1207+
TRY_TO(TraverseStmt(TL.getTypePtr()->getAddrSpaceExpr()));
1208+
TRY_TO(TraverseType(TL.getTypePtr()->getPointeeType()));
1209+
})
1210+
12011211
// FIXME: order? why not size expr first?
12021212
// FIXME: base VectorTypeLoc is unfinished
12031213
DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {

include/clang/AST/Type.h

+47
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,7 @@ class Type : public ExtQualsTypeCommonBase {
17051705
bool isComplexIntegerType() const; // GCC _Complex integer type.
17061706
bool isVectorType() const; // GCC vector type.
17071707
bool isExtVectorType() const; // Extended vector type.
1708+
bool isDependentAddressSpaceType() const; // value-dependent address space qualifier
17081709
bool isObjCObjectPointerType() const; // pointer to ObjC object
17091710
bool isObjCRetainableType() const; // ObjC object or block pointer
17101711
bool isObjCLifetimeType() const; // (array of)* retainable type
@@ -2743,6 +2744,49 @@ class DependentSizedArrayType : public ArrayType {
27432744
unsigned TypeQuals, Expr *E);
27442745
};
27452746

2747+
/// Represents an extended address space qualifier where the input address space
2748+
/// value is dependent. Non-dependent address spaces are not represented with a
2749+
/// special Type subclass; they are stored on an ExtQuals node as part of a QualType.
2750+
///
2751+
/// For example:
2752+
/// \code
2753+
/// template<typename T, int AddrSpace>
2754+
/// class AddressSpace {
2755+
/// typedef T __attribute__((address_space(AddrSpace))) type;
2756+
/// }
2757+
/// \endcode
2758+
class DependentAddressSpaceType : public Type, public llvm::FoldingSetNode {
2759+
const ASTContext &Context;
2760+
Expr *AddrSpaceExpr;
2761+
QualType PointeeType;
2762+
SourceLocation loc;
2763+
2764+
DependentAddressSpaceType(const ASTContext &Context, QualType PointeeType,
2765+
QualType can, Expr *AddrSpaceExpr,
2766+
SourceLocation loc);
2767+
2768+
friend class ASTContext;
2769+
2770+
public:
2771+
Expr *getAddrSpaceExpr() const { return AddrSpaceExpr; }
2772+
QualType getPointeeType() const { return PointeeType; }
2773+
SourceLocation getAttributeLoc() const { return loc; }
2774+
2775+
bool isSugared() const { return false; }
2776+
QualType desugar() const { return QualType(this, 0); }
2777+
2778+
static bool classof(const Type *T) {
2779+
return T->getTypeClass() == DependentAddressSpace;
2780+
}
2781+
2782+
void Profile(llvm::FoldingSetNodeID &ID) {
2783+
Profile(ID, Context, getPointeeType(), getAddrSpaceExpr());
2784+
}
2785+
2786+
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
2787+
QualType PointeeType, Expr *AddrSpaceExpr);
2788+
};
2789+
27462790
/// Represents an extended vector type where either the type or size is
27472791
/// dependent.
27482792
///
@@ -5791,6 +5835,9 @@ inline bool Type::isVectorType() const {
57915835
inline bool Type::isExtVectorType() const {
57925836
return isa<ExtVectorType>(CanonicalType);
57935837
}
5838+
inline bool Type::isDependentAddressSpaceType() const {
5839+
return isa<DependentAddressSpaceType>(CanonicalType);
5840+
}
57945841
inline bool Type::isObjCObjectPointerType() const {
57955842
return isa<ObjCObjectPointerType>(CanonicalType);
57965843
}

include/clang/AST/TypeLoc.h

+70
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,76 @@ class TemplateSpecializationTypeLoc :
16641664
}
16651665
};
16661666

1667+
struct DependentAddressSpaceLocInfo {
1668+
Expr *ExprOperand;
1669+
SourceRange OperandParens;
1670+
SourceLocation AttrLoc;
1671+
};
1672+
1673+
class DependentAddressSpaceTypeLoc
1674+
: public ConcreteTypeLoc<UnqualTypeLoc,
1675+
DependentAddressSpaceTypeLoc,
1676+
DependentAddressSpaceType,
1677+
DependentAddressSpaceLocInfo> {
1678+
1679+
public:
1680+
1681+
/// The location of the attribute name, i.e.
1682+
/// int * __attribute__((address_space(11)))
1683+
/// ^~~~~~~~~~~~~
1684+
SourceLocation getAttrNameLoc() const {
1685+
return getLocalData()->AttrLoc;
1686+
}
1687+
void setAttrNameLoc(SourceLocation loc) {
1688+
getLocalData()->AttrLoc = loc;
1689+
}
1690+
1691+
/// The attribute's expression operand, if it has one.
1692+
/// int * __attribute__((address_space(11)))
1693+
/// ^~
1694+
Expr *getAttrExprOperand() const {
1695+
return getLocalData()->ExprOperand;
1696+
}
1697+
void setAttrExprOperand(Expr *e) {
1698+
getLocalData()->ExprOperand = e;
1699+
}
1700+
1701+
/// The location of the parentheses around the operand, if there is
1702+
/// an operand.
1703+
/// int * __attribute__((address_space(11)))
1704+
/// ^ ^
1705+
SourceRange getAttrOperandParensRange() const {
1706+
return getLocalData()->OperandParens;
1707+
}
1708+
void setAttrOperandParensRange(SourceRange range) {
1709+
getLocalData()->OperandParens = range;
1710+
}
1711+
1712+
SourceRange getLocalSourceRange() const {
1713+
SourceRange range(getAttrNameLoc());
1714+
range.setEnd(getAttrOperandParensRange().getEnd());
1715+
return range;
1716+
}
1717+
1718+
/// Returns the type before the address space attribute application
1719+
/// area.
1720+
/// int * __attribute__((address_space(11))) *
1721+
/// ^ ^
1722+
QualType getInnerType() const {
1723+
return this->getTypePtr()->getPointeeType();
1724+
}
1725+
1726+
TypeLoc getPointeeTypeLoc() const {
1727+
return this->getInnerTypeLoc();
1728+
}
1729+
1730+
void initializeLocal(ASTContext &Context, SourceLocation loc) {
1731+
setAttrNameLoc(loc);
1732+
setAttrOperandParensRange(SourceRange(loc));
1733+
setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
1734+
}
1735+
};
1736+
16671737
//===----------------------------------------------------------------------===//
16681738
//
16691739
// All of these need proper implementations.

include/clang/AST/TypeNodes.def

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ TYPE(IncompleteArray, ArrayType)
7373
TYPE(VariableArray, ArrayType)
7474
DEPENDENT_TYPE(DependentSizedArray, ArrayType)
7575
DEPENDENT_TYPE(DependentSizedExtVector, Type)
76+
DEPENDENT_TYPE(DependentAddressSpace, Type)
7677
TYPE(Vector, Type)
7778
TYPE(ExtVector, VectorType)
7879
ABSTRACT_TYPE(Function, Type)

include/clang/Sema/Sema.h

+2
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,8 @@ class Sema {
13781378
SourceRange Brackets, DeclarationName Entity);
13791379
QualType BuildExtVectorType(QualType T, Expr *ArraySize,
13801380
SourceLocation AttrLoc);
1381+
QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
1382+
SourceLocation AttrLoc);
13811383

13821384
bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
13831385

include/clang/Serialization/ASTBitCodes.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,9 @@ namespace clang {
940940
/// \brief A DeducedTemplateSpecializationType record.
941941
TYPE_DEDUCED_TEMPLATE_SPECIALIZATION = 45,
942942
/// \brief A DependentSizedExtVectorType record.
943-
TYPE_DEPENDENT_SIZED_EXT_VECTOR = 46
943+
TYPE_DEPENDENT_SIZED_EXT_VECTOR = 46,
944+
/// \brief A DependentAddressSpaceType record.
945+
TYPE_DEPENDENT_ADDRESS_SPACE = 47
944946
};
945947

946948
/// \brief The type IDs for special types constructed by semantic

lib/AST/ASTContext.cpp

+57
Original file line numberDiff line numberDiff line change
@@ -2302,6 +2302,27 @@ ASTContext::getAddrSpaceQualType(QualType T, unsigned AddressSpace) const {
23022302
return getExtQualType(TypeNode, Quals);
23032303
}
23042304

2305+
QualType ASTContext::removeAddrSpaceQualType(QualType T) const {
2306+
// If we are composing extended qualifiers together, merge together
2307+
// into one ExtQuals node.
2308+
QualifierCollector Quals;
2309+
const Type *TypeNode = Quals.strip(T);
2310+
2311+
// If the qualifier doesn't have an address space just return it.
2312+
if (!Quals.hasAddressSpace())
2313+
return T;
2314+
2315+
Quals.removeAddressSpace();
2316+
2317+
// Removal of the address space can mean there are no longer any
2318+
// non-fast qualifiers, so creating an ExtQualType isn't possible (asserts)
2319+
// or required.
2320+
if (Quals.hasNonFastQualifiers())
2321+
return getExtQualType(TypeNode, Quals);
2322+
else
2323+
return QualType(TypeNode, Quals.getFastQualifiers());
2324+
}
2325+
23052326
QualType ASTContext::getObjCGCQualType(QualType T,
23062327
Qualifiers::GC GCAttr) const {
23072328
QualType CanT = getCanonicalType(T);
@@ -2752,6 +2773,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
27522773
case Type::Vector:
27532774
case Type::ExtVector:
27542775
case Type::DependentSizedExtVector:
2776+
case Type::DependentAddressSpace:
27552777
case Type::ObjCObject:
27562778
case Type::ObjCInterface:
27572779
case Type::ObjCObjectPointer:
@@ -3100,6 +3122,41 @@ ASTContext::getDependentSizedExtVectorType(QualType vecType,
31003122
return QualType(New, 0);
31013123
}
31023124

3125+
QualType ASTContext::getDependentAddressSpaceType(QualType PointeeType,
3126+
Expr *AddrSpaceExpr,
3127+
SourceLocation AttrLoc) const {
3128+
assert(AddrSpaceExpr->isInstantiationDependent());
3129+
3130+
QualType canonPointeeType = getCanonicalType(PointeeType);
3131+
3132+
void *insertPos = nullptr;
3133+
llvm::FoldingSetNodeID ID;
3134+
DependentAddressSpaceType::Profile(ID, *this, canonPointeeType,
3135+
AddrSpaceExpr);
3136+
3137+
DependentAddressSpaceType *canonTy =
3138+
DependentAddressSpaceTypes.FindNodeOrInsertPos(ID, insertPos);
3139+
3140+
if (!canonTy) {
3141+
canonTy = new (*this, TypeAlignment)
3142+
DependentAddressSpaceType(*this, canonPointeeType,
3143+
QualType(), AddrSpaceExpr, AttrLoc);
3144+
DependentAddressSpaceTypes.InsertNode(canonTy, insertPos);
3145+
Types.push_back(canonTy);
3146+
}
3147+
3148+
if (canonPointeeType == PointeeType &&
3149+
canonTy->getAddrSpaceExpr() == AddrSpaceExpr)
3150+
return QualType(canonTy, 0);
3151+
3152+
DependentAddressSpaceType *sugaredType
3153+
= new (*this, TypeAlignment)
3154+
DependentAddressSpaceType(*this, PointeeType, QualType(canonTy, 0),
3155+
AddrSpaceExpr, AttrLoc);
3156+
Types.push_back(sugaredType);
3157+
return QualType(sugaredType, 0);
3158+
}
3159+
31033160
/// \brief Determine whether \p T is canonical as the result type of a function.
31043161
static bool isCanonicalResultType(QualType T) {
31053162
return T.isCanonical() &&

lib/AST/ASTStructuralEquivalence.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,21 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
365365
break;
366366
}
367367

368+
case Type::DependentAddressSpace: {
369+
const DependentAddressSpaceType *DepAddressSpace1 =
370+
cast<DependentAddressSpaceType>(T1);
371+
const DependentAddressSpaceType *DepAddressSpace2 =
372+
cast<DependentAddressSpaceType>(T2);
373+
if (!IsStructurallyEquivalent(Context, DepAddressSpace1->getAddrSpaceExpr(),
374+
DepAddressSpace2->getAddrSpaceExpr()))
375+
return false;
376+
if (!IsStructurallyEquivalent(Context, DepAddressSpace1->getPointeeType(),
377+
DepAddressSpace2->getPointeeType()))
378+
return false;
379+
380+
break;
381+
}
382+
368383
case Type::DependentSizedExtVector: {
369384
const DependentSizedExtVectorType *Vec1 =
370385
cast<DependentSizedExtVectorType>(T1);

0 commit comments

Comments
 (0)