[NFC] Switch CodeGenFunction to use value init instead of member init lists

The member init list for the sole constructor for CodeGenFunction
has gotten out of hand, so this patch moves the non-parameter-dependent
initializations into the member value inits.

llvm-svn: 336726
This commit is contained in:
Erich Keane 2018-07-10 20:46:46 +00:00
parent 79d55d30c3
commit 7b8c12e7cc
23 changed files with 589 additions and 141 deletions

View File

@ -168,6 +168,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<DependentAddressSpaceType>
DependentAddressSpaceTypes;
mutable llvm::FoldingSet<VectorType> VectorTypes;
mutable llvm::FoldingSet<DependentVectorType> DependentVectorTypes;
mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
FunctionProtoTypes;
@ -1321,6 +1322,11 @@ public:
/// \pre \p VectorType must be a built-in type.
QualType getVectorType(QualType VectorType, unsigned NumElts,
VectorType::VectorKind VecKind) const;
/// Return the unique reference to the type for a dependently sized vector of
/// the specified element type.
QualType getDependentVectorType(QualType VectorType, Expr *SizeExpr,
SourceLocation AttrLoc,
VectorType::VectorKind VecKind) const;
/// Return the unique reference to an extended vector type
/// of the specified element type and size.

View File

@ -993,6 +993,12 @@ DEF_TRAVERSE_TYPE(DependentAddressSpaceType, {
TRY_TO(TraverseType(T->getPointeeType()));
})
DEF_TRAVERSE_TYPE(DependentVectorType, {
if (T->getSizeExpr())
TRY_TO(TraverseStmt(T->getSizeExpr()));
TRY_TO(TraverseType(T->getElementType()));
})
DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
if (T->getSizeExpr())
TRY_TO(TraverseStmt(T->getSizeExpr()));
@ -1221,6 +1227,12 @@ DEF_TRAVERSE_TYPELOC(VectorType, {
TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
})
DEF_TRAVERSE_TYPELOC(DependentVectorType, {
if (TL.getTypePtr()->getSizeExpr())
TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
})
// FIXME: size and attributes
// FIXME: base VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(ExtVectorType, {

View File

@ -1590,6 +1590,7 @@ protected:
class VectorTypeBitfields {
friend class VectorType;
friend class DependentVectorType;
unsigned : NumTypeBits;
@ -3079,6 +3080,51 @@ public:
}
};
/// Represents a vector type where either the type or sizeis dependent.
////
/// For example:
/// \code
/// template<typename T, int Size>
/// class vector {
/// typedef T __attribute__((vector_size(Size))) type;
/// }
/// \endcode
class DependentVectorType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
const ASTContext &Context;
QualType ElementType;
Expr *SizeExpr;
SourceLocation Loc;
DependentVectorType(const ASTContext &Context, QualType ElementType,
QualType CanonType, Expr *SizeExpr, SourceLocation Loc,
VectorType::VectorKind vecKind);
public:
Expr *getSizeExpr() const { return SizeExpr; }
QualType getElementType() const { return ElementType; }
SourceLocation getAttributeLoc() const { return Loc; }
VectorType::VectorKind getVectorKind() const {
return VectorType::VectorKind(VectorTypeBits.VecKind);
}
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
static bool classof(const Type *T) {
return T->getTypeClass() == DependentVector;
}
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, Context, getElementType(), getSizeExpr(), getVectorKind());
}
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
QualType ElementType, Expr *SizeExpr,
VectorType::VectorKind VecKind);
};
/// ExtVectorType - Extended vector type. This type is created using
/// __attribute__((ext_vector_type(n)), where "n" is the number of elements.
/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This

View File

@ -1798,6 +1798,12 @@ class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
VectorType> {
};
// FIXME: size expression and attribute locations (or keyword if we
// ever fully support altivec syntax).
class DependentVectorTypeLoc
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentVectorTypeLoc,
DependentVectorType> {};
// FIXME: size expression and attribute locations.
class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
ExtVectorTypeLoc,

View File

@ -75,6 +75,7 @@ DEPENDENT_TYPE(DependentSizedArray, ArrayType)
DEPENDENT_TYPE(DependentSizedExtVector, Type)
DEPENDENT_TYPE(DependentAddressSpace, Type)
TYPE(Vector, Type)
DEPENDENT_TYPE(DependentVector, Type)
TYPE(ExtVector, VectorType)
ABSTRACT_TYPE(Function, Type)
TYPE(FunctionProto, FunctionType)

View File

@ -1371,6 +1371,7 @@ public:
QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
Expr *ArraySize, unsigned Quals,
SourceRange Brackets, DeclarationName Entity);
QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc);
QualType BuildExtVectorType(QualType T, Expr *ArraySize,
SourceLocation AttrLoc);
QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,

View File

