Skip to content

Commit 0235ba7

Browse files
authored
Merge pull request #23685 from DougGregor/custom-attributes-parse
2 parents 7cf4c6b + a848d12 commit 0235ba7

19 files changed

+535
-120
lines changed

include/swift/AST/ASTTypeIDZone.def

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===--- ASTTypeIDZone.def - Define the AST TypeID Zone ---------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This definition file describes the types in the "AST" TypeID zone,
14+
// for use with the TypeID template.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
SWIFT_TYPEID_NAMED(NominalTypeDecl *, NominalTypeDecl)
18+
SWIFT_TYPEID_NAMED(VarDecl *, VarDecl)
19+
SWIFT_TYPEID(PropertyBehaviorTypeInfo)

include/swift/AST/ASTTypeIDs.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===--- ASTTypeIDs.h - AST Type Ids ----------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines TypeID support for AST types.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_AST_ASTTYPEIDS_H
18+
#define SWIFT_AST_ASTTYPEIDS_H
19+
20+
#include "swift/Basic/TypeID.h"
21+
namespace swift {
22+
23+
class NominalTypeDecl;
24+
struct PropertyBehaviorTypeInfo;
25+
class VarDecl;
26+
27+
#define SWIFT_AST_TYPEID_ZONE 1
28+
29+
// Define the AST type zone (zone 1)
30+
#define SWIFT_TYPEID_ZONE SWIFT_AST_TYPEID_ZONE
31+
#define SWIFT_TYPEID_HEADER "swift/AST/ASTTypeIDZone.def"
32+
#include "swift/Basic/DefineTypeIDZone.h"
33+
34+
} // end namespace swift
35+
36+
#endif /* SWIFT_AST_ASTTYPEIDS_H */

include/swift/AST/Attr.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,9 @@ SIMPLE_DECL_ATTR(_alwaysEmitIntoClient, AlwaysEmitIntoClient,
393393
SIMPLE_DECL_ATTR(_implementationOnly, ImplementationOnly,
394394
OnImport | UserInaccessible,
395395
84)
396+
DECL_ATTR(_custom, Custom,
397+
OnAnyDecl | UserInaccessible,
398+
85)
396399

397400
#undef TYPE_ATTR
398401
#undef DECL_ATTR_ALIAS

include/swift/AST/Attr.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "swift/AST/Ownership.h"
3333
#include "swift/AST/PlatformKind.h"
3434
#include "swift/AST/Requirement.h"
35+
#include "swift/AST/TrailingCallArguments.h"
3536
#include "swift/AST/TypeLoc.h"
3637
#include "llvm/ADT/SmallVector.h"
3738
#include "llvm/ADT/StringRef.h"
@@ -49,6 +50,7 @@ class FuncDecl;
4950
class ClassDecl;
5051
class GenericFunctionType;
5152
class LazyConformanceLoader;
53+
class PatternBindingInitializer;
5254
class TrailingWhereClause;
5355

5456
/// TypeAttributes - These are attributes that may be applied to types.
@@ -1408,6 +1410,54 @@ class ClangImporterSynthesizedTypeAttr : public DeclAttribute {
14081410
}
14091411
};
14101412

1413+
/// Defines a custom attribute.
1414+
class CustomAttr final : public DeclAttribute,
1415+
public TrailingCallArguments<CustomAttr> {
1416+
TypeLoc type;
1417+
Expr *arg;
1418+
PatternBindingInitializer *initContext;
1419+
1420+
unsigned hasArgLabelLocs : 1;
1421+
unsigned numArgLabels : 16;
1422+
1423+
CustomAttr(SourceLoc atLoc, SourceRange range, TypeLoc type,
1424+
PatternBindingInitializer *initContext, Expr *arg,
1425+
ArrayRef<Identifier> argLabels, ArrayRef<SourceLoc> argLabelLocs,
1426+
bool implicit);
1427+
1428+
public:
1429+
static CustomAttr *create(ASTContext &ctx, SourceLoc atLoc, TypeLoc type,
1430+
bool implicit = false) {
1431+
return create(ctx, atLoc, type, false, nullptr, SourceLoc(), { }, { }, { },
1432+
SourceLoc(), implicit);
1433+
}
1434+
1435+
static CustomAttr *create(ASTContext &ctx, SourceLoc atLoc, TypeLoc type,
1436+
bool hasInitializer,
1437+
PatternBindingInitializer *initContext,
1438+
SourceLoc lParenLoc,
1439+
ArrayRef<Expr *> args,
1440+
ArrayRef<Identifier> argLabels,
1441+
ArrayRef<SourceLoc> argLabelLocs,
1442+
SourceLoc rParenLoc,
1443+
bool implicit = false);
1444+
1445+
unsigned getNumArguments() const { return numArgLabels; }
1446+
bool hasArgumentLabelLocs() const { return hasArgLabelLocs; }
1447+
1448+
TypeLoc &getTypeLoc() { return type; }
1449+
const TypeLoc &getTypeLoc() const { return type; }
1450+
1451+
Expr *getArg() const { return arg; }
1452+
void setArg(Expr *newArg) { arg = newArg; }
1453+
1454+
PatternBindingInitializer *getInitContext() const { return initContext; }
1455+
1456+
static bool classof(const DeclAttribute *DA) {
1457+
return DA->getKind() == DAK_Custom;
1458+
}
1459+
};
1460+
14111461
/// Attributes that may be applied to declarations.
14121462
class DeclAttributes {
14131463
/// Linked list of declaration attributes.
@@ -1584,6 +1634,8 @@ class DeclAttributes {
15841634
SourceLoc getStartLoc(bool forModifiers = false) const;
15851635
};
15861636

1637+
void simple_display(llvm::raw_ostream &out, const DeclAttribute *attr);
1638+
15871639
} // end namespace swift
15881640

