summaryrefslogtreecommitdiffstats
path: root/lib/AST/Type.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r--lib/AST/Type.cpp273
1 files changed, 215 insertions, 58 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index cee5fee..7dd38cb 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -22,6 +22,7 @@
#include "clang/AST/Type.h"
#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"
@@ -509,6 +510,28 @@ bool Type::isObjCClassOrClassKindOfType() const {
return OPT->isObjCClassType() || OPT->isObjCQualifiedClassType();
}
+/// Was this type written with the special inert-in-MRC __unsafe_unretained
+/// qualifier?
+///
+/// This approximates the answer to the following question: if this
+/// translation unit were compiled in ARC, would this type be qualified
+/// with __unsafe_unretained?
+bool Type::isObjCInertUnsafeUnretainedType() const {
+ const Type *cur = this;
+ while (true) {
+ if (auto attributed = dyn_cast<AttributedType>(cur)) {
+ if (attributed->getAttrKind() ==
+ AttributedType::attr_objc_inert_unsafe_unretained)
+ return true;
+ }
+
+ // Single-step desugar until we run out of sugar.
+ QualType next = cur->getLocallyUnqualifiedSingleStepDesugaredType();
+ if (next.getTypePtr() == cur) return false;
+ cur = next.getTypePtr();
+ }
+}
+
ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
ArrayRef<QualType> typeArgs,
ArrayRef<ObjCProtocolDecl *> protocols,
@@ -836,11 +859,8 @@ public:
}
if (exceptionChanged) {
- unsigned size = sizeof(QualType) * exceptionTypes.size();
- void *mem = Ctx.Allocate(size, llvm::alignOf<QualType>());
- memcpy(mem, exceptionTypes.data(), size);
- info.ExceptionSpec.Exceptions
- = llvm::makeArrayRef((QualType *)mem, exceptionTypes.size());
+ info.ExceptionSpec.Exceptions =
+ llvm::makeArrayRef(exceptionTypes).copy(Ctx);
}
}
@@ -950,7 +970,7 @@ public:
== T->getDeducedType().getAsOpaquePtr())
return QualType(T, 0);
- return Ctx.getAutoType(deducedType, T->isDecltypeAuto(),
+ return Ctx.getAutoType(deducedType, T->getKeyword(),
T->isDependentType());
}
@@ -1158,11 +1178,8 @@ QualType QualType::substObjCTypeArgs(
}
if (exceptionChanged) {
- unsigned size = sizeof(QualType) * exceptionTypes.size();
- void *mem = ctx.Allocate(size, llvm::alignOf<QualType>());
- memcpy(mem, exceptionTypes.data(), size);
- info.ExceptionSpec.Exceptions
- = llvm::makeArrayRef((QualType *)mem, exceptionTypes.size());
+ info.ExceptionSpec.Exceptions =
+ llvm::makeArrayRef(exceptionTypes).copy(ctx);
}
}
@@ -1275,7 +1292,7 @@ Optional<ArrayRef<QualType>> Type::getObjCSubstitutions(
if (!dcTypeParams)
return None;
} else {
- // If we are in neither a class mor a category, there's no
+ // If we are in neither a class nor a category, there's no
// substitution to perform.
dcCategoryDecl = dyn_cast<ObjCCategoryDecl>(dc);
if (!dcCategoryDecl)
@@ -1905,6 +1922,28 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
case IncompleteArray:
// An array of unknown size is an incomplete type (C99 6.2.5p22).
return true;
+ case MemberPointer: {
+ // Member pointers in the MS ABI have special behavior in
+ // RequireCompleteType: they attach a MSInheritanceAttr to the CXXRecordDecl
+ // to indicate which inheritance model to use.
+ auto *MPTy = cast<MemberPointerType>(CanonicalType);
+ const Type *ClassTy = MPTy->getClass();
+ // Member pointers with dependent class types don't get special treatment.
+ if (ClassTy->isDependentType())
+ return false;
+ const CXXRecordDecl *RD = ClassTy->getAsCXXRecordDecl();
+ ASTContext &Context = RD->getASTContext();
+ // Member pointers not in the MS ABI don't get special treatment.
+ if (!Context.getTargetInfo().getCXXABI().isMicrosoft())
+ return false;
+ // The inheritance attribute might only be present on the most recent
+ // CXXRecordDecl, use that one.
+ RD = RD->getMostRecentDecl();
+ // Nothing interesting to do if the inheritance attribute is already set.
+ if (RD->hasAttr<MSInheritanceAttr>())
+ return false;
+ return true;
+ }
case ObjCObject:
return cast<ObjCObjectType>(CanonicalType)->getBaseType()
->isIncompleteType(Def);
@@ -2260,7 +2299,7 @@ bool QualType::isCXX11PODType(ASTContext &Context) const {
// a standard-layout class, and has no non-static data members of type
// non-POD struct, non-POD union (or array of such types). [...]
//
- // We don't directly query the recursive aspect as the requiremets for
+ // We don't directly query the recursive aspect as the requirements for
// both standard-layout classes and trivial classes apply recursively
// already.
}
@@ -2473,51 +2512,115 @@ const char *Type::getTypeClassName() const {
StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
switch (getKind()) {
- case Void: return "void";
- case Bool: return Policy.Bool ? "bool" : "_Bool";
- case Char_S: return "char";
- case Char_U: return "char";
- case SChar: return "signed char";
- case Short: return "short";
- case Int: return "int";
- case Long: return "long";
- case LongLong: return "long long";
- case Int128: return "__int128";
- case UChar: return "unsigned char";
- case UShort: return "unsigned short";
- case UInt: return "unsigned int";
- case ULong: return "unsigned long";
- case ULongLong: return "unsigned long long";
- case UInt128: return "unsigned __int128";
- case Half: return Policy.Half ? "half" : "__fp16";
- case Float: return "float";
- case Double: return "double";
- case LongDouble: return "long double";
+ case Void:
+ return "void";
+ case Bool:
+ return Policy.Bool ? "bool" : "_Bool";
+ case Char_S:
+ return "char";
+ case Char_U:
+ return "char";
+ case SChar:
+ return "signed char";
+ case Short:
+ return "short";
+ case Int:
+ return "int";
+ case Long:
+ return "long";
+ case LongLong:
+ return "long long";
+ case Int128:
+ return "__int128";
+ case UChar:
+ return "unsigned char";
+ case UShort:
+ return "unsigned short";
+ case UInt:
+ return "unsigned int";
+ case ULong:
+ return "unsigned long";
+ case ULongLong:
+ return "unsigned long long";
+ case UInt128:
+ return "unsigned __int128";
+ case Half:
+ return Policy.Half ? "half" : "__fp16";
+ case Float:
+ return "float";
+ case Double:
+ return "double";
+ case LongDouble:
+ return "long double";
case WChar_S:
- case WChar_U: return Policy.MSWChar ? "__wchar_t" : "wchar_t";
- case Char16: return "char16_t";
- case Char32: return "char32_t";
- case NullPtr: return "nullptr_t";
- case Overload: return "<overloaded function type>";
- case BoundMember: return "<bound member function type>";
- case PseudoObject: return "<pseudo-object type>";
- case Dependent: return "<dependent type>";
- case UnknownAny: return "<unknown type>";
- case ARCUnbridgedCast: return "<ARC unbridged cast type>";
- case BuiltinFn: return "<builtin fn type>";
- case ObjCId: return "id";
- case ObjCClass: return "Class";
- case ObjCSel: return "SEL";
- case OCLImage1d: return "image1d_t";
- case OCLImage1dArray: return "image1d_array_t";
- case OCLImage1dBuffer: return "image1d_buffer_t";
- case OCLImage2d: return "image2d_t";
- case OCLImage2dArray: return "image2d_array_t";
- case OCLImage3d: return "image3d_t";
- case OCLSampler: return "sampler_t";
- case OCLEvent: return "event_t";
+ case WChar_U:
+ return Policy.MSWChar ? "__wchar_t" : "wchar_t";
+ case Char16:
+ return "char16_t";
+ case Char32:
+ return "char32_t";
+ case NullPtr:
+ return "nullptr_t";
+ case Overload:
+ return "<overloaded function type>";
+ case BoundMember:
+ return "<bound member function type>";
+ case PseudoObject:
+ return "<pseudo-object type>";
+ case Dependent:
+ return "<dependent type>";
+ case UnknownAny:
+ return "<unknown type>";
+ case ARCUnbridgedCast:
+ return "<ARC unbridged cast type>";
+ case BuiltinFn:
+ return "<builtin fn type>";
+ case ObjCId:
+ return "id";
+ case ObjCClass:
+ return "Class";
+ case ObjCSel:
+ return "SEL";
+ case OCLImage1d:
+ return "image1d_t";
+ case OCLImage1dArray:
+ return "image1d_array_t";
+ case OCLImage1dBuffer:
+ return "image1d_buffer_t";
+ case OCLImage2d:
+ return "image2d_t";
+ case OCLImage2dArray:
+ return "image2d_array_t";
+ case OCLImage2dDepth:
+ return "image2d_depth_t";
+ case OCLImage2dArrayDepth:
+ return "image2d_array_depth_t";
+ case OCLImage2dMSAA:
+ return "image2d_msaa_t";
+ case OCLImage2dArrayMSAA:
+ return "image2d_array_msaa_t";
+ case OCLImage2dMSAADepth:
+ return "image2d_msaa_depth_t";
+ case OCLImage2dArrayMSAADepth:
+ return "image2d_array_msaa_depth_t";
+ case OCLImage3d:
+ return "image3d_t";
+ case OCLSampler:
+ return "sampler_t";
+ case OCLEvent:
+ return "event_t";
+ case OCLClkEvent:
+ return "clk_event_t";
+ case OCLQueue:
+ return "queue_t";
+ case OCLNDRange:
+ return "event_t";
+ case OCLReserveID:
+ return "reserve_id_t";
+ case OMPArraySection:
+ return "<OpenMP array section type>";
}
-
+
llvm_unreachable("Invalid builtin type.");
}
@@ -2863,6 +2966,48 @@ bool TagType::isBeingDefined() const {
return getDecl()->isBeingDefined();
}
+bool AttributedType::isQualifier() const {
+ switch (getAttrKind()) {
+ // These are type qualifiers in the traditional C sense: they annotate
+ // something about a specific value/variable of a type. (They aren't
+ // always part of the canonical type, though.)
+ case AttributedType::attr_address_space:
+ case AttributedType::attr_objc_gc:
+ case AttributedType::attr_objc_ownership:
+ case AttributedType::attr_objc_inert_unsafe_unretained:
+ case AttributedType::attr_nonnull:
+ case AttributedType::attr_nullable:
+ case AttributedType::attr_null_unspecified:
+ return true;
+
+ // These aren't qualifiers; they rewrite the modified type to be a
+ // semantically different type.
+ case AttributedType::attr_regparm:
+ case AttributedType::attr_vector_size:
+ case AttributedType::attr_neon_vector_type:
+ case AttributedType::attr_neon_polyvector_type:
+ case AttributedType::attr_pcs:
+ case AttributedType::attr_pcs_vfp:
+ case AttributedType::attr_noreturn:
+ case AttributedType::attr_cdecl:
+ case AttributedType::attr_fastcall:
+ case AttributedType::attr_stdcall:
+ case AttributedType::attr_thiscall:
+ case AttributedType::attr_pascal:
+ case AttributedType::attr_vectorcall:
+ case AttributedType::attr_inteloclbicc:
+ case AttributedType::attr_ms_abi:
+ case AttributedType::attr_sysv_abi:
+ case AttributedType::attr_ptr32:
+ case AttributedType::attr_ptr64:
+ case AttributedType::attr_sptr:
+ case AttributedType::attr_uptr:
+ case AttributedType::attr_objc_kindof:
+ return false;
+ }
+ llvm_unreachable("bad attributed type kind");
+}
+
bool AttributedType::isMSTypeSpec() const {
switch (getAttrKind()) {
default: return false;
@@ -2888,6 +3033,7 @@ bool AttributedType::isCallingConv() const {
case attr_neon_polyvector_type:
case attr_objc_gc:
case attr_objc_ownership:
+ case attr_objc_inert_unsafe_unretained:
case attr_noreturn:
case attr_nonnull:
case attr_nullable:
@@ -2930,7 +3076,7 @@ SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
}
TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const {
- return TemplateArgument(Arguments, NumArguments);
+ return TemplateArgument(llvm::makeArrayRef(Arguments, NumArguments));
}
void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) {
@@ -3416,11 +3562,22 @@ bool Type::canHaveNullability() const {
case BuiltinType::OCLImage1dBuffer:
case BuiltinType::OCLImage2d:
case BuiltinType::OCLImage2dArray:
+ case BuiltinType::OCLImage2dDepth:
+ case BuiltinType::OCLImage2dArrayDepth:
+ case BuiltinType::OCLImage2dMSAA:
+ case BuiltinType::OCLImage2dArrayMSAA:
+ case BuiltinType::OCLImage2dMSAADepth:
+ case BuiltinType::OCLImage2dArrayMSAADepth:
case BuiltinType::OCLImage3d:
case BuiltinType::OCLSampler:
case BuiltinType::OCLEvent:
+ case BuiltinType::OCLClkEvent:
+ case BuiltinType::OCLQueue:
+ case BuiltinType::OCLNDRange:
+ case BuiltinType::OCLReserveID:
case BuiltinType::BuiltinFn:
case BuiltinType::NullPtr:
+ case BuiltinType::OMPArraySection:
return false;
}
@@ -3521,7 +3678,7 @@ bool Type::isObjCARCImplicitlyUnretainedType() const {
if (const ObjCObjectPointerType *opt
= dyn_cast<ObjCObjectPointerType>(canon)) {
- // Class and Class<Protocol> don't require retension.
+ // Class and Class<Protocol> don't require retention.
if (opt->getObjectType()->isObjCClass())
return true;
}
OpenPOWER on IntegriCloud