@ -1032,133 +1032,133 @@ namespace serialization {
/// AST. Note that DeclCode values share this code space.
enum TypeCode {
/// An ExtQualType record.
TYPE_EXT_QUAL = 1,
TYPE_EXT_QUAL = 1,
/// A ComplexType record.
TYPE_COMPLEX = 3,
TYPE_COMPLEX = 3,
/// A PointerType record.
TYPE_POINTER = 4,
TYPE_POINTER = 4,
/// A BlockPointerType record.
TYPE_BLOCK_POINTER = 5,
TYPE_BLOCK_POINTER = 5,
/// An LValueReferenceType record.
TYPE_LVALUE_REFERENCE = 6,
TYPE_LVALUE_REFERENCE = 6,
/// An RValueReferenceType record.
TYPE_RVALUE_REFERENCE = 7,
TYPE_RVALUE_REFERENCE = 7,
/// A MemberPointerType record.
TYPE_MEMBER_POINTER = 8,
TYPE_MEMBER_POINTER = 8,
/// A ConstantArrayType record.
TYPE_CONSTANT_ARRAY = 9,
TYPE_CONSTANT_ARRAY = 9,
/// An IncompleteArrayType record.
TYPE_INCOMPLETE_ARRAY = 10,
TYPE_INCOMPLETE_ARRAY = 10,
/// A VariableArrayType record.
TYPE_VARIABLE_ARRAY = 11,
TYPE_VARIABLE_ARRAY = 11,
/// A VectorType record.
TYPE_VECTOR = 12,
TYPE_VECTOR = 12,
/// An ExtVectorType record.
TYPE_EXT_VECTOR = 13,
TYPE_EXT_VECTOR = 13,
/// A FunctionNoProtoType record.
TYPE_FUNCTION_NO_PROTO = 14,
TYPE_FUNCTION_NO_PROTO = 14,
/// A FunctionProtoType record.
TYPE_FUNCTION_PROTO = 15,
TYPE_FUNCTION_PROTO = 15,
/// A TypedefType record.
TYPE_TYPEDEF = 16,
TYPE_TYPEDEF = 16,
/// A TypeOfExprType record.
TYPE_TYPEOF_EXPR = 17,
TYPE_TYPEOF_EXPR = 17,
/// A TypeOfType record.
TYPE_TYPEOF = 18,
TYPE_TYPEOF = 18,
/// A RecordType record.
TYPE_RECORD = 19,
TYPE_RECORD = 19,
/// An EnumType record.
TYPE_ENUM = 20,
TYPE_ENUM = 20,
/// An ObjCInterfaceType record.
TYPE_OBJC_INTERFACE = 21,
TYPE_OBJC_INTERFACE = 21,
/// An ObjCObjectPointerType record.
TYPE_OBJC_OBJECT_POINTER = 22,
TYPE_OBJC_OBJECT_POINTER = 22,
/// a DecltypeType record.
TYPE_DECLTYPE = 23,
TYPE_DECLTYPE = 23,
/// An ElaboratedType record.
TYPE_ELABORATED = 24,
TYPE_ELABORATED = 24,
/// A SubstTemplateTypeParmType record.
TYPE_SUBST_TEMPLATE_TYPE_PARM = 25,
/// An UnresolvedUsingType record.
TYPE_UNRESOLVED_USING = 26,
TYPE_UNRESOLVED_USING = 26,
/// An InjectedClassNameType record.
TYPE_INJECTED_CLASS_NAME = 27,
TYPE_INJECTED_CLASS_NAME = 27,
/// An ObjCObjectType record.
TYPE_OBJC_OBJECT = 28,
TYPE_OBJC_OBJECT = 28,
/// An TemplateTypeParmType record.
TYPE_TEMPLATE_TYPE_PARM = 29,
TYPE_TEMPLATE_TYPE_PARM = 29,
/// An TemplateSpecializationType record.
TYPE_TEMPLATE_SPECIALIZATION = 30,
TYPE_TEMPLATE_SPECIALIZATION = 30,
/// A DependentNameType record.
TYPE_DEPENDENT_NAME = 31,
TYPE_DEPENDENT_NAME = 31,
/// A DependentTemplateSpecializationType record.
TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32,
/// A DependentSizedArrayType record.
TYPE_DEPENDENT_SIZED_ARRAY = 33,
TYPE_DEPENDENT_SIZED_ARRAY = 33,
/// A ParenType record.
TYPE_PAREN = 34,
TYPE_PAREN = 34,
/// A PackExpansionType record.
TYPE_PACK_EXPANSION = 35,
TYPE_PACK_EXPANSION = 35,
/// An AttributedType record.
TYPE_ATTRIBUTED = 36,
TYPE_ATTRIBUTED = 36,
/// A SubstTemplateTypeParmPackType record.
TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37,
/// A AutoType record.
TYPE_AUTO = 38,
TYPE_AUTO = 38,
/// A UnaryTransformType record.
TYPE_UNARY_TRANSFORM = 39,
TYPE_UNARY_TRANSFORM = 39,
/// An AtomicType record.
TYPE_ATOMIC = 40,
TYPE_ATOMIC = 40,
/// A DecayedType record.
TYPE_DECAYED = 41,
TYPE_DECAYED = 41,
/// An AdjustedType record.
TYPE_ADJUSTED = 42,
TYPE_ADJUSTED = 42,
/// A PipeType record.
TYPE_PIPE = 43,
TYPE_PIPE = 43,
/// An ObjCTypeParamType record.
TYPE_OBJC_TYPE_PARAM = 44,
TYPE_OBJC_TYPE_PARAM = 44,
/// A DeducedTemplateSpecializationType record.
TYPE_DEDUCED_TEMPLATE_SPECIALIZATION = 45,
@ -1167,7 +1167,10 @@ namespace serialization {
TYPE_DEPENDENT_SIZED_EXT_VECTOR = 46,
/// A DependentAddressSpaceType record.
TYPE_DEPENDENT_ADDRESS_SPACE = 47
TYPE_DEPENDENT_ADDRESS_SPACE = 47,
/// A dependentSizedVectorType record.
TYPE_DEPENDENT_SIZED_VECTOR = 48
};
/// The type IDs for special types constructed by semantic

View File

@ -3035,6 +3035,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
case Type::Builtin:
case Type::Complex:
case Type::Vector:
case Type::DependentVector:
case Type::ExtVector:
case Type::DependentSizedExtVector:
case Type::DependentAddressSpace:
@ -3312,6 +3313,44 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
Types.push_back(New);
return QualType(New, 0);
}
QualType
ASTContext::getDependentVectorType(QualType VecType, Expr *SizeExpr,
SourceLocation AttrLoc,
VectorType::VectorKind VecKind) const {
llvm::FoldingSetNodeID ID;
DependentVectorType::Profile(ID, *this, getCanonicalType(VecType), SizeExpr,
VecKind);
void *InsertPos = nullptr;
DependentVectorType *Canon =
DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
DependentVectorType *New;
if (Canon) {
New = new (*this, TypeAlignment) DependentVectorType(
*this, VecType, QualType(Canon, 0), SizeExpr, AttrLoc, VecKind);
} else {
QualType CanonVecTy = getCanonicalType(VecType);
if (CanonVecTy == VecType) {
New = new (*this, TypeAlignment) DependentVectorType(
*this, VecType, QualType(), SizeExpr, AttrLoc, VecKind);
DependentVectorType *CanonCheck =
DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!CanonCheck &&
"Dependent-sized vector_size canonical type broken");
(void)CanonCheck;
DependentVectorTypes.InsertNode(New, InsertPos);
} else {
QualType Canon = getDependentSizedExtVectorType(CanonVecTy, SizeExpr,
SourceLocation());
New = new (*this, TypeAlignment) DependentVectorType(
*this, VecType, Canon, SizeExpr, AttrLoc, VecKind);
}
}
Types.push_back(New);
return QualType(New, 0);
}
/// getExtVectorType - Return the unique reference to an extended vector type of
/// the specified element type and size. VectorType must be a built-in type.