15891641
#endif

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,9 @@ ERROR(attribute_requires_operator_identifier,none,
11041104
ERROR(attribute_requires_single_argument,none,
11051105
"'%0' requires a function with one argument", (StringRef))
11061106

1107+
ERROR(nominal_type_not_attribute,none,
1108+
"%0 %1 cannot be used as an attribute", (DescriptiveDeclKind, DeclName))
1109+
11071110
ERROR(mutating_invalid_global_scope,none, "%0 is only valid on methods",
11081111
(SelfAccessKind))
11091112
ERROR(mutating_invalid_classes,none, "%0 isn't valid on methods in "

include/swift/AST/Expr.h

Lines changed: 22 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/DeclNameLoc.h"
2323
#include "swift/AST/FunctionRefKind.h"
2424
#include "swift/AST/ProtocolConformanceRef.h"
25+
#include "swift/AST/TrailingCallArguments.h"
2526
#include "swift/AST/TypeAlignments.h"
2627
#include "swift/AST/TypeLoc.h"
2728
#include "swift/AST/TypeRepr.h"
@@ -570,105 +571,6 @@ class alignas(8) Expr {
570571
}
571572
};
572573

573-
/// Helper class to capture trailing call argument labels and related
574-
/// information, for expression nodes that involve argument labels, trailing
575-
/// closures, etc.
576-
template<typename Derived>
577-
class TrailingCallArguments
578-
: private llvm::TrailingObjects<Derived, Identifier, SourceLoc> {
579-
// We need to friend TrailingObjects twice here to work around an MSVC bug.
580-
// If we have two functions of the same name with the parameter
581-
// typename TrailingObjectsIdentifier::template OverloadToken<T> where T is
582-
// different for each function, then MSVC reports a "member function already
583-
// defined or declared" error, which is incorrect.
584-
using TrailingObjectsIdentifier = llvm::TrailingObjects<Derived, Identifier>;
585-
friend TrailingObjectsIdentifier;
586-
587-
using TrailingObjects = llvm::TrailingObjects<Derived, Identifier, SourceLoc>;
588-
friend TrailingObjects;
589-
590-
Derived &asDerived() {
591-
return *static_cast<Derived *>(this);
592-
}
593-
594-
const Derived &asDerived() const {
595-
return *static_cast<const Derived *>(this);
596-
}
597-
598-
size_t numTrailingObjects(
599-
typename TrailingObjectsIdentifier::template OverloadToken<Identifier>)
600-
const {
601-
return asDerived().getNumArguments();
602-
}
603-
604-
size_t numTrailingObjects(
605-
typename TrailingObjectsIdentifier::template OverloadToken<SourceLoc>)
606-
const {
607-
return asDerived().hasArgumentLabelLocs() ? asDerived().getNumArguments()
608-
: 0;
609-
}
610-
611-
/// Retrieve the buffer containing the argument labels.
612-
MutableArrayRef<Identifier> getArgumentLabelsBuffer() {
613-
return { this->template getTrailingObjects<Identifier>(),
614-
asDerived().getNumArguments() };
615-
}
616-
617-
/// Retrieve the buffer containing the argument label locations.
618-
MutableArrayRef<SourceLoc> getArgumentLabelLocsBuffer() {
619-
if (!asDerived().hasArgumentLabelLocs())
620-
return { };
621-
622-
return { this->template getTrailingObjects<SourceLoc>(),
623-
asDerived().getNumArguments() };
624-
}
625-
626-
protected:
627-
/// Determine the total size to allocate.
628-
static size_t totalSizeToAlloc(ArrayRef<Identifier> argLabels,
629-
ArrayRef<SourceLoc> argLabelLocs,
630-
bool hasTrailingClosure) {
631-
return TrailingObjects::template totalSizeToAlloc<Identifier, SourceLoc>(
632-
argLabels.size(), argLabelLocs.size());
633-
}
634-
635-
/// Initialize the actual call arguments.
636-
void initializeCallArguments(ArrayRef<Identifier> argLabels,
637-
ArrayRef<SourceLoc> argLabelLocs,
638-
bool hasTrailingClosure) {
639-
if (!argLabels.empty()) {
640-
std::uninitialized_copy(argLabels.begin(), argLabels.end(),
641-
this->template getTrailingObjects<Identifier>());
642-
}
643-
644-
if (!argLabelLocs.empty())
645-
std::uninitialized_copy(argLabelLocs.begin(), argLabelLocs.end(),
646-
this->template getTrailingObjects<SourceLoc>());
647-
}
648-
649-
public:
650-
/// Retrieve the argument labels provided at the call site.
651-
ArrayRef<Identifier> getArgumentLabels() const {
652-
return { this->template getTrailingObjects<Identifier>(),
653-
asDerived().getNumArguments() };
654-
}
655-
656-
/// Retrieve the buffer containing the argument label locations.
657-
ArrayRef<SourceLoc> getArgumentLabelLocs() const {
658-
if (!asDerived().hasArgumentLabelLocs())
659-
return { };
660-
661-
return { this->template getTrailingObjects<SourceLoc>(),
662-
asDerived().getNumArguments() };
663-
}
664-
665-
/// Retrieve the location of the ith argument label.
666-
SourceLoc getArgumentLabelLoc(unsigned i) const {
667-
auto locs = getArgumentLabelLocs();
668-
return i < locs.size() ? locs[i] : SourceLoc();
669-
}
670-
};
671-
672574
/// ErrorExpr - Represents a semantically erroneous subexpression in the AST,
673575
/// typically this will have an ErrorType.
674576
class ErrorExpr : public Expr {
@@ -5448,7 +5350,27 @@ inline const SourceLoc *CollectionExpr::getTrailingSourceLocs() const {
54485350
}
54495351

54505352
#undef SWIFT_FORWARD_SOURCE_LOCS_TO
5451-
5353+
5354+
/// Pack the argument information into a single argument, to match the
5355+
/// representation expected by the AST.
5356+
///
5357+
/// \param argLabels The argument labels, which might be updated by this
5358+
/// function.
5359+
///
5360+
/// \param argLabelLocs The argument label locations, which might be updated by
5361+
/// this function.
5362+
Expr *packSingleArgument(ASTContext &ctx, SourceLoc lParenLoc,
5363+
ArrayRef<Expr *> args,
5364+
ArrayRef<Identifier> &argLabels,
5365+
ArrayRef<SourceLoc> &argLabelLocs,
5366+
SourceLoc rParenLoc,
5367+
Expr *trailingClosure, bool implicit,
5368+
SmallVectorImpl<Identifier> &argLabelsScratch,
5369+
SmallVectorImpl<SourceLoc> &argLabelLocsScratch,
5370+
llvm::function_ref<Type(const Expr *)> getType =
5371+
[](const Expr *E) -> Type {
5372+
return E->getType();
5373+
});
54525374
} // end namespace swift
54535375

54545376
#endif

include/swift/AST/NameLookupRequests.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define SWIFT_NAME_LOOKUP_REQUESTS_H
1818

1919
#include "swift/AST/SimpleRequest.h"
20+
#include "swift/AST/ASTTypeIDs.h"
2021
#include "swift/Basic/Statistic.h"
2122
#include "llvm/ADT/TinyPtrVector.h"
2223

@@ -238,6 +239,33 @@ class TypeDeclsFromWhereClauseRequest :
238239
void noteCycleStep(DiagnosticEngine &diags) const;
239240
};
240241

