Skip to content

Commit 71521cf

Browse files
authored
Merge pull request #7918 from xedin/attributedtype-with-optional-attr
[clang/AST] Make it possible to use SwiftAttr in type context
2 parents e90b6fb + d176cbf commit 71521cf

22 files changed

+216
-77
lines changed

clang/include/clang/AST/ASTContext.h

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

16171617
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType,
1618+
QualType equivalentType,
1619+
const Attr *attr = nullptr) const;
1620+
1621+
QualType getAttributedType(const Attr *attr, QualType modifiedType,
16181622
QualType equivalentType) const;
16191623

1624+
QualType getAttributedType(NullabilityKind nullability, QualType modifiedType,
1625+
QualType equivalentType);
1626+
16201627
QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
16211628
QualType Wrapped);
16221629

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<"ArrayType::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: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class ConceptDecl;
6363
class TagDecl;
6464
class TemplateParameterList;
6565
class Type;
66+
class Attr;
6667

6768
enum {
6869
TypeAlignmentInBits = 4,
@@ -5073,13 +5074,24 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
50735074
private:
50745075
friend class ASTContext; // ASTContext creates these
50755076

5077+
const Attr *Attribute;
5078+
50765079
QualType ModifiedType;
50775080
QualType EquivalentType;
50785081

50795082
AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
50805083
QualType equivalent)
5084+
: AttributedType(canon, attrKind, nullptr, modified, equivalent) {}
5085+
5086+
AttributedType(QualType canon, const Attr *attr, QualType modified,
5087+
QualType equivalent);
5088+
5089+
private:
5090+
AttributedType(QualType canon, attr::Kind attrKind, const Attr *attr,
5091+
QualType modified, QualType equivalent)
50815092
: Type(Attributed, canon, equivalent->getDependence()),
5082-
ModifiedType(modified), EquivalentType(equivalent) {
5093+
Attribute(attr), ModifiedType(modified),
5094+
EquivalentType(equivalent) {
50835095
AttributedTypeBits.AttrKind = attrKind;
50845096
}
50855097

@@ -5088,6 +5100,8 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
50885100
return static_cast<Kind>(AttributedTypeBits.AttrKind);
50895101
}
50905102

5103+
const Attr *getAttr() const { return Attribute; }
5104+
50915105
QualType getModifiedType() const { return ModifiedType; }
50925106
QualType getEquivalentType() const { return EquivalentType; }
50935107

@@ -5119,25 +5133,6 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
51195133

51205134
std::optional<NullabilityKind> getImmediateNullability() const;
51215135

5122-
/// Retrieve the attribute kind corresponding to the given
5123-
/// nullability kind.
5124-
static Kind getNullabilityAttrKind(NullabilityKind kind) {
5125-
switch (kind) {
5126-
case NullabilityKind::NonNull:
5127-
return attr::TypeNonNull;
5128-
5129-
case NullabilityKind::Nullable:
5130-
return attr::TypeNullable;
5131-
5132-
case NullabilityKind::NullableResult:
5133-
return attr::TypeNullableResult;
5134-
5135-
case NullabilityKind::Unspecified:
5136-
return attr::TypeNullUnspecified;
5137-
}
5138-
llvm_unreachable("Unknown nullability kind.");
5139-
}
5140-
51415136
/// Strip off the top-level nullability annotation on the given
51425137
/// type, if it's there.
51435138
///

clang/include/clang/AST/TypeProperties.td

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -614,12 +614,16 @@ let Class = AttributedType in {
614614
def : Property<"equivalentType", QualType> {
615615
let Read = [{ node->getEquivalentType() }];
616616
}
617-
def : Property<"attribute", AttrKind> {
617+
def : Property<"attrKind", AttrKind> {
618618
let Read = [{ node->getAttrKind() }];
619619
}
620+
def : Property<"attribute", Attr> {
621+
let Read = [{ node->getAttr() }];
622+
}
620623

621624
def : Creator<[{
622-
return ctx.getAttributedType(attribute, modifiedType, equivalentType);
625+
return ctx.getAttributedType(attrKind, modifiedType,
626+
equivalentType, attribute);
623627
}]>;
624628
}
625629

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2522,7 +2522,7 @@ def SwiftAsyncName : InheritableAttr {
25222522
let Documentation = [SwiftAsyncNameDocs];
25232523
}
25242524

2525-
def SwiftAttr : InheritableAttr {
2525+
def SwiftAttr : DeclOrTypeAttr {
25262526
let Spellings = [GNU<"swift_attr">];
25272527
let Args = [StringArgument<"Attribute">];
25282528
let Documentation = [SwiftAttrDocs];

clang/include/clang/Basic/AttrDocs.td

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

clang/include/clang/Serialization/ASTRecordWriter.h

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

129+
void writeAttr(const Attr *A) { AddAttr(A); }
130+
129131
/// Write an BTFTypeTagAttr object.
130132
void writeBTFTypeTagAttr(const BTFTypeTagAttr *A) { AddAttr(A); }
131133

clang/lib/AST/ASTContext.cpp

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3147,11 +3147,13 @@ QualType ASTContext::getFunctionTypeWithExceptionSpec(
31473147
MQT->getMacroIdentifier());
31483148

31493149
// Might have a calling-convention attribute.
3150-
if (const auto *AT = dyn_cast<AttributedType>(Orig))
3150+
if (const auto *AT = dyn_cast<AttributedType>(Orig)) {
31513151
return getAttributedType(
31523152
AT->getAttrKind(),
31533153
getFunctionTypeWithExceptionSpec(AT->getModifiedType(), ESI),
3154-
getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI));
3154+
getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI),
3155+
AT->getAttr());
3156+
}
31553157

