summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/Type.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/Type.h')
-rw-r--r--include/clang/AST/Type.h49
1 files changed, 34 insertions, 15 deletions
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 71004fc572..09b3fc79b8 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -111,6 +111,7 @@ namespace clang {
/// The collection of all-type qualifiers we support.
/// Clang supports five independent qualifiers:
/// * C99: const, volatile, and restrict
+/// * MS: __unaligned
/// * Embedded C (TR18037): address spaces
/// * Objective C: the GC attributes (none, weak, or strong)
class Qualifiers {
@@ -152,8 +153,8 @@ public:
enum {
/// The maximum supported address space number.
- /// 24 bits should be enough for anyone.
- MaxAddressSpace = 0xffffffu,
+ /// 23 bits should be enough for anyone.
+ MaxAddressSpace = 0x7fffffu,
/// The width of the "fast" qualifier mask.
FastWidth = 3,
@@ -265,6 +266,13 @@ public:
Mask |= mask;
}
+ bool hasUnaligned() const { return Mask & UMask; }
+ void setUnaligned(bool flag) {
+ Mask = (Mask & ~UMask) | (flag ? UMask : 0);
+ }
+ void removeUnaligned() { Mask &= ~UMask; }
+ void addUnaligned() { Mask |= UMask; }
+
bool hasObjCGCAttr() const { return Mask & GCAttrMask; }
GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); }
void setObjCGCAttr(GC type) {
@@ -433,7 +441,9 @@ public:
// ObjC lifetime qualifiers must match exactly.
getObjCLifetime() == other.getObjCLifetime() &&
// CVR qualifiers may subset.
- (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask));
+ (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)) &&
+ // U qualifier may superset.
+ (!other.hasUnaligned() || hasUnaligned());
}
/// \brief Determines if these qualifiers compatibly include another set of
@@ -501,16 +511,19 @@ public:
private:
- // bits: |0 1 2|3 .. 4|5 .. 7|8 ... 31|
- // |C R V|GCAttr|Lifetime|AddressSpace|
+ // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31|
+ // |C R V|U|GCAttr|Lifetime|AddressSpace|
uint32_t Mask;
- static const uint32_t GCAttrMask = 0x18;
- static const uint32_t GCAttrShift = 3;
- static const uint32_t LifetimeMask = 0xE0;
- static const uint32_t LifetimeShift = 5;
- static const uint32_t AddressSpaceMask = ~(CVRMask|GCAttrMask|LifetimeMask);
- static const uint32_t AddressSpaceShift = 8;
+ static const uint32_t UMask = 0x8;
+ static const uint32_t UShift = 3;
+ static const uint32_t GCAttrMask = 0x30;
+ static const uint32_t GCAttrShift = 4;
+ static const uint32_t LifetimeMask = 0x1C0;
+ static const uint32_t LifetimeShift = 6;
+ static const uint32_t AddressSpaceMask =
+ ~(CVRMask | UMask | GCAttrMask | LifetimeMask);
+ static const uint32_t AddressSpaceShift = 9;
};
/// A std::pair-like structure for storing a qualified type split
@@ -5367,9 +5380,9 @@ inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) {
/// "int". However, it is not more qualified than "const volatile
/// int".
inline bool QualType::isMoreQualifiedThan(QualType other) const {
- Qualifiers myQuals = getQualifiers();
- Qualifiers otherQuals = other.getQualifiers();
- return (myQuals != otherQuals && myQuals.compatiblyIncludes(otherQuals));
+ Qualifiers MyQuals = getQualifiers();
+ Qualifiers OtherQuals = other.getQualifiers();
+ return (MyQuals != OtherQuals && MyQuals.compatiblyIncludes(OtherQuals));
}
/// Determine whether this type is at last
@@ -5377,7 +5390,13 @@ inline bool QualType::isMoreQualifiedThan(QualType other) const {
/// int" is at least as qualified as "const int", "volatile int",
/// "int", and "const volatile int".
inline bool QualType::isAtLeastAsQualifiedAs(QualType other) const {
- return getQualifiers().compatiblyIncludes(other.getQualifiers());
+ Qualifiers OtherQuals = other.getQualifiers();
+
+ // Ignore __unaligned qualifier if this type is a void.
+ if (getUnqualifiedType()->isVoidType())
+ OtherQuals.removeUnaligned();
+
+ return getQualifiers().compatiblyIncludes(OtherQuals);
}
/// If Type is a reference type (e.g., const