diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-10-13 16:58:14 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-10-13 16:58:14 +0000 |
commit | 35495eb14f22c4e96956912e23ca2a433227ad8c (patch) | |
tree | 8f1712b949df4cfec62f342d2804a9c98fb5aa20 /lib/AST/Type.cpp | |
parent | 7b1ec6c4781ce960e1c3157b84ebe8362df2d2a7 (diff) |
Compute whether a type is variably modified as we build the type,
rather than walking the type's structure every time we request this
information. Performance optimization; no functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116409 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r-- | lib/AST/Type.cpp | 93 |
1 files changed, 49 insertions, 44 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index d924135ac6..6698e50eba 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -268,42 +268,6 @@ QualType Type::getPointeeType() const { return QualType(); } -/// isVariablyModifiedType (C99 6.7.5p3) - Return true for variable length -/// array types and types that contain variable array types in their -/// declarator -bool Type::isVariablyModifiedType() const { - // FIXME: We should really keep a "variably modified" bit in Type, rather - // than walking the type hierarchy to recompute it. - - // A VLA is a variably modified type. - if (isVariableArrayType()) - return true; - - // An array can contain a variably modified type - if (const Type *T = getArrayElementTypeNoTypeQual()) - return T->isVariablyModifiedType(); - - // A pointer can point to a variably modified type. - // Also, C++ references and member pointers can point to a variably modified - // type, where VLAs appear as an extension to C++, and should be treated - // correctly. - if (const PointerType *PT = getAs<PointerType>()) - return PT->getPointeeType()->isVariablyModifiedType(); - if (const ReferenceType *RT = getAs<ReferenceType>()) - return RT->getPointeeType()->isVariablyModifiedType(); - if (const MemberPointerType *PT = getAs<MemberPointerType>()) - return PT->getPointeeType()->isVariablyModifiedType(); - - // A function can return a variably modified type - // This one isn't completely obvious, but it follows from the - // definition in C99 6.7.5p3. Because of this rule, it's - // illegal to declare a function returning a variably modified type. - if (const FunctionType *FT = getAs<FunctionType>()) - return FT->getResultType()->isVariablyModifiedType(); - - return false; -} - const RecordType *Type::getAsStructureType() const { // If this is directly a structure type, return it. if (const RecordType *RT = dyn_cast<RecordType>(this)) { @@ -346,7 +310,7 @@ const RecordType *Type::getAsUnionType() const { ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base, ObjCProtocolDecl * const *Protocols, unsigned NumProtocols) - : Type(ObjCObject, Canonical, false), + : Type(ObjCObject, Canonical, false, false), NumProtocols(NumProtocols), BaseType(Base) { assert(this->NumProtocols == NumProtocols && @@ -913,7 +877,8 @@ DependentTemplateSpecializationType::DependentTemplateSpecializationType( NestedNameSpecifier *NNS, const IdentifierInfo *Name, unsigned NumArgs, const TemplateArgument *Args, QualType Canon) - : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true), + : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, + false), NNS(NNS), Name(Name), NumArgs(NumArgs) { assert(NNS && NNS->isDependent() && "DependentTemplateSpecializatonType requires dependent qualifier"); @@ -1026,6 +991,35 @@ llvm::StringRef FunctionType::getNameForCallConv(CallingConv CC) { } } +FunctionProtoType::FunctionProtoType(QualType Result, const QualType *ArgArray, + unsigned numArgs, bool isVariadic, + unsigned typeQuals, bool hasExs, + bool hasAnyExs, const QualType *ExArray, + unsigned numExs, QualType Canonical, + const ExtInfo &Info) + : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical, + Result->isDependentType(), + Result->isVariablyModifiedType(), + Info), + NumArgs(numArgs), NumExceptions(numExs), HasExceptionSpec(hasExs), + AnyExceptionSpec(hasAnyExs) +{ + // Fill in the trailing argument array. + QualType *ArgInfo = reinterpret_cast<QualType*>(this+1); + for (unsigned i = 0; i != numArgs; ++i) { + if (ArgArray[i]->isDependentType()) + setDependent(); + + ArgInfo[i] = ArgArray[i]; + } + + // Fill in the exception array. + QualType *Ex = ArgInfo + numArgs; + for (unsigned i = 0; i != numExs; ++i) + Ex[i] = ExArray[i]; +} + + void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, arg_type_iterator ArgTys, unsigned NumArgs, bool isVariadic, @@ -1087,7 +1081,8 @@ QualType TypedefType::desugar() const { } TypeOfExprType::TypeOfExprType(Expr *E, QualType can) - : Type(TypeOfExpr, can, E->isTypeDependent()), TOExpr(E) { + : Type(TypeOfExpr, can, E->isTypeDependent(), + E->getType()->isVariablyModifiedType()), TOExpr(E) { } QualType TypeOfExprType::desugar() const { @@ -1100,7 +1095,8 @@ void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID, } DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can) - : Type(Decltype, can, E->isTypeDependent()), E(E), + : Type(Decltype, can, E->isTypeDependent(), + E->getType()->isVariablyModifiedType()), E(E), UnderlyingType(underlyingType) { } @@ -1113,7 +1109,7 @@ void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID, } TagType::TagType(TypeClass TC, const TagDecl *D, QualType can) - : Type(TC, can, D->isDependentType()), + : Type(TC, can, D->isDependentType(), /*VariablyModified=*/false), decl(const_cast<TagDecl*>(D)) {} static TagDecl *getInterestingTagDecl(TagDecl *decl) { @@ -1213,16 +1209,25 @@ TemplateSpecializationType(TemplateName T, unsigned NumArgs, QualType Canon) : Type(TemplateSpecialization, Canon.isNull()? QualType(this, 0) : Canon, - T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)), - Template(T), NumArgs(NumArgs) { + T.isDependent(), false), + Template(T), NumArgs(NumArgs) +{ assert((!Canon.isNull() || T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)) && "No canonical type for non-dependent class template specialization"); TemplateArgument *TemplateArgs = reinterpret_cast<TemplateArgument *>(this + 1); - for (unsigned Arg = 0; Arg < NumArgs; ++Arg) + for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { + // Update dependent and variably-modified bits. + if (isDependent(Args[Arg])) + setDependent(); + if (Args[Arg].getKind() == TemplateArgument::Type && + Args[Arg].getAsType()->isVariablyModifiedType()) + setVariablyModified(); + new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]); + } } void |