Skip to content

Commit bd44742

Browse files
committed
[clang/AST] Make it possible to use SwiftAttr in type context
Swift ClangImporter now supports concurrency annotations on imported declarations and their parameters/results, to make it possible to use imported APIs in Swift safely there has to be a way to annotate individual parameters and result types with relevant attributes that indicate that e.g. a block is called on a particular actor or it accepts a `Sendable` parameter. To faciliate that `SwiftAttr` is switched from `InheritableAttr` which is a declaration attribute to `DeclOrTypeAttr`. To support this attribute in type context we need access to its "Attribute" argument which requires `AttributedType` to be extended to include `Attr *` when available instead of just `attr::Kind` otherwise it won't be possible to determine what attribute should be imported.
1 parent 02e4186 commit bd44742

22 files changed

+229
-84
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,8 +1677,15 @@ class ASTContext : public RefCountedBase<ASTContext> {
16771677
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
16781678

16791679
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType,
1680+
QualType equivalentType,
1681+
const Attr *attr = nullptr) const;
1682+
1683+
QualType getAttributedType(const Attr *attr, QualType modifiedType,
16801684
QualType equivalentType) const;
16811685

1686+
QualType getAttributedType(NullabilityKind nullability, QualType modifiedType,
1687+
QualType equivalentType);
1688+
16821689
QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
16831690
QualType Wrapped);
16841691

clang/include/clang/AST/PropertiesBase.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ def APValue : PropertyType { let PassByReference = 1; }
7676
def APValueKind : EnumPropertyType<"APValue::ValueKind">;
7777
def ArraySizeModifier : EnumPropertyType<"ArraySizeModifier">;
7878
def AttrKind : EnumPropertyType<"attr::Kind">;
79+
def Attr : PropertyType<"const Attr *">;
7980
def AutoTypeKeyword : EnumPropertyType;
8081
def Bool : PropertyType<"bool">;
8182
def BuiltinTypeKind : EnumPropertyType<"BuiltinType::Kind">;

clang/include/clang/AST/Type.h

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class ValueDecl;
6868
class TagDecl;
6969
class TemplateParameterList;
7070
class Type;
71+
class Attr;
7172

7273
enum {
7374
TypeAlignmentInBits = 4,
@@ -6037,21 +6038,29 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
60376038
private:
60386039
friend class ASTContext; // ASTContext creates these
60396040

6041+
const Attr *Attribute;
6042+
60406043
QualType ModifiedType;
60416044
QualType EquivalentType;
60426045

60436046
AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
60446047
QualType equivalent)
6045-
: Type(Attributed, canon, equivalent->getDependence()),
6046-
ModifiedType(modified), EquivalentType(equivalent) {
6047-
AttributedTypeBits.AttrKind = attrKind;
6048-
}
6048+
: AttributedType(canon, attrKind, nullptr, modified, equivalent) {}
6049+
6050+
AttributedType(QualType canon, const Attr *attr, QualType modified,
6051+
QualType equivalent);
6052+
6053+
private:
6054+
AttributedType(QualType canon, attr::Kind attrKind, const Attr *attr,
6055+
QualType modified, QualType equivalent);
60496056

60506057
public:
60516058
Kind getAttrKind() const {
60526059
return static_cast<Kind>(AttributedTypeBits.AttrKind);
60536060
}
60546061

6062+
const Attr *getAttr() const { return Attribute; }
6063+
60556064
QualType getModifiedType() const { return ModifiedType; }
60566065
QualType getEquivalentType() const { return EquivalentType; }
60576066

@@ -6083,25 +6092,6 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
60836092

60846093
std::optional<NullabilityKind> getImmediateNullability() const;
60856094

6086-
/// Retrieve the attribute kind corresponding to the given
6087-
/// nullability kind.
6088-
static Kind getNullabilityAttrKind(NullabilityKind kind) {
6089-
switch (kind) {
6090-
case NullabilityKind::NonNull:
6091-
return attr::TypeNonNull;
6092-
6093-
case NullabilityKind::Nullable:
6094-
return attr::TypeNullable;
6095-
6096-
case NullabilityKind::NullableResult:
6097-
return attr::TypeNullableResult;
6098-
6099-
case NullabilityKind::Unspecified:
6100-
return attr::TypeNullUnspecified;
6101-
}
6102-
llvm_unreachable("Unknown nullability kind.");
6103-
}
6104-
61056095
/// Strip off the top-level nullability annotation on the given
61066096
/// type, if it's there.
61076097
///
@@ -6114,14 +6104,16 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
61146104
static std::optional<NullabilityKind> stripOuterNullability(QualType &T);
61156105

