Files
swift-mirror/include/swift/AST/Attr.h
Chris Lattner 69d0afb658 rename [force_inlining] to [transparent].
Swift SVN r7448
2013-08-22 16:05:41 +00:00

214 lines
7.0 KiB
C++

//===--- Attr.h - Swift Language Attribute ASTs -----------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines classes related to declaration attributes.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_ATTR_H
#define SWIFT_ATTR_H
#include "swift/Basic/Optional.h"
#include "swift/Basic/SourceLoc.h"
#include "swift/AST/Ownership.h"
#include "llvm/ADT/StringRef.h"
namespace swift {
/// The associativity of a binary operator.
enum class Associativity {
/// Non-associative operators cannot be written next to other
/// operators with the same precedence. Relational operators are
/// typically non-associative.
None,
/// Left-associative operators associate to the left if written next
/// to other left-associative operators of the same precedence.
Left,
/// Right-associative operators associate to the right if written
/// next to other right-associative operators of the same precedence.
Right
};
class InfixData {
unsigned Precedence : 8;
/// Zero if invalid, or else an Associativity+1.
unsigned InvalidOrAssoc : 8;
public:
InfixData() : Precedence(0), InvalidOrAssoc(0) {}
InfixData(unsigned char prec, Associativity assoc)
: Precedence(prec), InvalidOrAssoc(unsigned(assoc) + 1) {}
bool isValid() const { return InvalidOrAssoc != 0; }
Associativity getAssociativity() const {
assert(isValid());
return Associativity(InvalidOrAssoc - 1);
}
bool isLeftAssociative() const {
return getAssociativity() == Associativity::Left;
}
bool isRightAssociative() const {
return getAssociativity() == Associativity::Right;
}
bool isNonAssociative() const {
return getAssociativity() == Associativity::None;
}
unsigned getPrecedence() const {
assert(isValid());
return Precedence;
}
friend bool operator==(InfixData L, InfixData R) {
return L.Precedence == R.Precedence
&& L.InvalidOrAssoc == R.InvalidOrAssoc;
}
friend bool operator!=(InfixData L, InfixData R) {
return !operator==(L, R);
}
};
/// ABI resilience. Language structures are resilient if the details
/// of their implementation may be changed without requiring
/// associated code to be reprocessed. Different structures are resilient
/// in different ways. For example:
/// - A resilient type does not have a statically fixed size or layout.
/// - A resilient field must be accessed with getters and setters, even if
/// none are defined for it now.
/// - A resilient function may not be inlined.
///
/// In general, resilience is inherited from the lexical context. For
/// example, a field declared in a fragile struct is implicitly fragile.
///
/// Some language structures, like tuples, are never themselves
/// resilient (although they may be defined in terms of resilient
/// types). Additionally, code distributed with the component
/// defining a resilient structure need not actually use resilience
/// boundaries.
enum class Resilience : unsigned char {
/// Inherently fragile language structures are not only resilient,
/// but they have never been exposed as resilient. This permits
/// certain kinds of optimizations that are not otherwise possible
/// because of the need for backward compatibility.
InherentlyFragile,
/// Fragile language structures are non-resilient. They may have
/// been resilient at some point in the past, however.
Fragile,
/// Everything else is resilient. Resilience means different things
/// on different kinds of objects.
Resilient
};
class ResilienceData {
unsigned Valid : 1;
unsigned Kind : 2;
public:
ResilienceData() : Valid(false) {}
ResilienceData(Resilience resil) : Valid(true), Kind(unsigned(resil)) {}
bool isValid() const { return Valid; }
Resilience getResilience() const {
assert(Valid);
return Resilience(Kind);
}
};
enum class AbstractCC : unsigned char;
/// DeclAttributes - These are attributes that may be applied to declarations.
class DeclAttributes {
public:
/// LSquareLoc/RSquareLoc - This is the location of the '[' and ']' in the
/// attribute specifier. If this is an empty attribute specifier, then these
/// will be invalid locs.
SourceLoc LSquareLoc, RSquareLoc;
ResilienceData Resilience;
StringRef AsmName;
bool Byref = false;
bool AutoClosure = false;
bool Thin = false;
bool NoReturn = false;
bool Assignment = false;
bool Conversion = false;
bool Transparent = false;
bool ObjC = false;
bool ObjCBlock = false;
bool ExplicitPrefix = false;
bool ExplicitPostfix = false;
bool ExplicitInfix = false;
bool IBOutlet = false;
bool IBAction = false;
bool ClassProtocol = false;
bool Weak = false;
bool Unowned = false;
bool LocalStorage = false;
bool Exported = false;
Optional<AbstractCC> cc = Nothing;
DeclAttributes() {}
bool isValid() const { return LSquareLoc.isValid(); }
ResilienceData getResilienceData() const { return Resilience; }
bool isByref() const { return Byref; }
bool isAutoClosure() const { return AutoClosure; }
bool isThin() const { return Thin; }
bool isNoReturn() const { return NoReturn; }
bool isAssignment() const { return Assignment; }
bool isConversion() const { return Conversion; }
bool isTransparent() const { return Transparent; }
bool isPrefix() const { return ExplicitPrefix; }
bool isPostfix() const { return ExplicitPostfix; }
bool isInfix() const { return ExplicitInfix; }
bool isObjC() const { return ObjC; }
bool isObjCBlock() const { return ObjCBlock; }
bool isIBOutlet() const { return IBOutlet; }
bool isIBAction() const { return IBAction; }
bool isClassProtocol() const { return ClassProtocol; }
bool isLocalStorage() const { return LocalStorage; }
bool isWeak() const { return Weak; }
bool isUnowned() const { return Unowned; }
bool hasOwnership() const { return Weak || Unowned; }
Ownership getOwnership() const {
if (Weak) return Ownership::Weak;
if (Unowned) return Ownership::Unowned;
return Ownership::Strong;
}
bool isExported() const { return Exported; }
bool hasCC() const { return cc.hasValue(); }
AbstractCC getAbstractCC() const { return *cc; }
bool empty() const {
return !isInfix() && !getResilienceData().isValid() && !isByref() &&
!isAutoClosure() && !isThin() && !isNoReturn() && !isAssignment() &&
!isConversion() && !isTransparent() && !isPostfix() && !isPrefix() &&
!isObjC() && !isObjCBlock() && !isIBOutlet() && !isIBAction() &&
!isClassProtocol() && !hasCC() && !hasOwnership() &&
!isLocalStorage() && !isExported() && AsmName.empty();
}
void clearOwnership() {
Weak = Unowned = false;
}
};
} // end namespace swift
#endif