From 89ee6822d8a6ac9fad18105c8f68194315c6edc5 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sat, 28 Feb 2009 01:32:25 +0000 Subject: [PATCH] Eliminate CXXRecordType llvm-svn: 65671 --- clang/Driver/ASTConsumers.cpp | 13 ++-- clang/include/clang/AST/Type.h | 20 ------ clang/include/clang/AST/TypeNodes.def | 1 - clang/lib/AST/ASTContext.cpp | 10 +-- clang/lib/AST/Type.cpp | 22 +++---- clang/lib/AST/TypeSerialization.cpp | 1 - clang/lib/CodeGen/CGDebugInfo.cpp | 1 - clang/lib/CodeGen/CodeGenTypes.cpp | 1 - clang/lib/Sema/SemaExprCXX.cpp | 4 +- clang/lib/Sema/SemaInherit.cpp | 4 +- clang/lib/Sema/SemaInherit.h | 5 +- clang/lib/Sema/SemaInit.cpp | 4 +- clang/lib/Sema/SemaLookup.cpp | 15 +++-- clang/lib/Sema/SemaNamedCast.cpp | 2 +- clang/lib/Sema/SemaOverload.cpp | 74 +++++++++++----------- clang/lib/Sema/SemaTemplateInstantiate.cpp | 8 --- 16 files changed, 73 insertions(+), 112 deletions(-) diff --git a/clang/Driver/ASTConsumers.cpp b/clang/Driver/ASTConsumers.cpp index cdfcb68b1446..85e379f9763e 100644 --- a/clang/Driver/ASTConsumers.cpp +++ b/clang/Driver/ASTConsumers.cpp @@ -944,12 +944,13 @@ public: void HandleTranslationUnit(TranslationUnit& TU) { ASTContext& C = TU.getContext(); for (ASTContext::type_iterator I=C.types_begin(),E=C.types_end(); I!=E; ++I) - if (CXXRecordType *T = dyn_cast(*I)) { - CXXRecordDecl* D = T->getDecl(); - // FIXME: This lookup needs to be generalized to handle namespaces and - // (when we support them) templates. - if (D->getNameAsString() == clsname) { - D->viewInheritance(C); + if (RecordType *T = dyn_cast(*I)) { + if (CXXRecordDecl *D = dyn_cast(T->getDecl())) { + // FIXME: This lookup needs to be generalized to handle namespaces and + // (when we support them) templates. + if (D->getNameAsString() == clsname) { + D->viewInheritance(C); + } } } } diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 3ca695c0b8bf..b6a1ec17b9fc 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1308,7 +1308,6 @@ public: } static bool classof(const TagType *) { return true; } static bool classof(const RecordType *) { return true; } - static bool classof(const CXXRecordType *) { return true; } static bool classof(const EnumType *) { return true; } protected: @@ -1348,25 +1347,6 @@ public: static bool classof(const RecordType *) { return true; } }; -/// CXXRecordType - This is a helper class that allows the use of -/// isa/cast/dyncast to detect TagType objects of C++ structs/unions/classes. -class CXXRecordType : public RecordType { - explicit CXXRecordType(CXXRecordDecl *D) - : RecordType(CXXRecord, reinterpret_cast(D)) { } - friend class ASTContext; // ASTContext creates these. -public: - - CXXRecordDecl *getDecl() const { - return reinterpret_cast(RecordType::getDecl()); - } - - static bool classof(const TagType *T); - static bool classof(const Type *T) { - return isa(T) && classof(cast(T)); - } - static bool classof(const CXXRecordType *) { return true; } -}; - /// EnumType - This is a helper class that allows the use of isa/cast/dyncast /// to detect TagType objects of enums. class EnumType : public TagType { diff --git a/clang/include/clang/AST/TypeNodes.def b/clang/include/clang/AST/TypeNodes.def index 273475b0411a..e071f640ba0e 100644 --- a/clang/include/clang/AST/TypeNodes.def +++ b/clang/include/clang/AST/TypeNodes.def @@ -68,7 +68,6 @@ NON_CANONICAL_TYPE(TypeOfExpr, Type) NON_CANONICAL_TYPE(TypeOf, Type) ABSTRACT_TYPE(Tag, Type) TYPE(Record, TagType) -TYPE(CXXRecord, RecordType) // FIXME: kill this one TYPE(Enum, TagType) DEPENDENT_TYPE(TemplateTypeParm, Type) NON_CANONICAL_TYPE(ClassTemplateSpecialization, Type) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 702dba2431a9..749655d8712e 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -448,7 +448,6 @@ ASTContext::getTypeInfo(const Type *T) { break; } case Type::Record: - case Type::CXXRecord: case Type::Enum: { const TagType *TT = cast(T); @@ -1231,13 +1230,7 @@ QualType ASTContext::getTypeDeclType(TypeDecl *Decl, TypeDecl* PrevDecl) { } else if (ObjCInterfaceDecl *ObjCInterface = dyn_cast(Decl)) return getObjCInterfaceType(ObjCInterface); - if (CXXRecordDecl *CXXRecord = dyn_cast(Decl)) { - if (PrevDecl) - Decl->TypeForDecl = PrevDecl->TypeForDecl; - else - Decl->TypeForDecl = new (*this,8) CXXRecordType(CXXRecord); - } - else if (RecordDecl *Record = dyn_cast(Decl)) { + if (RecordDecl *Record = dyn_cast(Decl)) { if (PrevDecl) Decl->TypeForDecl = PrevDecl->TypeForDecl; else @@ -2841,7 +2834,6 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) { case Type::FunctionNoProto: return mergeFunctionTypes(LHS, RHS); case Type::Record: - case Type::CXXRecord: case Type::Enum: // FIXME: Why are these compatible? if (isObjCIdStructType(LHS) && isObjCClassStructType(RHS)) return LHS; diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 06ae9eb4e259..3b06b4ee28d2 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -119,7 +119,6 @@ bool Type::isDerivedType() const { case FunctionNoProto: case Reference: case Record: - case CXXRecord: return true; default: return false; @@ -709,10 +708,13 @@ bool Type::isScalarType() const { /// subsumes the notion of C aggregates (C99 6.2.5p21) because it also /// includes union types. bool Type::isAggregateType() const { - if (const CXXRecordType *CXXClassType = dyn_cast(CanonicalType)) - return CXXClassType->getDecl()->isAggregate(); - if (isa(CanonicalType)) + if (const RecordType *Record = dyn_cast(CanonicalType)) { + if (CXXRecordDecl *ClassDecl = dyn_cast(Record->getDecl())) + return ClassDecl->isAggregate(); + return true; + } + if (const ExtQualType *EXTQT = dyn_cast(CanonicalType)) return EXTQT->getBaseType()->isAggregateType(); return isa(CanonicalType); @@ -743,7 +745,6 @@ bool Type::isIncompleteType() const { // be completed. return isVoidType(); case Record: - case CXXRecord: case Enum: // A tagged type (struct/union/enum/class) is incomplete if the decl is a // forward declaration, but not a full definition (C99 6.2.5p22). @@ -784,11 +785,12 @@ bool Type::isPODType() const { return true; case Record: + if (CXXRecordDecl *ClassDecl + = dyn_cast(cast(CanonicalType)->getDecl())) + return ClassDecl->isPOD(); + // C struct/union is POD. return true; - - case CXXRecord: - return cast(CanonicalType)->getDecl()->isPOD(); } } @@ -915,10 +917,6 @@ bool RecordType::classof(const TagType *TT) { return isa(TT->getDecl()); } -bool CXXRecordType::classof(const TagType *TT) { - return isa(TT->getDecl()); -} - bool EnumType::classof(const TagType *TT) { return isa(TT->getDecl()); } diff --git a/clang/lib/AST/TypeSerialization.cpp b/clang/lib/AST/TypeSerialization.cpp index 2d052aa270f5..b7a8f1a366dc 100644 --- a/clang/lib/AST/TypeSerialization.cpp +++ b/clang/lib/AST/TypeSerialization.cpp @@ -112,7 +112,6 @@ void Type::Create(ASTContext& Context, unsigned i, Deserializer& D) { break; case Type::Record: - case Type::CXXRecord: case Type::Enum: // FIXME: Implement this! assert(false && "Can't deserialize tag types!"); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 62b9f4aff727..101dae059268 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -508,7 +508,6 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, case Type::Pointer: Slot = CreateType(cast(Ty), Unit); break; case Type::Typedef: Slot = CreateType(cast(Ty), Unit); break; case Type::Record: - case Type::CXXRecord: case Type::Enum: Slot = CreateType(cast(Ty), Unit); break; diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 77131332e6d8..4d92f5cc3ad8 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -302,7 +302,6 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { return ConvertTypeRecursive(Context.getObjCIdType()); case Type::Record: - case Type::CXXRecord: case Type::Enum: { const TagDecl *TD = cast(Ty).getDecl(); const llvm::Type *Res = ConvertTagDeclType(TD); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 60234691932e..37e4fdb24d57 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -402,8 +402,8 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, DeclarationName NewName = Context.DeclarationNames.getCXXOperatorName( IsArray ? OO_Array_New : OO_New); if (AllocType->isRecordType() && !UseGlobal) { - CXXRecordDecl *Record = cast(AllocType->getAsRecordType()) - ->getDecl(); + CXXRecordDecl *Record + = cast(AllocType->getAsRecordType()->getDecl()); // FIXME: We fail to find inherited overloads. if (FindAllocationOverload(StartLoc, Range, NewName, &AllocArgs[0], AllocArgs.size(), Record, /*AllowMissing=*/true, diff --git a/clang/lib/Sema/SemaInherit.cpp b/clang/lib/Sema/SemaInherit.cpp index fe1c96b09db1..a9135a3b3c6a 100644 --- a/clang/lib/Sema/SemaInherit.cpp +++ b/clang/lib/Sema/SemaInherit.cpp @@ -87,7 +87,7 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base, BasePaths &Paths) { return false; Paths.setOrigin(Derived); - return LookupInBases(cast(Derived->getAsRecordType())->getDecl(), + return LookupInBases(cast(Derived->getAsRecordType()->getDecl()), MemberLookupCriteria(Base), Paths); } @@ -123,7 +123,7 @@ bool Sema::LookupInBases(CXXRecordDecl *Class, if (Paths.isDetectingVirtual() && Paths.DetectedVirtual == 0) { // If this is the first virtual we find, remember it. If it turns out // there is no base path here, we'll reset it later. - Paths.DetectedVirtual = cast(BaseType->getAsRecordType()); + Paths.DetectedVirtual = BaseType->getAsRecordType(); SetVirtual = true; } } else diff --git a/clang/lib/Sema/SemaInherit.h b/clang/lib/Sema/SemaInherit.h index 311c136a0fff..8d008a2ce61f 100644 --- a/clang/lib/Sema/SemaInherit.h +++ b/clang/lib/Sema/SemaInherit.h @@ -27,7 +27,6 @@ namespace clang { class CXXBaseSpecifier; - class CXXRecordType; /// BasePathElement - An element in a path from a derived class to a /// base class. Each step in the path references the link from a @@ -128,7 +127,7 @@ namespace clang { BasePath ScratchPath; /// DetectedVirtual - The base class that is virtual. - const CXXRecordType *DetectedVirtual; + const RecordType *DetectedVirtual; friend class Sema; @@ -167,7 +166,7 @@ namespace clang { bool isDetectingVirtual() const { return DetectVirtual; } /// getDetectedVirtual - The virtual base discovered on the path. - const CXXRecordType* getDetectedVirtual() const { + const RecordType* getDetectedVirtual() const { return DetectedVirtual; } diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index c4edbba751b9..5b022217e545 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -1612,12 +1612,12 @@ bool Sema::CheckValueInitialization(QualType Type, SourceLocation Loc) { return CheckValueInitialization(AT->getElementType(), Loc); if (const RecordType *RT = Type->getAsRecordType()) { - if (const CXXRecordType *CXXRec = dyn_cast(RT)) { + if (CXXRecordDecl *ClassDecl = dyn_cast(RT->getDecl())) { // -- if T is a class type (clause 9) with a user-declared // constructor (12.1), then the default constructor for T is // called (and the initialization is ill-formed if T has no // accessible default constructor); - if (CXXRec->getDecl()->hasUserDeclaredConstructor()) + if (ClassDecl->hasUserDeclaredConstructor()) // FIXME: Eventually, we'll need to put the constructor decl // into the AST. return PerformInitializationByConstructor(Type, 0, 0, Loc, diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 00849a68812b..dd9c850d089e 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1232,13 +1232,14 @@ addAssociatedClassesAndNamespaces(QualType T, // member, if any; and its direct and indirect base // classes. Its associated namespaces are the namespaces in // which its associated classes are defined. - if (const CXXRecordType *ClassType - = dyn_cast_or_null(T->getAsRecordType())) { - addAssociatedClassesAndNamespaces(ClassType->getDecl(), - Context, AssociatedNamespaces, - AssociatedClasses); - return; - } + if (const RecordType *ClassType = T->getAsRecordType()) + if (CXXRecordDecl *ClassDecl + = dyn_cast(ClassType->getDecl())) { + addAssociatedClassesAndNamespaces(ClassDecl, Context, + AssociatedNamespaces, + AssociatedClasses); + return; + } // -- If T is an enumeration type, its associated namespace is // the namespace in which it is defined. If it is class diff --git a/clang/lib/Sema/SemaNamedCast.cpp b/clang/lib/Sema/SemaNamedCast.cpp index c5bee98a372e..166ed24d92e3 100644 --- a/clang/lib/Sema/SemaNamedCast.cpp +++ b/clang/lib/Sema/SemaNamedCast.cpp @@ -706,7 +706,7 @@ TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType, return TSC_Failed; } - if (const CXXRecordType *VBase = Paths.getDetectedVirtual()) { + if (const RecordType *VBase = Paths.getDetectedVirtual()) { Self.Diag(OpRange.getBegin(), diag::err_memptr_conv_via_virtual) << SrcClass << DestClass << QualType(VBase, 0) << OpRange; return TSC_Failed; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index c33389eda4cc..fe12eb74b9fd 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1233,7 +1233,7 @@ bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType) { return true; } - if (const CXXRecordType *VBase = Paths.getDetectedVirtual()) { + if (const RecordType *VBase = Paths.getDetectedVirtual()) { Diag(From->getExprLoc(), diag::err_memptr_conv_via_virtual) << FromClass << ToClass << QualType(VBase, 0) << From->getSourceRange(); @@ -1317,46 +1317,48 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, bool AllowExplicit) { OverloadCandidateSet CandidateSet; - if (const CXXRecordType *ToRecordType - = dyn_cast_or_null(ToType->getAsRecordType())) { - // C++ [over.match.ctor]p1: - // When objects of class type are direct-initialized (8.5), or - // copy-initialized from an expression of the same or a - // derived class type (8.5), overload resolution selects the - // constructor. [...] For copy-initialization, the candidate - // functions are all the converting constructors (12.3.1) of - // that class. The argument list is the expression-list within - // the parentheses of the initializer. - CXXRecordDecl *ToRecordDecl = ToRecordType->getDecl(); - DeclarationName ConstructorName - = Context.DeclarationNames.getCXXConstructorName( - Context.getCanonicalType(ToType).getUnqualifiedType()); - DeclContext::lookup_iterator Con, ConEnd; - for (llvm::tie(Con, ConEnd) = ToRecordDecl->lookup(ConstructorName); - Con != ConEnd; ++Con) { - CXXConstructorDecl *Constructor = cast(*Con); - if (Constructor->isConvertingConstructor()) - AddOverloadCandidate(Constructor, &From, 1, CandidateSet, - /*SuppressUserConversions=*/true); + if (const RecordType *ToRecordType = ToType->getAsRecordType()) { + if (CXXRecordDecl *ToRecordDecl + = dyn_cast(ToRecordType->getDecl())) { + // C++ [over.match.ctor]p1: + // When objects of class type are direct-initialized (8.5), or + // copy-initialized from an expression of the same or a + // derived class type (8.5), overload resolution selects the + // constructor. [...] For copy-initialization, the candidate + // functions are all the converting constructors (12.3.1) of + // that class. The argument list is the expression-list within + // the parentheses of the initializer. + DeclarationName ConstructorName + = Context.DeclarationNames.getCXXConstructorName( + Context.getCanonicalType(ToType).getUnqualifiedType()); + DeclContext::lookup_iterator Con, ConEnd; + for (llvm::tie(Con, ConEnd) = ToRecordDecl->lookup(ConstructorName); + Con != ConEnd; ++Con) { + CXXConstructorDecl *Constructor = cast(*Con); + if (Constructor->isConvertingConstructor()) + AddOverloadCandidate(Constructor, &From, 1, CandidateSet, + /*SuppressUserConversions=*/true); + } } } if (!AllowConversionFunctions) { // Don't allow any conversion functions to enter the overload set. - } else if (const CXXRecordType *FromRecordType - = dyn_cast_or_null( - From->getType()->getAsRecordType())) { - // Add all of the conversion functions as candidates. - // FIXME: Look for conversions in base classes! - CXXRecordDecl *FromRecordDecl = FromRecordType->getDecl(); - OverloadedFunctionDecl *Conversions - = FromRecordDecl->getConversionFunctions(); - for (OverloadedFunctionDecl::function_iterator Func - = Conversions->function_begin(); - Func != Conversions->function_end(); ++Func) { - CXXConversionDecl *Conv = cast(*Func); - if (AllowExplicit || !Conv->isExplicit()) - AddConversionCandidate(Conv, From, ToType, CandidateSet); + } else if (const RecordType *FromRecordType + = From->getType()->getAsRecordType()) { + if (CXXRecordDecl *FromRecordDecl + = dyn_cast(FromRecordType->getDecl())) { + // Add all of the conversion functions as candidates. + // FIXME: Look for conversions in base classes! + OverloadedFunctionDecl *Conversions + = FromRecordDecl->getConversionFunctions(); + for (OverloadedFunctionDecl::function_iterator Func + = Conversions->function_begin(); + Func != Conversions->function_end(); ++Func) { + CXXConversionDecl *Conv = cast(*Func); + if (AllowExplicit || !Conv->isExplicit()) + AddConversionCandidate(Conv, From, ToType, CandidateSet); + } } } diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index d2e8419d0b78..6b4346377764 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -254,14 +254,6 @@ TemplateTypeInstantiator::InstantiateRecordType(const RecordType *T, return QualType(); } -QualType -TemplateTypeInstantiator::InstantiateCXXRecordType(const CXXRecordType *T, - unsigned Quals) const { - // FIXME: Implement this - assert(false && "Cannot instantiate CXXRecordType yet"); - return QualType(); -} - QualType TemplateTypeInstantiator::InstantiateEnumType(const EnumType *T, unsigned Quals) const {