31563158
// Anything else must be a function type. Rebuild it with the new exception
31573159
// specification.
@@ -4730,24 +4732,54 @@ QualType ASTContext::getUnresolvedUsingType(
47304732

47314733
QualType ASTContext::getAttributedType(attr::Kind attrKind,
47324734
QualType modifiedType,
4733-
QualType equivalentType) const {
4735+
QualType equivalentType,
4736+
const Attr *attr) const {
47344737
llvm::FoldingSetNodeID id;
47354738
AttributedType::Profile(id, attrKind, modifiedType, equivalentType);
47364739

47374740
void *insertPos = nullptr;
47384741
AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos);
47394742
if (type) return QualType(type, 0);
47404743

4744+
assert(!attr || attr->getKind() == attrKind);
4745+
47414746
QualType canon = getCanonicalType(equivalentType);
47424747
type = new (*this, TypeAlignment)
4743-
AttributedType(canon, attrKind, modifiedType, equivalentType);
4748+
AttributedType(canon, attrKind, attr, modifiedType, equivalentType);
47444749

47454750
Types.push_back(type);
47464751
AttributedTypes.InsertNode(type, insertPos);
47474752

47484753
return QualType(type, 0);
47494754
}
47504755

4756+
QualType ASTContext::getAttributedType(const Attr *attr, QualType modifiedType,
4757+
QualType equivalentType) const {
4758+
return getAttributedType(attr->getKind(), modifiedType, equivalentType, attr);
4759+
}
4760+
4761+
QualType ASTContext::getAttributedType(NullabilityKind nullability,
4762+
QualType modifiedType,
4763+
QualType equivalentType) {
4764+
switch (nullability) {
4765+
case NullabilityKind::NonNull:
4766+
return getAttributedType(attr::TypeNonNull, modifiedType, equivalentType);
4767+
4768+
case NullabilityKind::Nullable:
4769+
return getAttributedType(attr::TypeNullable, modifiedType, equivalentType);
4770+
4771+
case NullabilityKind::NullableResult:
4772+
return getAttributedType(attr::TypeNullableResult, modifiedType,
4773+
equivalentType);
4774+
4775+
case NullabilityKind::Unspecified:
4776+
return getAttributedType(attr::TypeNullUnspecified, modifiedType,
4777+
equivalentType);
4778+
}
4779+
4780+
llvm_unreachable("Unknown nullability kind");
4781+
}
4782+
47514783
QualType ASTContext::getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
47524784
QualType Wrapped) {
47534785
llvm::FoldingSetNodeID ID;
@@ -6916,8 +6948,8 @@ QualType ASTContext::getArrayDecayedType(QualType Ty) const {
69166948

69176949
// int x[_Nullable] -> int * _Nullable
69186950
if (auto Nullability = Ty->getNullability()) {
6919-
Result = const_cast<ASTContext *>(this)->getAttributedType(
6920-
AttributedType::getNullabilityAttrKind(*Nullability), Result, Result);
6951+
Result = const_cast<ASTContext *>(this)->getAttributedType(*Nullability,
6952+
Result, Result);
69216953
}
69226954
return Result;
69236955
}
@@ -12996,7 +13028,8 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
1299613028
return QualType();
1299713029
// FIXME: It's inefficient to have to unify the modified types.
1299813030
return Ctx.getAttributedType(Kind, Ctx.getCommonSugaredType(MX, MY),
12999-
Ctx.getQualifiedType(Underlying));
13031+
Ctx.getQualifiedType(Underlying),
13032+
AX->getAttr());
1300013033
}
1300113034
case Type::BTFTagAttributed: {
1300213035
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
@@ -1505,8 +1505,9 @@ ExpectedType ASTNodeImporter::VisitAttributedType(const AttributedType *T) {
15051505
if (!ToEquivalentTypeOrErr)
15061506
return ToEquivalentTypeOrErr.takeError();
15071507

1508-
return Importer.getToContext().getAttributedType(T->getAttrKind(),
1509-
*ToModifiedTypeOrErr, *ToEquivalentTypeOrErr);
1508+
return Importer.getToContext().getAttributedType(
1509+
T->getAttrKind(), *ToModifiedTypeOrErr, *ToEquivalentTypeOrErr,
1510+
T->getAttr());
15101511
}
15111512

15121513
ExpectedType ASTNodeImporter::VisitTemplateTypeParmType(

clang/lib/AST/Type.cpp

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

1162-
return Ctx.getAttributedType(T->getAttrKind(), modifiedType,
1163-
equivalentType);
1162+
return Ctx.getAttributedType(T->getAttrKind(), modifiedType, equivalentType,
1163+
T->getAttr());
11641164
}
11651165

11661166
QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
@@ -1458,7 +1458,8 @@ struct SubstObjCTypeArgsVisitor
14581458

14591459
// Rebuild the attributed type.
14601460
return Ctx.getAttributedType(newAttrType->getAttrKind(),
1461-
newAttrType->getModifiedType(), newEquivType);
1461+
newAttrType->getModifiedType(), newEquivType,
1462+
newAttrType->getAttr());
14621463
}
14631464
};
14641465