61166106
void Profile(llvm::FoldingSetNodeID &ID) {
6117-
Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
6107+
Profile(ID, getAttrKind(), ModifiedType, EquivalentType, Attribute);
61186108
}
61196109

61206110
static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
6121-
QualType modified, QualType equivalent) {
6111+
QualType modified, QualType equivalent,
6112+
const Attr *attr) {
61226113
ID.AddInteger(attrKind);
61236114
ID.AddPointer(modified.getAsOpaquePtr());
61246115
ID.AddPointer(equivalent.getAsOpaquePtr());
6116+
ID.AddPointer(attr);
61256117
}
61266118

61276119
static bool classof(const Type *T) {

clang/include/clang/AST/TypeProperties.td

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,12 +668,16 @@ let Class = AttributedType in {
668668
def : Property<"equivalentType", QualType> {
669669
let Read = [{ node->getEquivalentType() }];
670670
}
671-
def : Property<"attribute", AttrKind> {
671+
def : Property<"attrKind", AttrKind> {
672672
let Read = [{ node->getAttrKind() }];
673673
}
674+
def : Property<"attribute", Attr> {
675+
let Read = [{ node->getAttr() }];
676+
}
674677

675678
def : Creator<[{
676-
return ctx.getAttributedType(attribute, modifiedType, equivalentType);
679+
return ctx.getAttributedType(attrKind, modifiedType,
680+
equivalentType, attribute);
677681
}]>;
678682
}
679683

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2834,7 +2834,7 @@ def SwiftAsyncName : InheritableAttr {
28342834
let Documentation = [SwiftAsyncNameDocs];
28352835
}
28362836

2837-
def SwiftAttr : InheritableAttr {
2837+
def SwiftAttr : DeclOrTypeAttr {
28382838
let Spellings = [GNU<"swift_attr">];
28392839
let Args = [StringArgument<"Attribute">];
28402840
let Documentation = [SwiftAttrDocs];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4489,8 +4489,8 @@ def SwiftAttrDocs : Documentation {
44894489
let Heading = "swift_attr";
44904490
let Content = [{
44914491
The ``swift_attr`` provides a Swift-specific annotation for the declaration
4492-
to which the attribute appertains to. It can be used on any declaration
4493-
in Clang. This kind of annotation is ignored by Clang as it doesn't have any
4492+
or type to which the attribute appertains to. It can be used on any declaration
4493+
or type in Clang. This kind of annotation is ignored by Clang as it doesn't have any
44944494
semantic meaning in languages supported by Clang. The Swift compiler can
44954495
interpret these annotations according to its own rules when importing C or
44964496
Objective-C declarations.

clang/include/clang/Serialization/ASTRecordWriter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ class ASTRecordWriter
128128
AddStmt(const_cast<Stmt*>(S));
129129
}
130130

131+
void writeAttr(const Attr *A) { AddAttr(A); }
132+
131133
/// Write an BTFTypeTagAttr object.
132134
void writeBTFTypeTagAttr(const BTFTypeTagAttr *A) { AddAttr(A); }
133135

clang/lib/AST/ASTContext.cpp

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3566,11 +3566,13 @@ QualType ASTContext::getFunctionTypeWithExceptionSpec(
35663566
MQT->getMacroIdentifier());
35673567

35683568
// Might have a calling-convention attribute.
3569-
if (const auto *AT = dyn_cast<AttributedType>(Orig))
3569+
if (const auto *AT = dyn_cast<AttributedType>(Orig)) {
35703570
return getAttributedType(
35713571
AT->getAttrKind(),
35723572
getFunctionTypeWithExceptionSpec(AT->getModifiedType(), ESI),
3573-
getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI));
3573+
getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI),
3574+
AT->getAttr());
3575+
}
35743576

35753577
// Anything else must be a function type. Rebuild it with the new exception
35763578
// specification.
@@ -5125,24 +5127,54 @@ QualType ASTContext::getUnresolvedUsingType(
51255127

51265128
QualType ASTContext::getAttributedType(attr::Kind attrKind,
51275129
QualType modifiedType,
5128-
QualType equivalentType) const {
5130+
QualType equivalentType,
5131+
const Attr *attr) const {
51295132
llvm::FoldingSetNodeID id;
5130-
AttributedType::Profile(id, attrKind, modifiedType, equivalentType);
5133+
AttributedType::Profile(id, attrKind, modifiedType, equivalentType, attr);
51315134

51325135
void *insertPos = nullptr;
51335136
AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos);
51345137
if (type) return QualType(type, 0);
51355138

5139+
assert(!attr || attr->getKind() == attrKind);
5140+
51365141
QualType canon = getCanonicalType(equivalentType);
5137-
type = new (*this, alignof(AttributedType))
5138-
AttributedType(canon, attrKind, modifiedType, equivalentType);
5142+
type = new (*this, alignof(AttributedType))
5143+
AttributedType(canon, attrKind, attr, modifiedType, equivalentType);
51395144

51405145
Types.push_back(type);
51415146
AttributedTypes.InsertNode(type, insertPos);
51425147

51435148
return QualType(type, 0);
51445149
}
51455150

5151+
QualType ASTContext::getAttributedType(const Attr *attr, QualType modifiedType,
5152+
QualType equivalentType) const {
5153+
return getAttributedType(attr->getKind(), modifiedType, equivalentType, attr);
5154+
}
5155+
5156+
QualType ASTContext::getAttributedType(NullabilityKind nullability,
5157+
QualType modifiedType,
5158+
QualType equivalentType) {
5159+
switch (nullability) {
5160+
case NullabilityKind::NonNull:
5161+
return getAttributedType(attr::TypeNonNull, modifiedType, equivalentType);
5162+
5163+
case NullabilityKind::Nullable:
5164+
return getAttributedType(attr::TypeNullable, modifiedType, equivalentType);
5165+
5166+
case NullabilityKind::NullableResult:
5167+
return getAttributedType(attr::TypeNullableResult, modifiedType,
5168+
equivalentType);
5169+
5170+
case NullabilityKind::Unspecified:
5171+
return getAttributedType(attr::TypeNullUnspecified, modifiedType,
5172+
equivalentType);
5173+
}
5174+
5175+
llvm_unreachable("Unknown nullability kind");
5176+
}
5177+
51465178
QualType ASTContext::getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
51475179
QualType Wrapped) {
51485180
llvm::FoldingSetNodeID ID;
@@ -7474,8 +7506,8 @@ QualType ASTContext::getArrayDecayedType(QualType Ty) const {
74747506

74757507
// int x[_Nullable] -> int * _Nullable
74767508
if (auto Nullability = Ty->getNullability()) {
7477-
Result = const_cast<ASTContext *>(this)->getAttributedType(
7478-
AttributedType::getNullabilityAttrKind(*Nullability), Result, Result);
7509+
Result = const_cast<ASTContext *>(this)->getAttributedType(*Nullability,
7510+
Result, Result);
74797511
}
74807512
return Result;
74817513
}
@@ -13693,7 +13725,8 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
1369313725
return QualType();
1369413726
// FIXME: It's inefficient to have to unify the modified types.
1369513727
return Ctx.getAttributedType(Kind, Ctx.getCommonSugaredType(MX, MY),
13696-
Ctx.getQualifiedType(Underlying));
13728+
Ctx.getQualifiedType(Underlying),
13729+
AX->getAttr());
1369713730
}
1369813731
case Type::BTFTagAttributed: {
1369913732
const auto *BX = cast<BTFTagAttributedType>(X);

clang/lib/AST/ASTDiagnostic.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT,
8585
QualType SugarRT = FT->getReturnType();
8686
QualType RT = desugarForDiagnostic(Context, SugarRT, DesugarReturn);
8787
if (auto nullability = AttributedType::stripOuterNullability(SugarRT)) {
88-
RT = Context.getAttributedType(
89-
AttributedType::getNullabilityAttrKind(*nullability), RT, RT);
88+
RT = Context.getAttributedType(*nullability, RT, RT);
9089
}
9190

9291
bool DesugarArgument = false;
@@ -97,8 +96,7 @@ QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT,
9796
QualType PT = desugarForDiagnostic(Context, SugarPT, DesugarArgument);
9897
if (auto nullability =
9998
AttributedType::stripOuterNullability(SugarPT)) {
100-
PT = Context.getAttributedType(
101-
AttributedType::getNullabilityAttrKind(*nullability), PT, PT);
99+
PT = Context.getAttributedType(*nullability, PT, PT);
102100
}
103101
Args.push_back(PT);
104102
}

clang/lib/AST/ASTImporter.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,8 +1580,9 @@ ExpectedType ASTNodeImporter::VisitAttributedType(const AttributedType *T) {
15801580
if (!ToEquivalentTypeOrErr)
15811581
return ToEquivalentTypeOrErr.takeError();
15821582

1583-
return Importer.getToContext().getAttributedType(T->getAttrKind(),
1584-
*ToModifiedTypeOrErr, *ToEquivalentTypeOrErr);
1583+
return Importer.getToContext().getAttributedType(
1584+
T->getAttrKind(), *ToModifiedTypeOrErr, *ToEquivalentTypeOrErr,
1585+
T->getAttr());
15851586
}
15861587

15871588
ExpectedType

clang/lib/AST/Type.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,8 +1241,8 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
12411241
== T->getEquivalentType().getAsOpaquePtr())
12421242
return QualType(T, 0);
12431243

