Skip to content

Parse unknown attributes as "custom" attributes. #23685

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions include/swift/AST/ASTTypeIDZone.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===--- ASTTypeIDZone.def - Define the AST TypeID Zone ---------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This definition file describes the types in the "AST" TypeID zone,
// for use with the TypeID template.
//
//===----------------------------------------------------------------------===//
SWIFT_TYPEID_NAMED(NominalTypeDecl *, NominalTypeDecl)
SWIFT_TYPEID_NAMED(VarDecl *, VarDecl)
SWIFT_TYPEID(PropertyBehaviorTypeInfo)
36 changes: 36 additions & 0 deletions include/swift/AST/ASTTypeIDs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//===--- ASTTypeIDs.h - AST Type Ids ----------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines TypeID support for AST types.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_AST_ASTTYPEIDS_H
#define SWIFT_AST_ASTTYPEIDS_H

#include "swift/Basic/TypeID.h"
namespace swift {

class NominalTypeDecl;
struct PropertyBehaviorTypeInfo;
class VarDecl;

#define SWIFT_AST_TYPEID_ZONE 1

// Define the AST type zone (zone 1)
#define SWIFT_TYPEID_ZONE SWIFT_AST_TYPEID_ZONE
#define SWIFT_TYPEID_HEADER "swift/AST/ASTTypeIDZone.def"
#include "swift/Basic/DefineTypeIDZone.h"

} // end namespace swift