@@ -3755,6 +3756,10 @@ bool RecordType::hasConstFields() const {
37553756
return false;
37563757
}
37573758

3759+
AttributedType::AttributedType(QualType canon, const Attr *attr,
3760+
QualType modified, QualType equivalent)
3761+
: AttributedType(canon, attr->getKind(), attr, modified, equivalent) {}
3762+
37583763
bool AttributedType::isQualifier() const {
37593764
// FIXME: Generate this with TableGen.
37603765
switch (getAttrKind()) {

clang/lib/AST/TypePrinter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,6 +1784,14 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
17841784
return;
17851785
}
17861786

1787+
if (T->getAttrKind() == attr::SwiftAttr) {
1788+
if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(T->getAttr())) {
1789+
OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
1790+
<< "\")))";
1791+
}
1792+
return;
1793+
}
1794+
17871795
OS << " __attribute__((";
17881796
switch (T->getAttrKind()) {
17891797
#define TYPE_ATTR(NAME)
@@ -1826,6 +1834,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
18261834
case attr::AnnotateType:
18271835
case attr::WebAssemblyFuncref:
18281836
case attr::ArmStreaming:
1837+
case attr::SwiftAttr:
18291838
llvm_unreachable("This attribute should have been handled already");
18301839

18311840
case attr::NSReturnsRetained:

clang/lib/Sema/SemaDecl.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3430,9 +3430,7 @@ static void mergeParamDeclTypes(ParmVarDecl *NewParam,
34303430
}
34313431
} else {
34323432
QualType NewT = NewParam->getType();
3433-
NewT = S.Context.getAttributedType(
3434-
AttributedType::getNullabilityAttrKind(*Oldnullability),
3435-
NewT, NewT);
3433+
NewT = S.Context.getAttributedType(*Oldnullability, NewT, NewT);
34363434
NewParam->setType(NewT);
34373435
}
34383436
}

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6353,11 +6353,16 @@ static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
63536353
}
63546354

63556355
static void handleSwiftAttrAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6356+
if (AL.isInvalid() || AL.isUsedAsTypeAttr())
6357+
return;
6358+
63566359
// Make sure that there is a string literal as the annotation's single
63576360
// argument.
63586361
StringRef Str;
6359-
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
6362+
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str)) {
6363+
AL.setInvalid();
63606364
return;
6365+
}
63616366

63626367
D->addAttr(::new (S.Context) SwiftAttrAttr(S.Context, AL, Str));
63636368
}

clang/lib/Sema/SemaDeclObjC.cpp

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

46254625
// Otherwise, provide the result with the same nullability.
4626-
return S.Context.getAttributedType(
4627-
AttributedType::getNullabilityAttrKind(*prevNullability),
4628-
type, type);
4626+
return S.Context.getAttributedType(*prevNullability, type, type);
46294627
}
46304628

46314629
/// 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
@@ -9593,8 +9593,7 @@ static QualType computeConditionalNullability(QualType ResTy, bool IsBin,
95939593
ResTy = ResTy.getSingleStepDesugaredType(Ctx);
95949594

95959595
// Create a new AttributedType with the new nullability kind.
9596-
auto NewAttr = AttributedType::getNullabilityAttrKind(MergedKind);
9597-
return Ctx.getAttributedType(NewAttr, ResTy, ResTy);
9596+
return Ctx.getAttributedType(MergedKind, ResTy, ResTy);
95989597
}
95999598

96009599
/// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null

0 commit comments

Comments
 (0)