1244-
return Ctx.getAttributedType(T->getAttrKind(), modifiedType,
1245-
equivalentType);
1244+
return Ctx.getAttributedType(T->getAttrKind(), modifiedType, equivalentType,
1245+
T->getAttr());
12461246
}
12471247

12481248
QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
@@ -1545,7 +1545,8 @@ struct SubstObjCTypeArgsVisitor
15451545

15461546
// Rebuild the attributed type.
15471547
return Ctx.getAttributedType(newAttrType->getAttrKind(),
1548-
newAttrType->getModifiedType(), newEquivType);
1548+
newAttrType->getModifiedType(), newEquivType,
1549+
newAttrType->getAttr());
15491550
}
15501551
};
15511552

@@ -4104,6 +4105,19 @@ bool RecordType::hasConstFields() const {
41044105
return false;
41054106
}
41064107

4108+
AttributedType::AttributedType(QualType canon, const Attr *attr,
4109+
QualType modified, QualType equivalent)
4110+
: AttributedType(canon, attr->getKind(), attr, modified, equivalent) {}
4111+
4112+
AttributedType::AttributedType(QualType canon, attr::Kind attrKind,
4113+
const Attr *attr, QualType modified,
4114+
QualType equivalent)
4115+
: Type(Attributed, canon, equivalent->getDependence()), Attribute(attr),
4116+
ModifiedType(modified), EquivalentType(equivalent) {
4117+
AttributedTypeBits.AttrKind = attrKind;
4118+
assert(!attr || attr->getKind() == attrKind);
4119+
}
4120+
41074121
bool AttributedType::isQualifier() const {
41084122
// FIXME: Generate this with TableGen.
41094123
switch (getAttrKind()) {

clang/lib/AST/TypePrinter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1932,6 +1932,14 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
19321932
return;
19331933
}
19341934

1935+
if (T->getAttrKind() == attr::SwiftAttr) {
1936+
if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(T->getAttr())) {
1937+
OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
1938+
<< "\")))";
1939+
}
1940+
return;
1941+
}
1942+
19351943
OS << " __attribute__((";
19361944
switch (T->getAttrKind()) {
19371945
#define TYPE_ATTR(NAME)
@@ -1990,6 +1998,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
19901998
case attr::NonAllocating:
19911999
case attr::Blocking:
19922000
case attr::Allocating:
2001+
case attr::SwiftAttr:
19932002
llvm_unreachable("This attribute should have been handled already");
19942003

19952004
case attr::NSReturnsRetained:

clang/lib/Sema/SemaDecl.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3329,9 +3329,7 @@ static void mergeParamDeclTypes(ParmVarDecl *NewParam,
33293329
}
33303330
} else {
33313331
QualType NewT = NewParam->getType();
3332-
NewT = S.Context.getAttributedType(
3333-
AttributedType::getNullabilityAttrKind(*Oldnullability),
3334-
NewT, NewT);
3332+
NewT = S.Context.getAttributedType(*Oldnullability, NewT, NewT);
33353333
NewParam->setType(NewT);
33363334
}
33373335
}

clang/lib/Sema/SemaDeclObjC.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4577,9 +4577,7 @@ static QualType mergeTypeNullabilityForRedecl(Sema &S, SourceLocation loc,
45774577
return type;
45784578

45794579
// Otherwise, provide the result with the same nullability.
4580-
return S.Context.getAttributedType(
4581-
AttributedType::getNullabilityAttrKind(*prevNullability),
4582-
type, type);
4580+
return S.Context.getAttributedType(*prevNullability, type, type);
45834581
}
45844582

45854583
/// Merge information from the declaration of a method in the \@interface

clang/lib/Sema/SemaExpr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8738,8 +8738,7 @@ static QualType computeConditionalNullability(QualType ResTy, bool IsBin,
87388738
ResTy = ResTy.getSingleStepDesugaredType(Ctx);
87398739

87408740
// Create a new AttributedType with the new nullability kind.
8741-
auto NewAttr = AttributedType::getNullabilityAttrKind(MergedKind);
8742-
return Ctx.getAttributedType(NewAttr, ResTy, ResTy);
8741+
return Ctx.getAttributedType(MergedKind, ResTy, ResTy);
87438742
}
87448743

87458744
ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,

0 commit comments

Comments
 (0)