#endif /* SWIFT_AST_ASTTYPEIDS_H */
3 changes: 3 additions & 0 deletions include/swift/AST/Attr.def
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,9 @@ SIMPLE_DECL_ATTR(_alwaysEmitIntoClient, AlwaysEmitIntoClient,
SIMPLE_DECL_ATTR(_implementationOnly, ImplementationOnly,
OnImport | UserInaccessible,
84)
DECL_ATTR(_custom, Custom,
OnAnyDecl | UserInaccessible,
85)

#undef TYPE_ATTR
#undef DECL_ATTR_ALIAS
Expand Down
52 changes: 52 additions & 0 deletions include/swift/AST/Attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "swift/AST/Ownership.h"
#include "swift/AST/PlatformKind.h"
#include "swift/AST/Requirement.h"
#include "swift/AST/TrailingCallArguments.h"
#include "swift/AST/TypeLoc.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
Expand All @@ -49,6 +50,7 @@ class FuncDecl;
class ClassDecl;
class GenericFunctionType;
class LazyConformanceLoader;
class PatternBindingInitializer;
class TrailingWhereClause;

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

/// Defines a custom attribute.
class CustomAttr final : public DeclAttribute,
public TrailingCallArguments<CustomAttr> {
TypeLoc type;
Expr *arg;
PatternBindingInitializer *initContext;

unsigned hasArgLabelLocs : 1;
unsigned numArgLabels : 16;

CustomAttr(SourceLoc atLoc, SourceRange range, TypeLoc type,
PatternBindingInitializer *initContext, Expr *arg,
ArrayRef<Identifier> argLabels, ArrayRef<SourceLoc> argLabelLocs,
bool implicit);

public:
static CustomAttr *create(ASTContext &ctx, SourceLoc atLoc, TypeLoc type,
bool implicit = false) {
return create(ctx, atLoc, type, false, nullptr, SourceLoc(), { }, { }, { },
SourceLoc(), implicit);
}

static CustomAttr *create(ASTContext &ctx, SourceLoc atLoc, TypeLoc type,
bool hasInitializer,
PatternBindingInitializer *initContext,
SourceLoc lParenLoc,
ArrayRef<Expr *> args,
ArrayRef<Identifier> argLabels,
ArrayRef<SourceLoc> argLabelLocs,
SourceLoc rParenLoc,
bool implicit = false);

unsigned getNumArguments() const { return numArgLabels; }
bool hasArgumentLabelLocs() const { return hasArgLabelLocs; }

TypeLoc &getTypeLoc() { return type; }
const TypeLoc &getTypeLoc() const { return type; }

Expr *getArg() const { return arg; }
void setArg(Expr *newArg) { arg = newArg; }

PatternBindingInitializer *getInitContext() const { return initContext; }

static bool classof(const DeclAttribute *DA) {
return DA->getKind() == DAK_Custom;
}
};

/// Attributes that may be applied to declarations.
class DeclAttributes {
/// Linked list of declaration attributes.
Expand Down Expand Up @@ -1584,6 +1634,8 @@ class DeclAttributes {
SourceLoc getStartLoc(bool forModifiers = false) const;
};

void simple_display(llvm::raw_ostream &out, const DeclAttribute *attr);

} // end namespace swift

#endif
3 changes: 3 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1104,6 +1104,9 @@ ERROR(attribute_requires_operator_identifier,none,
ERROR(attribute_requires_single_argument,none,
"'%0' requires a function with one argument", (StringRef))

ERROR(nominal_type_not_attribute,none,
"%0 %1 cannot be used as an attribute", (DescriptiveDeclKind, DeclName))

ERROR(mutating_invalid_global_scope,none, "%0 is only valid on methods",
(SelfAccessKind))
ERROR(mutating_invalid_classes,none, "%0 isn't valid on methods in "
Expand Down
122 changes: 22 additions & 100 deletions include/swift/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "swift/AST/DeclNameLoc.h"
#include "swift/AST/FunctionRefKind.h"
#include "swift/AST/ProtocolConformanceRef.h"
#include "swift/AST/TrailingCallArguments.h"
#include "swift/AST/TypeAlignments.h"
#include "swift/AST/TypeLoc.h"
#include "swift/AST/TypeRepr.h"
Expand Down Expand Up @@ -570,105 +571,6 @@ class alignas(8) Expr {
}
};

/// Helper class to capture trailing call argument labels and related
/// information, for expression nodes that involve argument labels, trailing
/// closures, etc.
template<typename Derived>
class TrailingCallArguments
: private llvm::TrailingObjects<Derived, Identifier, SourceLoc> {
// We need to friend TrailingObjects twice here to work around an MSVC bug.
// If we have two functions of the same name with the parameter
// typename TrailingObjectsIdentifier::template OverloadToken<T> where T is
// different for each function, then MSVC reports a "member function already
// defined or declared" error, which is incorrect.
using TrailingObjectsIdentifier = llvm::TrailingObjects<Derived, Identifier>;
friend TrailingObjectsIdentifier;

using TrailingObjects = llvm::TrailingObjects<Derived, Identifier, SourceLoc>;
friend TrailingObjects;

Derived &asDerived() {
return *static_cast<Derived *>(this);
}

const Derived &asDerived() const {
return *static_cast<const Derived *>(this);
}

size_t numTrailingObjects(
typename TrailingObjectsIdentifier::template OverloadToken<Identifier>)
const {
return asDerived().getNumArguments();
}

size_t numTrailingObjects(
typename TrailingObjectsIdentifier::template OverloadToken<SourceLoc>)
const {
return asDerived().hasArgumentLabelLocs() ? asDerived().getNumArguments()
: 0;
}

/// Retrieve the buffer containing the argument labels.
MutableArrayRef<Identifier> getArgumentLabelsBuffer() {
return { this->template getTrailingObjects<Identifier>(),
asDerived().getNumArguments() };
}

/// Retrieve the buffer containing the argument label locations.
MutableArrayRef<SourceLoc> getArgumentLabelLocsBuffer() {
if (!asDerived().hasArgumentLabelLocs())
return { };

return { this->template getTrailingObjects<SourceLoc>(),
asDerived().getNumArguments() };
}

protected:
/// Determine the total size to allocate.
static size_t totalSizeToAlloc(ArrayRef<Identifier> argLabels,
ArrayRef<SourceLoc> argLabelLocs,
bool hasTrailingClosure) {
return TrailingObjects::template totalSizeToAlloc<Identifier, SourceLoc>(
argLabels.size(), argLabelLocs.size());
}

/// Initialize the actual call arguments.
void initializeCallArguments(ArrayRef<Identifier> argLabels,
ArrayRef<SourceLoc> argLabelLocs,
bool hasTrailingClosure) {
if (!argLabels.empty()) {
std::uninitialized_copy(argLabels.begin(), argLabels.end(),
this->template getTrailingObjects<Identifier>());
}

if (!argLabelLocs.empty())
std::uninitialized_copy(argLabelLocs.begin(), argLabelLocs.end(),
this->template getTrailingObjects<SourceLoc>());
}

public:
/// Retrieve the argument labels provided at the call site.
ArrayRef<Identifier> getArgumentLabels() const {
return { this->template getTrailingObjects<Identifier>(),
asDerived().getNumArguments() };
}

/// Retrieve the buffer containing the argument label locations.
ArrayRef<SourceLoc> getArgumentLabelLocs() const {
if (!asDerived().hasArgumentLabelLocs())
return { };

return { this->template getTrailingObjects<SourceLoc>(),
asDerived().getNumArguments() };
}

/// Retrieve the location of the ith argument label.
SourceLoc getArgumentLabelLoc(unsigned i) const {
auto locs = getArgumentLabelLocs();
return i < locs.size() ? locs[i] : SourceLoc();
}
};

/// ErrorExpr - Represents a semantically erroneous subexpression in the AST,
/// typically this will have an ErrorType.
class ErrorExpr : public Expr {
Expand Down Expand Up @@ -5448,7 +5350,27 @@ inline const SourceLoc *CollectionExpr::getTrailingSourceLocs() const {
}

#undef SWIFT_FORWARD_SOURCE_LOCS_TO


/// Pack the argument information into a single argument, to match the
/// representation expected by the AST.
///
/// \param argLabels The argument labels, which might be updated by this
/// function.
///
/// \param argLabelLocs The argument label locations, which might be updated by
/// this function.
Expr *packSingleArgument(ASTContext &ctx, SourceLoc lParenLoc,
ArrayRef<Expr *> args,
ArrayRef<Identifier> &argLabels,
ArrayRef<SourceLoc> &argLabelLocs,
SourceLoc rParenLoc,
Expr *trailingClosure, bool implicit,
SmallVectorImpl<Identifier> &argLabelsScratch,
SmallVectorImpl<SourceLoc> &argLabelLocsScratch,
llvm::function_ref<Type(const Expr *)> getType =
[](const Expr *E) -> Type {
return E->getType();
});
} // end namespace swift

#endif
28 changes: 28 additions & 0 deletions include/swift/AST/NameLookupRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define SWIFT_NAME_LOOKUP_REQUESTS_H

#include "swift/AST/SimpleRequest.h"
#include "swift/AST/ASTTypeIDs.h"
#include "swift/Basic/Statistic.h"
#include "llvm/ADT/TinyPtrVector.h"

Expand Down Expand Up @@ -238,6 +239,33 @@ class TypeDeclsFromWhereClauseRequest :
void noteCycleStep(DiagnosticEngine &diags) const;
};

/// Request the nominal type declaration to which the given custom attribute
/// refers.
class CustomAttrNominalRequest :
public SimpleRequest<CustomAttrNominalRequest,
CacheKind::Cached,
NominalTypeDecl *,
CustomAttr *,
DeclContext *> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
llvm::Expected<NominalTypeDecl *>
evaluate(Evaluator &evaluator, CustomAttr *attr, DeclContext *dc) const;

public:
// Caching
bool isCached() const { return true; }

// Cycle handling
void diagnoseCycle(DiagnosticEngine &diags) const;
void noteCycleStep(DiagnosticEngine &diags) const;
};

/// The zone number for name-lookup requests.
#define SWIFT_NAME_LOOKUP_REQUESTS_TYPEID_ZONE 9

Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/NameLookupTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ SWIFT_TYPEID(SuperclassDeclRequest)
SWIFT_TYPEID(ExtendedNominalRequest)
SWIFT_TYPEID(SelfBoundsFromWhereClauseRequest)
SWIFT_TYPEID(TypeDeclsFromWhereClauseRequest)
SWIFT_TYPEID(CustomAttrNominalRequest)
Loading