View File

@ -405,6 +405,20 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
}
case Type::DependentVector: {
const auto *Vec1 = cast<DependentVectorType>(T1);
const auto *Vec2 = cast<DependentVectorType>(T2);
if (Vec1->getVectorKind() != Vec2->getVectorKind())
return false;
if (!IsStructurallyEquivalent(Context, Vec1->getSizeExpr(),
Vec2->getSizeExpr()))
return false;
if (!IsStructurallyEquivalent(Context, Vec1->getElementType(),
Vec2->getElementType()))
return false;
break;
}
case Type::Vector:
case Type::ExtVector: {
const auto *Vec1 = cast<VectorType>(T1);

View File

@ -539,7 +539,9 @@ private:
void mangleBareFunctionType(const FunctionProtoType *T, bool MangleReturnType,
const FunctionDecl *FD = nullptr);
void mangleNeonVectorType(const VectorType *T);
void mangleNeonVectorType(const DependentVectorType *T);
void mangleAArch64NeonVectorType(const VectorType *T);
void mangleAArch64NeonVectorType(const DependentVectorType *T);
void mangleIntegerLiteral(QualType T, const llvm::APSInt &Value);
void mangleMemberExprBase(const Expr *base, bool isArrow);
@ -1930,6 +1932,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::VariableArray:
case Type::DependentSizedArray:
case Type::DependentAddressSpace:
case Type::DependentVector:
case Type::DependentSizedExtVector:
case Type::Vector:
case Type::ExtVector:
@ -3000,6 +3003,11 @@ void CXXNameMangler::mangleNeonVectorType(const VectorType *T) {
Out << BaseName << EltName;
}
void CXXNameMangler::mangleNeonVectorType(const DependentVectorType *T) {
llvm_unreachable(
"Mangling for Dependent Sized Neon Vector not yet implemented");
}
static StringRef mangleAArch64VectorBase(const BuiltinType *EltType) {
switch (EltType->getKind()) {
case BuiltinType::SChar:
@ -3067,6 +3075,10 @@ void CXXNameMangler::mangleAArch64NeonVectorType(const VectorType *T) {
("__" + EltName + "x" + Twine(T->getNumElements()) + "_t").str();
Out << TypeName.length() << TypeName;
}
void CXXNameMangler::mangleAArch64NeonVectorType(const DependentVectorType *T) {
llvm_unreachable(
"Mangling for Dependent Sized AArch64 Neon Vector not yet implemented");
}
// GNU extension: vector types
// <type> ::= <vector-type>
@ -3097,6 +3109,32 @@ void CXXNameMangler::mangleType(const VectorType *T) {
else
mangleType(T->getElementType());
}
void CXXNameMangler::mangleType(const DependentVectorType *T) {
if ((T->getVectorKind() == VectorType::NeonVector ||
T->getVectorKind() == VectorType::NeonPolyVector)) {
llvm::Triple Target = getASTContext().getTargetInfo().getTriple();
llvm::Triple::ArchType Arch =
getASTContext().getTargetInfo().getTriple().getArch();
if ((Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be) &&
!Target.isOSDarwin())
mangleAArch64NeonVectorType(T);
else
mangleNeonVectorType(T);
return;
}
Out << "Dv";
mangleExpression(T->getSizeExpr());
Out << '_';
if (T->getVectorKind() == VectorType::AltiVecPixel)
Out << 'p';
else if (T->getVectorKind() == VectorType::AltiVecBool)
Out << 'b';
else
mangleType(T->getElementType());
}
void CXXNameMangler::mangleType(const ExtVectorType *T) {
mangleType(static_cast<const VectorType*>(T));
}

View File

@ -2514,6 +2514,16 @@ void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T,
Qualifiers Quals, SourceRange Range) {
mangleType(static_cast<const VectorType *>(T), Quals, Range);
}
void MicrosoftCXXNameMangler::mangleType(const DependentVectorType *T,
Qualifiers, SourceRange Range) {
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(
DiagnosticsEngine::Error,
"cannot mangle this dependent-sized vector type yet");
Diags.Report(Range.getBegin(), DiagID) << Range;
}
void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T,
Qualifiers, SourceRange Range) {
DiagnosticsEngine &Diags = Context.getDiags();

View File

@ -177,6 +177,28 @@ void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID,
E->Profile(ID, Context, true);
}
DependentVectorType::DependentVectorType(const ASTContext &Context,
QualType ElementType,
QualType CanonType, Expr *SizeExpr,
SourceLocation Loc,
VectorType::VectorKind VecKind)
: Type(DependentVector, CanonType, /*Dependent=*/true,
/*InstantiationDependent=*/true,
ElementType->isVariablyModifiedType(),
ElementType->containsUnexpandedParameterPack() ||
(SizeExpr && SizeExpr->containsUnexpandedParameterPack())),
Context(Context), ElementType(ElementType), SizeExpr(SizeExpr), Loc(Loc) {
VectorTypeBits.VecKind = VecKind;
}
void DependentVectorType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context,
QualType ElementType, Expr *SizeExpr,
VectorType::VectorKind VecKind) {
ID.AddPointer(ElementType.getAsOpaquePtr());
SizeExpr->Profile(ID, Context, true);
}
DependentSizedExtVectorType::DependentSizedExtVectorType(const
ASTContext &Context,
QualType ElementType,
@ -3783,6 +3805,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
case Type::IncompleteArray:
case Type::VariableArray:
case Type::DependentSizedArray:
case Type::DependentVector:
case Type::DependentSizedExtVector:
case Type::Vector:
case Type::ExtVector:

View File

@ -242,6 +242,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
case Type::RValueReference:
case Type::MemberPointer:
case Type::DependentAddressSpace:
case Type::DependentVector:
case Type::DependentSizedExtVector:
case Type::Vector:
case Type::ExtVector:
@ -640,7 +641,55 @@ void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
printAfter(T->getElementType(), OS);
}
}
void TypePrinter::printDependentVectorBefore(const DependentVectorType *T,
raw_ostream &OS) {
switch (T->getVectorKind()) {
case VectorType::AltiVecPixel:
OS << "__vector __pixel ";
break;
case VectorType::AltiVecBool:
OS << "__vector __bool ";
printBefore(T->getElementType(), OS);
break;
case VectorType::AltiVecVector:
OS << "__vector ";
printBefore(T->getElementType(), OS);
break;
case VectorType::NeonVector:
OS << "__attribute__((neon_vector_type(";
if (T->getSizeExpr())
T->getSizeExpr()->printPretty(OS, nullptr, Policy);
OS << "))) ";
printBefore(T->getElementType(), OS);
break;
case VectorType::NeonPolyVector:
OS << "__attribute__((neon_polyvector_type(";
if (T->getSizeExpr())
T->getSizeExpr()->printPretty(OS, nullptr, Policy);
OS << "))) ";
printBefore(T->getElementType(), OS);
break;
case VectorType::GenericVector: {
// FIXME: We prefer to print the size directly here, but have no way
// to get the size of the type.
OS << "__attribute__((__vector_size__(";
if (T->getSizeExpr())
T->getSizeExpr()->printPretty(OS, nullptr, Policy);
OS << " * sizeof(";
print(T->getElementType(), OS, StringRef());
OS << ")))) ";
printBefore(T->getElementType(), OS);
break;
}
}
}
void TypePrinter::printDependentVectorAfter(const DependentVectorType *T,
raw_ostream &OS) {
printAfter(T->getElementType(), OS);
}
void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
raw_ostream &OS) {

View File

@ -65,25 +65,9 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
: CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
Builder(cgm, cgm.getModule().getContext(), llvm::ConstantFolder(),
CGBuilderInserterTy(this)),
CurFn(nullptr), ReturnValue(Address::invalid()),
CapturedStmtInfo(nullptr), SanOpts(CGM.getLangOpts().Sanitize),
IsSanitizerScope(false), CurFuncIsThunk(false), AutoreleaseResult(false),
SawAsmBlock(false), IsOutlinedSEHHelper(false), BlockInfo(nullptr),
BlockPointer(nullptr), LambdaThisCaptureField(nullptr),
NormalCleanupDest(Address::invalid()), NextCleanupDestIndex(1),
FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr),
EHSelectorSlot(nullptr), DebugInfo(CGM.getModuleDebugInfo()),
DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(nullptr),
PGO(cgm), SwitchInsn(nullptr), SwitchWeights(nullptr),
CaseRangeBlock(nullptr), UnreachableBlock(nullptr), NumReturnExprs(0),
NumSimpleReturnExprs(0), CXXABIThisDecl(nullptr),
CXXABIThisValue(nullptr), CXXThisValue(nullptr),
CXXStructorImplicitParamDecl(nullptr),
CXXStructorImplicitParamValue(nullptr), OutermostConditional(nullptr),
CurLexicalScope(nullptr), TerminateLandingPad(nullptr),
TerminateHandler(nullptr), TrapBB(nullptr), LargestVectorWidth(0),
ShouldEmitLifetimeMarkers(
shouldEmitLifetimeMarkers(CGM.getCodeGenOpts(), CGM.getLangOpts())) {
SanOpts(CGM.getLangOpts().Sanitize), DebugInfo(CGM.getModuleDebugInfo()),
PGO(cgm), ShouldEmitLifetimeMarkers(shouldEmitLifetimeMarkers(
CGM.getCodeGenOpts(), CGM.getLangOpts())) {
if (!suppressNewContext)
CGM.getCXXABI().getMangleContext().startNewFunction();

View File

@ -214,7 +214,7 @@ public:
const Decl *CurCodeDecl;
const CGFunctionInfo *CurFnInfo;
QualType FnRetTy;
llvm::Function *CurFn;
llvm::Function *CurFn = nullptr;
// Holds coroutine data if the current function is a coroutine. We use a
// wrapper to manage its lifetime, so that we don't have to define CGCoroData
@ -242,7 +242,7 @@ public:
/// ReturnValue - The temporary alloca to hold the return
/// value. This is invalid iff the function has no return value.
Address ReturnValue;
Address ReturnValue = Address::invalid();
/// Return true if a label was seen in the current scope.
bool hasLabelBeenSeenInCurrentScope() const {
@ -321,7 +321,7 @@ public:
/// Captured 'this' type.
FieldDecl *CXXThisFieldDecl;
};
CGCapturedStmtInfo *CapturedStmtInfo;
CGCapturedStmtInfo *CapturedStmtInfo = nullptr;
/// RAII for correct setting/restoring of CapturedStmtInfo.
class CGCapturedStmtRAII {
@ -366,7 +366,7 @@ public:
SanitizerSet SanOpts;
/// True if CodeGen currently emits code implementing sanitizer checks.
bool IsSanitizerScope;
bool IsSanitizerScope = false;
/// RAII object to set/unset CodeGenFunction::IsSanitizerScope.
class SanitizerScope {
@ -378,26 +378,26 @@ public:
/// In C++, whether we are code generating a thunk. This controls whether we
/// should emit cleanups.
bool CurFuncIsThunk;
bool CurFuncIsThunk = false;
/// In ARC, whether we should autorelease the return value.
bool AutoreleaseResult;
bool AutoreleaseResult = false;
/// Whether we processed a Microsoft-style asm block during CodeGen. These can
/// potentially set the return value.
bool SawAsmBlock;
bool SawAsmBlock = false;
const FunctionDecl *CurSEHParent = nullptr;
/// True if the current function is an outlined SEH helper. This can be a
/// finally block or filter expression.
bool IsOutlinedSEHHelper;
bool IsOutlinedSEHHelper = false;
const CodeGen::CGBlockInfo *BlockInfo;
llvm::Value *BlockPointer;
const CodeGen::CGBlockInfo *BlockInfo = nullptr;
llvm::Value *BlockPointer = nullptr;
llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
FieldDecl *LambdaThisCaptureField;
FieldDecl *LambdaThisCaptureField = nullptr;
/// A mapping from NRVO variables to the flags used to indicate
/// when the NRVO has been applied to this variable.
@ -434,23 +434,23 @@ public:
};
/// i32s containing the indexes of the cleanup destinations.
Address NormalCleanupDest;
Address NormalCleanupDest = Address::invalid();
unsigned NextCleanupDestIndex;
unsigned NextCleanupDestIndex = 1;
/// FirstBlockInfo - The head of a singly-linked-list of block layouts.
CGBlockInfo *FirstBlockInfo;
CGBlockInfo *FirstBlockInfo = nullptr;
/// EHResumeBlock - Unified block containing a call to llvm.eh.resume.
llvm::BasicBlock *EHResumeBlock;
llvm::BasicBlock *EHResumeBlock = nullptr;
/// The exception slot. All landing pads write the current exception pointer
/// into this alloca.
llvm::Value *ExceptionSlot;
llvm::Value *ExceptionSlot = nullptr;
/// The selector slot. Under the MandatoryCleanup model, all landing pads
/// write the current selector value into this alloca.
llvm::AllocaInst *EHSelectorSlot;
llvm::AllocaInst *EHSelectorSlot = nullptr;
/// A stack of exception code slots. Entering an __except block pushes a slot
/// on the stack and leaving pops one. The __exception_code() intrinsic loads
@ -1087,17 +1087,17 @@ public:
private:
CGDebugInfo *DebugInfo;
bool DisableDebugInfo;
bool DisableDebugInfo = false;
/// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid
/// calling llvm.stacksave for multiple VLAs in the same scope.
bool DidCallStackSave;
bool DidCallStackSave = false;
/// IndirectBranch - The first time an indirect goto is seen we create a block
/// with an indirect branch. Every time we see the address of a label taken,
/// we add the label to the indirect goto. Every subsequent indirect goto is
/// codegen'd as a jump to the IndirectBranch's basic block.
llvm::IndirectBrInst *IndirectBranch;
llvm::IndirectBrInst *IndirectBranch = nullptr;
/// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
/// decls.
@ -1247,13 +1247,13 @@ private:
/// SwitchInsn - This is nearest current switch instruction. It is null if
/// current context is not in a switch.
llvm::SwitchInst *SwitchInsn;
llvm::SwitchInst *SwitchInsn = nullptr;
/// The branch weights of SwitchInsn when doing instrumentation based PGO.
SmallVector<uint64_t, 16> *SwitchWeights;
SmallVector<uint64_t, 16> *SwitchWeights = nullptr;
/// CaseRangeBlock - This block holds if condition check for last case
/// statement range in current switch instruction.
llvm::BasicBlock *CaseRangeBlock;
llvm::BasicBlock *CaseRangeBlock = nullptr;
/// OpaqueLValues - Keeps track of the current set of opaque value
/// expressions.
@ -1270,13 +1270,13 @@ private:
/// A block containing a single 'unreachable' instruction. Created
/// lazily by getUnreachableBlock().
llvm::BasicBlock *UnreachableBlock;
llvm::BasicBlock *UnreachableBlock = nullptr;
/// Counts of the number return expressions in the function.
unsigned NumReturnExprs;
unsigned NumReturnExprs = 0;
/// Count the number of simple (constant) return expressions in the function.
unsigned NumSimpleReturnExprs;
unsigned NumSimpleReturnExprs = 0;
/// The last regular (non-return) debug location (breakpoint) in the function.
SourceLocation LastStopPoint;
@ -1396,9 +1396,9 @@ public:
private:
/// CXXThisDecl - When generating code for a C++ member function,
/// this will hold the implicit 'this' declaration.
ImplicitParamDecl *CXXABIThisDecl;
llvm::Value *CXXABIThisValue;
llvm::Value *CXXThisValue;
ImplicitParamDecl *CXXABIThisDecl = nullptr;
llvm::Value *CXXABIThisValue = nullptr;
llvm::Value *CXXThisValue = nullptr;
CharUnits CXXABIThisAlignment;
CharUnits CXXThisAlignment;
@ -1416,16 +1416,16 @@ private:
/// CXXStructorImplicitParamDecl - When generating code for a constructor or
/// destructor, this will hold the implicit argument (e.g. VTT).
ImplicitParamDecl *CXXStructorImplicitParamDecl;
llvm::Value *CXXStructorImplicitParamValue;
ImplicitParamDecl *CXXStructorImplicitParamDecl = nullptr;
llvm::Value *CXXStructorImplicitParamValue = nullptr;
/// OutermostConditional - Points to the outermost active
/// conditional control. This is used so that we know if a
/// temporary should be destroyed conditionally.
ConditionalEvaluation *OutermostConditional;
ConditionalEvaluation *OutermostConditional = nullptr;
/// The current lexical scope.
LexicalScope *CurLexicalScope;
LexicalScope *CurLexicalScope = nullptr;
/// The current source location that should be used for exception
/// handling code.
@ -1456,16 +1456,16 @@ private:
CurCodeDecl && CurCodeDecl->getAttr<ReturnsNonNullAttr>());
}
llvm::BasicBlock *TerminateLandingPad;
llvm::BasicBlock *TerminateHandler;
llvm::BasicBlock *TrapBB;
llvm::BasicBlock *TerminateLandingPad = nullptr;
llvm::BasicBlock *TerminateHandler = nullptr;
llvm::BasicBlock *TrapBB = nullptr;
/// Terminate funclets keyed by parent funclet pad.
llvm::MapVector<llvm::Value *, llvm::BasicBlock *> TerminateFunclets;
/// Largest vector width used in ths function. Will be used to create a
/// function attribute.
unsigned LargestVectorWidth;
unsigned LargestVectorWidth = 0;
/// True if we need emit the life-time markers.
const bool ShouldEmitLifetimeMarkers;

View File

@ -5346,6 +5346,11 @@ bool UnnamedLocalNoLinkageFinder::VisitVectorType(const VectorType* T) {
return Visit(T->getElementType());
}
bool UnnamedLocalNoLinkageFinder::VisitDependentVectorType(
const DependentVectorType *T) {
return Visit(T->getElementType());
}
bool UnnamedLocalNoLinkageFinder::VisitExtVectorType(const ExtVectorType* T) {
return Visit(T->getElementType());
}

View File

@ -1837,6 +1837,55 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
return Sema::TDK_NonDeducedMismatch;
}
case Type::DependentVector: {
const DependentVectorType *VectorParam = cast<DependentVectorType>(Param);
if (const VectorType *VectorArg = dyn_cast<VectorType>(Arg)) {
// Perform deduction on the element types.
if (Sema::TemplateDeductionResult Result =
DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, VectorParam->getElementType(),
VectorArg->getElementType(), Info, Deduced, TDF))
return Result;
// Perform deduction on the vector size, if we can.
NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr());
if (!NTTP)
return Sema::TDK_Success;
llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
ArgSize = VectorArg->getNumElements();
// Note that we use the "array bound" rules here; just like in that
// case, we don't have any particular type for the vector size, but
// we can provide one if necessary.
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgSize,
S.Context.IntTy, true, Info,
Deduced);
}
if (const DependentVectorType *VectorArg =
dyn_cast<DependentVectorType>(Arg)) {
// Perform deduction on the element types.
if (Sema::TemplateDeductionResult Result =
DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, VectorParam->getElementType(),
VectorArg->getElementType(), Info, Deduced, TDF))
return Result;
// Perform deduction on the vector size, if we can.
NonTypeTemplateParmDecl *NTTP =
getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr());
if (!NTTP)
return Sema::TDK_Success;
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP, VectorArg->getSizeExpr(), Info, Deduced);
}
return Sema::TDK_NonDeducedMismatch;
}
// (clang extension)
//
// T __attribute__(((ext_vector_type(N))))
@ -5227,6 +5276,14 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
OnlyDeduced, Depth, Used);
break;
case Type::DependentVector: {
const DependentVectorType *VecType = cast<DependentVectorType>(T);
MarkUsedTemplateParameters(Ctx, VecType->getElementType(), OnlyDeduced,
Depth, Used);
MarkUsedTemplateParameters(Ctx, VecType->getSizeExpr(), OnlyDeduced, Depth,
Used);
break;
}
case Type::DependentSizedExtVector: {
const DependentSizedExtVectorType *VecType
= cast<DependentSizedExtVectorType>(T);

View File

@ -2294,6 +2294,58 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
return T;
}
QualType Sema::BuildVectorType(QualType CurType, Expr *SizeExpr,
SourceLocation AttrLoc) {
// The base type must be integer (not Boolean or enumeration) or float, and
// can't already be a vector.
if (!CurType->isDependentType() &&
(!CurType->isBuiltinType() || CurType->isBooleanType() ||
(!CurType->isIntegerType() && !CurType->isRealFloatingType()))) {
Diag(AttrLoc, diag::err_attribute_invalid_vector_type) << CurType;
return QualType();
}
if (SizeExpr->isTypeDependent() || SizeExpr->isValueDependent())
return Context.getDependentVectorType(CurType, SizeExpr, AttrLoc,
VectorType::GenericVector);
llvm::APSInt VecSize(32);
if (!SizeExpr->isIntegerConstantExpr(VecSize, Context)) {
Diag(AttrLoc, diag::err_attribute_argument_type)
<< "vector_size" << AANT_ArgumentIntegerConstant
<< SizeExpr->getSourceRange();
return QualType();
}
if (CurType->isDependentType())
return Context.getDependentVectorType(CurType, SizeExpr, AttrLoc,
VectorType::GenericVector);
unsigned VectorSize = static_cast<unsigned>(VecSize.getZExtValue() * 8);
unsigned TypeSize = static_cast<unsigned>(Context.getTypeSize(CurType));
if (VectorSize == 0) {
Diag(AttrLoc, diag::err_attribute_zero_size) << SizeExpr->getSourceRange();
return QualType();
}
// vecSize is specified in bytes - convert to bits.
if (VectorSize % TypeSize) {
Diag(AttrLoc, diag::err_attribute_invalid_size)
<< SizeExpr->getSourceRange();
return QualType();
}
if (VectorType::isVectorSizeTooLarge(VectorSize / TypeSize)) {
Diag(AttrLoc, diag::err_attribute_size_too_large)
<< SizeExpr->getSourceRange();
return QualType();
}
return Context.getVectorType(CurType, VectorSize / TypeSize,
VectorType::GenericVector);
}
/// Build an ext-vector type.
///
/// Run the required checks for the extended vector type.
@ -6929,52 +6981,30 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr,
Attr.setInvalid();
return;
}
Expr *sizeExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
llvm::APSInt vecSize(32);
if (sizeExpr->isTypeDependent() || sizeExpr->isValueDependent() ||
!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
<< Attr.getName() << AANT_ArgumentIntegerConstant
<< sizeExpr->getSourceRange();
Attr.setInvalid();
return;
}
// The base type must be integer (not Boolean or enumeration) or float, and
// can't already be a vector.
if (!CurType->isBuiltinType() || CurType->isBooleanType() ||
(!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
Attr.setInvalid();
return;
}
unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
// vecSize is specified in bytes - convert to bits.
unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
// the vector size needs to be an integral multiple of the type size.
if (vectorSize % typeSize) {
S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size)
<< sizeExpr->getSourceRange();
Attr.setInvalid();
return;
}
if (VectorType::isVectorSizeTooLarge(vectorSize / typeSize)) {
S.Diag(Attr.getLoc(), diag::err_attribute_size_too_large)
<< sizeExpr->getSourceRange();
Attr.setInvalid();
return;
}
if (vectorSize == 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
<< sizeExpr->getSourceRange();
Attr.setInvalid();
return;
Expr *SizeExpr;
// Special case where the argument is a template id.
if (Attr.isArgIdent(0)) {
CXXScopeSpec SS;
SourceLocation TemplateKWLoc;
UnqualifiedId Id;
Id.setIdentifier(Attr.getArgAsIdent(0)->Ident, Attr.getLoc());
ExprResult Size = S.ActOnIdExpression(S.getCurScope(), SS, TemplateKWLoc,
Id, false, false);
if (Size.isInvalid())
return;
SizeExpr = Size.get();
} else {
SizeExpr = Attr.getArgAsExpr(0);
}
// Success! Instantiate the vector type, the number of elements is > 0, and
// not required to be a power of 2, unlike GCC.
CurType = S.Context.getVectorType(CurType, vectorSize/typeSize,
VectorType::GenericVector);
QualType T = S.BuildVectorType(CurType, SizeExpr, Attr.getLoc());
if (!T.isNull())
CurType = T;
else
Attr.setInvalid();
}
/// Process the OpenCL-like ext_vector_type attribute when it occurs on