242+
/// Request the nominal type declaration to which the given custom attribute
243+
/// refers.
244+
class CustomAttrNominalRequest :
245+
public SimpleRequest<CustomAttrNominalRequest,
246+
CacheKind::Cached,
247+
NominalTypeDecl *,
248+
CustomAttr *,
249+
DeclContext *> {
250+
public:
251+
using SimpleRequest::SimpleRequest;
252+
253+
private:
254+
friend SimpleRequest;
255+
256+
// Evaluation.
257+
llvm::Expected<NominalTypeDecl *>
258+
evaluate(Evaluator &evaluator, CustomAttr *attr, DeclContext *dc) const;
259+
260+
public:
261+
// Caching
262+
bool isCached() const { return true; }
263+
264+
// Cycle handling
265+
void diagnoseCycle(DiagnosticEngine &diags) const;
266+
void noteCycleStep(DiagnosticEngine &diags) const;
267+
};
268+
241269
/// The zone number for name-lookup requests.
242270
#define SWIFT_NAME_LOOKUP_REQUESTS_TYPEID_ZONE 9
243271

include/swift/AST/NameLookupTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ SWIFT_TYPEID(SuperclassDeclRequest)
2020
SWIFT_TYPEID(ExtendedNominalRequest)
2121
SWIFT_TYPEID(SelfBoundsFromWhereClauseRequest)
2222
SWIFT_TYPEID(TypeDeclsFromWhereClauseRequest)
23+
SWIFT_TYPEID(CustomAttrNominalRequest)

0 commit comments

Comments
 (0)