diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/DeclCXX.cpp | 22 | ||||
-rw-r--r-- | lib/AST/InheritViz.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 40 | ||||
-rw-r--r-- | lib/Sema/SemaInherit.cpp | 4 |
4 files changed, 40 insertions, 30 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 86db8532c8..8baf4196bf 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -26,14 +26,6 @@ CXXFieldDecl *CXXFieldDecl::Create(ASTContext &C, CXXRecordDecl *RD, return new (Mem) CXXFieldDecl(RD, L, Id, T, BW); } -CXXBaseSpecifier *CXXBaseSpecifier::Create(ASTContext &C, SourceRange R, bool V, - bool BC, AccessSpecifier A, QualType T) -{ - void *Mem = C.getAllocator().Allocate<CXXBaseSpecifier>(); - CXXBaseSpecifier* BS = new (Mem) CXXBaseSpecifier(R, V, BC, A, T); - return BS; -} - CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, CXXRecordDecl* PrevDecl) { @@ -44,11 +36,21 @@ CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, } CXXRecordDecl::~CXXRecordDecl() { - for (unsigned i = 0; i < NumBases; ++i) - delete Bases[i]; delete [] Bases; } +void +CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, + unsigned NumBases) { + if (this->Bases) + delete [] this->Bases; + + this->Bases = new CXXBaseSpecifier[NumBases]; + this->NumBases = NumBases; + for (unsigned i = 0; i < NumBases; ++i) + this->Bases[i] = *Bases[i]; +} + CXXMethodDecl * CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation L, IdentifierInfo *Id, diff --git a/lib/AST/InheritViz.cpp b/lib/AST/InheritViz.cpp index b817ed613f..bfd859f527 100644 --- a/lib/AST/InheritViz.cpp +++ b/lib/AST/InheritViz.cpp @@ -92,8 +92,8 @@ void InheritanceHierarchyWriter::WriteNode(QualType Type, bool FromVirtual) { // Display the base classes. const CXXRecordDecl *Decl = static_cast<const CXXRecordDecl *>(Type->getAsRecordType()->getDecl()); - for (unsigned idx = 0; idx < Decl->getNumBases(); ++idx) { - const CXXBaseSpecifier *Base = Decl->getBase(idx); + for (CXXRecordDecl::base_class_const_iterator Base = Decl->bases_begin(); + Base != Decl->bases_end(); ++Base) { QualType CanonBaseType = Context.getCanonicalType(Base->getType()); // If this is not virtual inheritance, bump the direct base diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index f17875b986..729bd7c35c 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -299,11 +299,8 @@ Sema::ActOnBaseSpecifier(DeclTy *classdecl, SourceRange SpecifierRange, } // Create the base specifier. - CXXBaseSpecifier *BS = CXXBaseSpecifier::Create(Context, SpecifierRange, - Virtual, - BaseType->isClassType(), - Access, BaseType); - return BS; + return new CXXBaseSpecifier(SpecifierRange, Virtual, + BaseType->isClassType(), Access, BaseType); } /// ActOnBaseSpecifiers - Attach the given base specifiers to the @@ -316,34 +313,45 @@ void Sema::ActOnBaseSpecifiers(DeclTy *ClassDecl, BaseTy **Bases, // Used to keep track of which base types we have already seen, so // that we can properly diagnose redundant direct base types. Note - // that the key is always the canonical type. + // that the key is always the unqualified canonical type of the base + // class. std::map<QualType, CXXBaseSpecifier*, QualTypeOrdering> KnownBaseTypes; // Copy non-redundant base specifiers into permanent storage. - CXXBaseSpecifier **InBaseSpecs = (CXXBaseSpecifier **)Bases; - CXXBaseSpecifier **StoredBaseSpecs = new CXXBaseSpecifier* [NumBases]; - unsigned outIdx = 0; - for (unsigned inIdx = 0; inIdx < NumBases; ++inIdx) { + CXXBaseSpecifier **BaseSpecs = (CXXBaseSpecifier **)Bases; + unsigned NumGoodBases = 0; + for (unsigned idx = 0; idx < NumBases; ++idx) { QualType NewBaseType - = Context.getCanonicalType(InBaseSpecs[inIdx]->getType()); + = Context.getCanonicalType(BaseSpecs[idx]->getType()); + NewBaseType = NewBaseType.getUnqualifiedType(); + if (KnownBaseTypes[NewBaseType]) { // C++ [class.mi]p3: // A class shall not be specified as a direct base class of a // derived class more than once. - Diag(InBaseSpecs[inIdx]->getSourceRange().getBegin(), + Diag(BaseSpecs[idx]->getSourceRange().getBegin(), diag::err_duplicate_base_class, KnownBaseTypes[NewBaseType]->getType().getAsString(), - InBaseSpecs[inIdx]->getSourceRange()); + BaseSpecs[idx]->getSourceRange()); + + // Delete the duplicate base class specifier; we're going to + // overwrite its pointer later. + delete BaseSpecs[idx]; } else { // Okay, add this new base class. - KnownBaseTypes[NewBaseType] = InBaseSpecs[inIdx]; - StoredBaseSpecs[outIdx++] = InBaseSpecs[inIdx]; + KnownBaseTypes[NewBaseType] = BaseSpecs[idx]; + BaseSpecs[NumGoodBases++] = BaseSpecs[idx]; } } // Attach the remaining base class specifiers to the derived class. CXXRecordDecl *Decl = (CXXRecordDecl*)ClassDecl; - Decl->setBases(StoredBaseSpecs, outIdx); + Decl->setBases(BaseSpecs, NumGoodBases); + + // Delete the remaining (good) base class specifiers, since their + // data has been copied into the CXXRecordDecl. + for (unsigned idx = 0; idx < NumGoodBases; ++idx) + delete BaseSpecs[idx]; } //===----------------------------------------------------------------------===// diff --git a/lib/Sema/SemaInherit.cpp b/lib/Sema/SemaInherit.cpp index 022c8043d0..6890dbfc64 100644 --- a/lib/Sema/SemaInherit.cpp +++ b/lib/Sema/SemaInherit.cpp @@ -39,8 +39,8 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base) if (const RecordType *DerivedType = Derived->getAsRecordType()) { const CXXRecordDecl *Decl = static_cast<const CXXRecordDecl *>(DerivedType->getDecl()); - for (unsigned idx = 0; idx < Decl->getNumBases(); ++idx) { - const CXXBaseSpecifier *BaseSpec = Decl->getBase(idx); + for (CXXRecordDecl::base_class_const_iterator BaseSpec = Decl->bases_begin(); + BaseSpec != Decl->bases_end(); ++BaseSpec) { if (Context.getCanonicalType(BaseSpec->getType()) == Base || IsDerivedFrom(BaseSpec->getType(), Base)) return true; |