View File

@ -818,6 +818,15 @@ public:
QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
VectorType::VectorKind VecKind);
/// Build a new potentially dependently-sized extended vector type
/// given the element type and number of elements.
///
/// By default, performs semantic analysis when building the vector type.
/// Subclasses may override this routine to provide different behavior.
QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
SourceLocation AttributeLoc,
VectorType::VectorKind);
/// Build a new extended vector type given the element type and
/// number of elements.
///
@ -4746,6 +4755,43 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
return Result;
}
template <typename Derived>
QualType TreeTransform<Derived>::TransformDependentVectorType(
TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
const DependentVectorType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(T->getElementType());
if (ElementType.isNull())
return QualType();
EnterExpressionEvaluationContext Unevaluated(
SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
Size = SemaRef.ActOnConstantExpression(Size);
if (Size.isInvalid())
return QualType();
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
Size.get() != T->getSizeExpr()) {
Result = getDerived().RebuildDependentVectorType(
ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
if (Result.isNull())
return QualType();
}
// Result might be dependent or not.
if (isa<DependentVectorType>(Result)) {
DependentVectorTypeLoc NewTL = TLB.push<DependentVectorTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc());
} else {
VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc());
}
return Result;
}
template<typename Derived>
QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
TypeLocBuilder &TLB,
@ -12377,6 +12423,13 @@ TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
}
template <typename Derived>
QualType TreeTransform<Derived>::RebuildDependentVectorType(
QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
VectorType::VectorKind VecKind) {
return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);
}
template<typename Derived>
QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
unsigned NumElements,

View File

@ -6371,6 +6371,17 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
return Context.getPipeType(ElementType, ReadOnly);
}
case TYPE_DEPENDENT_SIZED_VECTOR: {
unsigned Idx = 0;
QualType ElementType = readType(*Loc.F, Record, Idx);
Expr *SizeExpr = ReadExpr(*Loc.F);
SourceLocation AttrLoc = ReadSourceLocation(*Loc.F, Record, Idx);
unsigned VecKind = Record[Idx];
return Context.getDependentVectorType(ElementType, SizeExpr, AttrLoc,
(VectorType::VectorKind)VecKind);
}
case TYPE_DEPENDENT_SIZED_EXT_VECTOR: {
unsigned Idx = 0;
@ -6551,6 +6562,10 @@ void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation());
}
void TypeLocReader::VisitDependentVectorTypeLoc(DependentVectorTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation());
}
void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation());
}

View File

@ -455,6 +455,14 @@ ASTTypeWriter::VisitDependentSizedExtVectorType(
Code = TYPE_DEPENDENT_SIZED_EXT_VECTOR;
}
void ASTTypeWriter::VisitDependentVectorType(const DependentVectorType *T) {
Record.AddTypeRef(T->getElementType());
Record.AddStmt(T->getSizeExpr());
Record.AddSourceLocation(T->getAttributeLoc());
Record.push_back(T->getVectorKind());
Code = TYPE_DEPENDENT_SIZED_VECTOR;
}
void
ASTTypeWriter::VisitDependentAddressSpaceType(
const DependentAddressSpaceType *T) {
@ -676,6 +684,10 @@ void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) {
Record.AddSourceLocation(TL.getNameLoc());
}
void TypeLocWriter::VisitDependentVectorTypeLoc(DependentVectorTypeLoc TL) {
Record.AddSourceLocation(TL.getNameLoc());
}
void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
Record.AddSourceLocation(TL.getNameLoc());
}

View File

@ -291,3 +291,46 @@ const int &reference_to_vec_element = vi4(1).x;
// PR12649
typedef bool bad __attribute__((__vector_size__(16))); // expected-error {{invalid vector element type 'bool'}}
namespace Templates {
template <typename Elt, unsigned Size>
struct TemplateVectorType {
typedef Elt __attribute__((__vector_size__(Size))) type;
};
template <int N, typename T>
struct PR15730 {
typedef T __attribute__((vector_size(N * sizeof(T)))) type;
typedef T __attribute__((vector_size(8192))) type2;
typedef T __attribute__((vector_size(3))) type3;
};
void Init() {
const TemplateVectorType<float, 32>::type Works = {};
const TemplateVectorType<int, 32>::type Works2 = {};
// expected-error@298 {{invalid vector element type 'bool'}}
// expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<bool, 32>' requested here}}
const TemplateVectorType<bool, 32>::type NoBool;
// expected-error@298 {{invalid vector element type 'int __attribute__((ext_vector_type(4)))' (vector of 4 'int' values)}}
// expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int __attribute__((ext_vector_type(4))), 32>' requested here}}
const TemplateVectorType<vi4, 32>::type NoComplex;
// expected-error@298 {{vector size not an integral multiple of component size}}
// expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 33>' requested here}}
const TemplateVectorType<int, 33>::type BadSize;
// expected-error@298 {{vector size too large}}
// expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 8192>' requested here}}
const TemplateVectorType<int, 8192>::type TooLarge;
// expected-error@298 {{zero vector size}}
// expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 0>' requested here}}
const TemplateVectorType<int, 0>::type Zero;
// expected-error@304 {{vector size too large}}
// expected-error@305 {{vector size not an integral multiple of component size}}
// expected-note@+1 {{in instantiation of template class 'Templates::PR15730<8, int>' requested here}}
const PR15730<8, int>::type PR15730_1 = {};
// expected-error@304 {{vector size too large}}
// expected-note@+1 {{in instantiation of template class 'Templates::PR15730<8, char>' requested here}}
const PR15730<8, char>::type2 PR15730_2 = {};
}
} // namespace Templates

View File

@ -1772,6 +1772,7 @@ DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)
DEFAULT_TYPELOC_IMPL(DependentVector, Type)
DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
DEFAULT_TYPELOC_IMPL(Vector, Type)
DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)