diff options
| author | John McCall <rjmccall@apple.com> | 2010-08-07 06:22:56 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2010-08-07 06:22:56 +0000 |
| commit | cf1421650953d47ae5089198c0fdc3f3263fa300 (patch) | |
| tree | f34c6179794cc5d613d8f27e6877babc0c4047bd /clang/lib | |
| parent | a5a3ff586f1be7b9edc51ce4ee0ba03c9be300da (diff) | |
| download | bcm5719-llvm-cf1421650953d47ae5089198c0fdc3f3263fa300.tar.gz bcm5719-llvm-cf1421650953d47ae5089198c0fdc3f3263fa300.zip | |
Store inheritance paths after CastExprs instead of inside them.
This takes some trickery since CastExpr has subclasses (and indeed,
is abstract).
Also, smoosh the CastKind into the bitfield from Expr.
Drops two words of storage from Expr in the common case of expressions
which don't need inheritance paths. Avoids a separate allocation and
another word of overhead in cases needing inheritance paths. Also has
the advantage of not leaking memory, since destructors for AST nodes are
never run.
llvm-svn: 110507
Diffstat (limited to 'clang/lib')
25 files changed, 363 insertions, 175 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index b5fa362adb4..5e8586f2a06 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -123,6 +123,8 @@ namespace { Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E); Expr *VisitImplicitCastExpr(ImplicitCastExpr *E); Expr *VisitCStyleCastExpr(CStyleCastExpr *E); + + bool ImportCasePath(CastExpr *E, CXXCastPath &Path); }; } @@ -2886,6 +2888,13 @@ Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) { Importer.Import(E->getOperatorLoc())); } +bool ImportCastPath(CastExpr *E, CXXCastPath &Path) { + if (E->path_empty()) return false; + + // TODO: import cast paths + return true; +} + Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -2894,13 +2903,13 @@ Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) { Expr *SubExpr = Importer.Import(E->getSubExpr()); if (!SubExpr) return 0; - - // FIXME: Initialize the base path. - assert(E->getBasePath().empty() && "FIXME: Must copy base path!"); - CXXBaseSpecifierArray BasePath; - return new (Importer.getToContext()) ImplicitCastExpr(T, E->getCastKind(), - SubExpr, BasePath, - E->getCategory()); + + CXXCastPath BasePath; + if (ImportCastPath(E, BasePath)) + return 0; + + return ImplicitCastExpr::Create(Importer.getToContext(), T, E->getCastKind(), + SubExpr, &BasePath, E->getCategory()); } Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) { @@ -2916,13 +2925,14 @@ Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) { if (!TInfo && E->getTypeInfoAsWritten()) return 0; - // FIXME: Initialize the base path. - assert(E->getBasePath().empty() && "FIXME: Must copy base path!"); - CXXBaseSpecifierArray BasePath; - return new (Importer.getToContext()) CStyleCastExpr(T, E->getCastKind(), - SubExpr, BasePath, TInfo, - Importer.Import(E->getLParenLoc()), - Importer.Import(E->getRParenLoc())); + CXXCastPath BasePath; + if (ImportCastPath(E, BasePath)) + return 0; + + return CStyleCastExpr::Create(Importer.getToContext(), T, E->getCastKind(), + SubExpr, &BasePath, TInfo, + Importer.Import(E->getLParenLoc()), + Importer.Import(E->getRParenLoc())); } ASTImporter::ASTImporter(Diagnostic &Diags, diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 7642c0de2cb..d85162a3426 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -747,6 +747,66 @@ Expr *CastExpr::getSubExprAsWritten() { return SubExpr; } +CXXBaseSpecifier **CastExpr::path_buffer() { + switch (getStmtClass()) { +#define ABSTRACT_STMT(x) +#define CASTEXPR(Type, Base) \ + case Stmt::Type##Class: \ + return reinterpret_cast<CXXBaseSpecifier**>(static_cast<Type*>(this)+1); +#define STMT(Type, Base) +#include "clang/AST/StmtNodes.inc" + default: + llvm_unreachable("non-cast expressions not possible here"); + return 0; + } +} + +void CastExpr::setCastPath(const CXXCastPath &Path) { + assert(Path.size() == path_size()); + memcpy(path_buffer(), Path.data(), Path.size() * sizeof(CXXBaseSpecifier*)); +} + +ImplicitCastExpr *ImplicitCastExpr::Create(ASTContext &C, QualType T, + CastKind Kind, Expr *Operand, + const CXXCastPath *BasePath, + ResultCategory Cat) { + unsigned PathSize = (BasePath ? BasePath->size() : 0); + void *Buffer = + C.Allocate(sizeof(ImplicitCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); + ImplicitCastExpr *E = + new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, Cat); + if (PathSize) E->setCastPath(*BasePath); + return E; +} + +ImplicitCastExpr *ImplicitCastExpr::CreateEmpty(ASTContext &C, + unsigned PathSize) { + void *Buffer = + C.Allocate(sizeof(ImplicitCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); + return new (Buffer) ImplicitCastExpr(EmptyShell(), PathSize); +} + + +CStyleCastExpr *CStyleCastExpr::Create(ASTContext &C, QualType T, + CastKind K, Expr *Op, + const CXXCastPath *BasePath, + TypeSourceInfo *WrittenTy, + SourceLocation L, SourceLocation R) { + unsigned PathSize = (BasePath ? BasePath->size() : 0); + void *Buffer = + C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); + CStyleCastExpr *E = + new (Buffer) CStyleCastExpr(T, K, Op, PathSize, WrittenTy, L, R); + if (PathSize) E->setCastPath(*BasePath); + return E; +} + +CStyleCastExpr *CStyleCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) { + void *Buffer = + C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); + return new (Buffer) CStyleCastExpr(EmptyShell(), PathSize); +} + /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it /// corresponds to, e.g. "<<=". const char *BinaryOperator::getOpcodeStr(Opcode Op) { diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 7c2a8934a59..490783316ed 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -460,6 +460,100 @@ const char *CXXNamedCastExpr::getCastName() const { } } +CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T, + CastKind K, Expr *Op, + const CXXCastPath *BasePath, + TypeSourceInfo *WrittenTy, + SourceLocation L) { + unsigned PathSize = (BasePath ? BasePath->size() : 0); + void *Buffer = C.Allocate(sizeof(CXXStaticCastExpr) + + PathSize * sizeof(CXXBaseSpecifier*)); + CXXStaticCastExpr *E = + new (Buffer) CXXStaticCastExpr(T, K, Op, PathSize, WrittenTy, L); + if (PathSize) E->setCastPath(*BasePath); + return E; +} + +CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(ASTContext &C, + unsigned PathSize) { + void *Buffer = + C.Allocate(sizeof(CXXStaticCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); + return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize); +} + +CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T, + CastKind K, Expr *Op, + const CXXCastPath *BasePath, + TypeSourceInfo *WrittenTy, + SourceLocation L) { + unsigned PathSize = (BasePath ? BasePath->size() : 0); + void *Buffer = C.Allocate(sizeof(CXXDynamicCastExpr) + + PathSize * sizeof(CXXBaseSpecifier*)); + CXXDynamicCastExpr *E = + new (Buffer) CXXDynamicCastExpr(T, K, Op, PathSize, WrittenTy, L); + if (PathSize) E->setCastPath(*BasePath); + return E; +} + +CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(ASTContext &C, + unsigned PathSize) { + void *Buffer = + C.Allocate(sizeof(CXXDynamicCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); + return new (Buffer) CXXDynamicCastExpr(EmptyShell(), PathSize); +} + +CXXReinterpretCastExpr * +CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, CastKind K, Expr *Op, + const CXXCastPath *BasePath, + TypeSourceInfo *WrittenTy, SourceLocation L) { + unsigned PathSize = (BasePath ? BasePath->size() : 0); + void *Buffer = + C.Allocate(sizeof(CXXReinterpretCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); + CXXReinterpretCastExpr *E = + new (Buffer) CXXReinterpretCastExpr(T, K, Op, PathSize, WrittenTy, L); + if (PathSize) E->setCastPath(*BasePath); + return E; +} + +CXXReinterpretCastExpr * +CXXReinterpretCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) { + void *Buffer = C.Allocate(sizeof(CXXReinterpretCastExpr) + + PathSize * sizeof(CXXBaseSpecifier*)); + return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize); +} + +CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T, Expr *Op, + TypeSourceInfo *WrittenTy, + SourceLocation L) { + return new (C) CXXConstCastExpr(T, Op, WrittenTy, L); +} + +CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) { + return new (C) CXXConstCastExpr(EmptyShell()); +} + +CXXFunctionalCastExpr * +CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, + TypeSourceInfo *Written, SourceLocation L, + CastKind K, Expr *Op, const CXXCastPath *BasePath, + SourceLocation R) { + unsigned PathSize = (BasePath ? BasePath->size() : 0); + void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr) + + PathSize * sizeof(CXXBaseSpecifier*)); + CXXFunctionalCastExpr *E = + new (Buffer) CXXFunctionalCastExpr(T, Written, L, K, Op, PathSize, R); + if (PathSize) E->setCastPath(*BasePath); + return E; +} + +CXXFunctionalCastExpr * +CXXFunctionalCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) { + void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr) + + PathSize * sizeof(CXXBaseSpecifier*)); + return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize); +} + + CXXDefaultArgExpr * CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc, ParmVarDecl *Param, Expr *SubExpr) { diff --git a/clang/lib/AST/StmtDumper.cpp b/clang/lib/AST/StmtDumper.cpp index c878a55e0e6..f8f149541e1 100644 --- a/clang/lib/AST/StmtDumper.cpp +++ b/clang/lib/AST/StmtDumper.cpp @@ -308,13 +308,13 @@ void StmtDumper::VisitExpr(Expr *Node) { } static void DumpBasePath(llvm::raw_ostream &OS, CastExpr *Node) { - if (Node->getBasePath().empty()) + if (Node->path_empty()) return; OS << " ("; bool First = true; - for (CXXBaseSpecifierArray::iterator I = Node->getBasePath().begin(), - E = Node->getBasePath().end(); I != E; ++I) { + for (CastExpr::path_iterator + I = Node->path_begin(), E = Node->path_end(); I != E; ++I) { const CXXBaseSpecifier *Base = *I; if (!First) OS << " -> "; diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 5bac172b0ee..9ae9b3a8003 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -22,13 +22,13 @@ using namespace CodeGen; static uint64_t ComputeNonVirtualBaseClassOffset(ASTContext &Context, const CXXRecordDecl *DerivedClass, - CXXBaseSpecifierArray::iterator Start, - CXXBaseSpecifierArray::iterator End) { + CastExpr::path_const_iterator Start, + CastExpr::path_const_iterator End) { uint64_t Offset = 0; const CXXRecordDecl *RD = DerivedClass; - for (CXXBaseSpecifierArray::iterator I = Start; I != End; ++I) { + for (CastExpr::path_const_iterator I = Start; I != End; ++I) { const CXXBaseSpecifier *Base = *I; assert(!Base->isVirtual() && "Should not see virtual bases here!"); @@ -50,12 +50,13 @@ ComputeNonVirtualBaseClassOffset(ASTContext &Context, llvm::Constant * CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, - const CXXBaseSpecifierArray &BasePath) { - assert(!BasePath.empty() && "Base path should not be empty!"); + CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd) { + assert(PathBegin != PathEnd && "Base path should not be empty!"); uint64_t Offset = - ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, - BasePath.begin(), BasePath.end()); + ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, + PathBegin, PathEnd); if (!Offset) return 0; @@ -131,11 +132,12 @@ ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, llvm::Value *ThisPtr, llvm::Value * CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, const CXXRecordDecl *Derived, - const CXXBaseSpecifierArray &BasePath, + CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd, bool NullCheckValue) { - assert(!BasePath.empty() && "Base path should not be empty!"); + assert(PathBegin != PathEnd && "Base path should not be empty!"); - CXXBaseSpecifierArray::iterator Start = BasePath.begin(); + CastExpr::path_const_iterator Start = PathBegin; const CXXRecordDecl *VBase = 0; // Get the virtual base. @@ -147,11 +149,11 @@ CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, uint64_t NonVirtualOffset = ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived, - Start, BasePath.end()); + Start, PathEnd); // Get the base pointer type. const llvm::Type *BasePtrTy = - ConvertType((BasePath.end()[-1])->getType())->getPointerTo(); + ConvertType((PathEnd[-1])->getType())->getPointerTo(); if (!NonVirtualOffset && !VBase) { // Just cast back. @@ -206,16 +208,17 @@ CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, llvm::Value * CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, const CXXRecordDecl *Derived, - const CXXBaseSpecifierArray &BasePath, + CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd, bool NullCheckValue) { - assert(!BasePath.empty() && "Base path should not be empty!"); + assert(PathBegin != PathEnd && "Base path should not be empty!"); QualType DerivedTy = getContext().getCanonicalType(getContext().getTagDeclType(Derived)); const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(); llvm::Value *NonVirtualOffset = - CGM.GetNonVirtualBaseClassOffset(Derived, BasePath); + CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd); if (!NonVirtualOffset) { // No offset, we can just cast back. diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 173aadc91a0..9424776898b 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -142,7 +142,7 @@ struct SubobjectAdjustment { union { struct { - const CXXBaseSpecifierArray *BasePath; + const CastExpr *BasePath; const CXXRecordDecl *DerivedClass; } DerivedToBase; @@ -152,7 +152,7 @@ struct SubobjectAdjustment { } Field; }; - SubobjectAdjustment(const CXXBaseSpecifierArray *BasePath, + SubobjectAdjustment(const CastExpr *BasePath, const CXXRecordDecl *DerivedClass) : Kind(DerivedToBaseAdjustment) { @@ -236,8 +236,7 @@ EmitExprForReferenceBinding(CodeGenFunction& CGF, const Expr* E, E = CE->getSubExpr(); CXXRecordDecl *Derived = cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl()); - Adjustments.push_back(SubobjectAdjustment(&CE->getBasePath(), - Derived)); + Adjustments.push_back(SubobjectAdjustment(CE, Derived)); continue; } @@ -291,7 +290,8 @@ EmitExprForReferenceBinding(CodeGenFunction& CGF, const Expr* E, Object = CGF.GetAddressOfBaseClass(Object, Adjustment.DerivedToBase.DerivedClass, - *Adjustment.DerivedToBase.BasePath, + Adjustment.DerivedToBase.BasePath->path_begin(), + Adjustment.DerivedToBase.BasePath->path_end(), /*NullCheckValue=*/false); break; @@ -1820,7 +1820,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { // Perform the derived-to-base conversion llvm::Value *Base = GetAddressOfBaseClass(This, DerivedClassDecl, - E->getBasePath(), /*NullCheckValue=*/false); + E->path_begin(), E->path_end(), + /*NullCheckValue=*/false); return LValue::MakeAddr(Base, MakeQualifiers(E->getType())); } @@ -1836,7 +1837,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { // Perform the base-to-derived conversion llvm::Value *Derived = GetAddressOfDerivedClass(LV.getAddress(), DerivedClassDecl, - E->getBasePath(),/*NullCheckValue=*/false); + E->path_begin(), E->path_end(), + /*NullCheckValue=*/false); return LValue::MakeAddr(Derived, MakeQualifiers(E->getType())); } diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 219a5f91532..0014d8291e8 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -346,7 +346,9 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { std::swap(DerivedDecl, BaseDecl); if (llvm::Constant *Adj = - CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, E->getBasePath())) { + CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, + E->path_begin(), + E->path_end())) { if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer) SrcAdj = Builder.CreateSub(SrcAdj, Adj, "adj"); else diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 4831b5dabe0..61d4ac26cf3 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -572,7 +572,9 @@ public: // Check if we need to update the adjustment. if (llvm::Constant *Offset = - CGM.GetNonVirtualBaseClassOffset(DerivedClass, E->getBasePath())) { + CGM.GetNonVirtualBaseClassOffset(DerivedClass, + E->path_begin(), + E->path_end())) { llvm::Constant *Values[2]; Values[0] = CS->getOperand(0); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index d2ff5623cbe..dbafd2bffe8 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -949,7 +949,7 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { DestTy->getCXXRecordDeclForPointerType(); return CGF.GetAddressOfDerivedClass(Visit(E), DerivedClassDecl, - CE->getBasePath(), + CE->path_begin(), CE->path_end(), ShouldNullCheckClassCastValue(CE)); } case CastExpr::CK_UncheckedDerivedToBase: @@ -960,7 +960,7 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { cast<CXXRecordDecl>(DerivedClassTy->getDecl()); return CGF.GetAddressOfBaseClass(Visit(E), DerivedClassDecl, - CE->getBasePath(), + CE->path_begin(), CE->path_end(), ShouldNullCheckClassCastValue(CE)); } case CastExpr::CK_Dynamic: { @@ -1011,7 +1011,9 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { std::swap(DerivedDecl, BaseDecl); if (llvm::Constant *Adj = - CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, CE->getBasePath())){ + CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, + CE->path_begin(), + CE->path_end())) { if (CE->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer) Src = Builder.CreateNSWSub(Src, Adj, "adj"); else diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 62a118cb02e..255898b0aa7 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -403,8 +403,8 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, // Objective-C pointer types, we can always bit cast the RHS in these cases. if (getContext().getCanonicalType(Ivar->getType()) != getContext().getCanonicalType(ArgDecl->getType())) { - ImplicitCastExpr ArgCasted(Ivar->getType(), CastExpr::CK_BitCast, &Arg, - CXXBaseSpecifierArray(), + ImplicitCastExpr ArgCasted(ImplicitCastExpr::OnStack, + Ivar->getType(), CastExpr::CK_BitCast, &Arg, ImplicitCastExpr::RValue); BinaryOperator Assign(&IvarRef, &ArgCasted, BinaryOperator::Assign, Ivar->getType(), Loc); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 5934da0ef91..af7e0696f49 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1074,12 +1074,14 @@ public: /// load of 'this' and returns address of the base class. llvm::Value *GetAddressOfBaseClass(llvm::Value *Value, const CXXRecordDecl *Derived, - const CXXBaseSpecifierArray &BasePath, + CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd, bool NullCheckValue); llvm::Value *GetAddressOfDerivedClass(llvm::Value *Value, const CXXRecordDecl *Derived, - const CXXBaseSpecifierArray &BasePath, + CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd, bool NullCheckValue); llvm::Value *GetVirtualBaseClassOffset(llvm::Value *This, diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index a4d8368d4d9..c7578788a57 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -315,7 +315,8 @@ public: /// a class. Returns null if the offset is 0. llvm::Constant * GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, - const CXXBaseSpecifierArray &BasePath); + CastExpr::path_const_iterator PathBegin, + CastExpr::path_const_iterator PathEnd); /// GetStringForStringLiteral - Return the appropriate bytes for a string /// literal, properly padded to match the literal type. If only the address of diff --git a/clang/lib/Frontend/PCHReaderStmt.cpp b/clang/lib/Frontend/PCHReaderStmt.cpp index 6a11529b02c..d5d527d32e3 100644 --- a/clang/lib/Frontend/PCHReaderStmt.cpp +++ b/clang/lib/Frontend/PCHReaderStmt.cpp @@ -559,14 +559,15 @@ void PCHStmtReader::VisitObjCIsaExpr(ObjCIsaExpr *E) { void PCHStmtReader::VisitCastExpr(CastExpr *E) { VisitExpr(E); + unsigned NumBaseSpecs = Record[Idx++]; + assert(NumBaseSpecs == E->path_size()); E->setSubExpr(Reader.ReadSubExpr()); E->setCastKind((CastExpr::CastKind)Record[Idx++]); - CXXBaseSpecifierArray &BasePath = E->getBasePath(); - unsigned NumBaseSpecs = Record[Idx++]; + CastExpr::path_iterator BaseI = E->path_begin(); while (NumBaseSpecs--) { CXXBaseSpecifier *BaseSpec = new (*Reader.getContext()) CXXBaseSpecifier; *BaseSpec = Reader.ReadCXXBaseSpecifier(DeclsCursor, Record, Idx); - BasePath.push_back(BaseSpec); + *BaseI++ = BaseSpec; } } @@ -1495,11 +1496,13 @@ Stmt *PCHReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { break; case pch::EXPR_IMPLICIT_CAST: - S = new (Context) ImplicitCastExpr(Empty); + S = ImplicitCastExpr::CreateEmpty(*Context, + /*PathSize*/ Record[PCHStmtReader::NumExprFields]); break; case pch::EXPR_CSTYLE_CAST: - S = new (Context) CStyleCastExpr(Empty); + S = CStyleCastExpr::CreateEmpty(*Context, + /*PathSize*/ Record[PCHStmtReader::NumExprFields]); break; case pch::EXPR_COMPOUND_LITERAL: @@ -1638,23 +1641,27 @@ Stmt *PCHReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { break; case pch::EXPR_CXX_STATIC_CAST: - S = new (Context) CXXStaticCastExpr(Empty); + S = CXXStaticCastExpr::CreateEmpty(*Context, + /*PathSize*/ Record[PCHStmtReader::NumExprFields]); break; case pch::EXPR_CXX_DYNAMIC_CAST: - S = new (Context) CXXDynamicCastExpr(Empty); + S = CXXDynamicCastExpr::CreateEmpty(*Context, + /*PathSize*/ Record[PCHStmtReader::NumExprFields]); break; case pch::EXPR_CXX_REINTERPRET_CAST: - S = new (Context) CXXReinterpretCastExpr(Empty); + S = CXXReinterpretCastExpr::CreateEmpty(*Context, + /*PathSize*/ Record[PCHStmtReader::NumExprFields]); break; case pch::EXPR_CXX_CONST_CAST: - S = new (Context) CXXConstCastExpr(Empty); + S = CXXConstCastExpr::CreateEmpty(*Context); break; case pch::EXPR_CXX_FUNCTIONAL_CAST: - S = new (Context) CXXFunctionalCastExpr(Empty); + S = CXXFunctionalCastExpr::CreateEmpty(*Context, + /*PathSize*/ Record[PCHStmtReader::NumExprFields]); break; case pch::EXPR_CXX_BOOL_LITERAL: diff --git a/clang/lib/Frontend/PCHWriterStmt.cpp b/clang/lib/Frontend/PCHWriterStmt.cpp index eee409b047d..3a65785b0f7 100644 --- a/clang/lib/Frontend/PCHWriterStmt.cpp +++ b/clang/lib/Frontend/PCHWriterStmt.cpp @@ -567,13 +567,13 @@ void PCHStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) { void PCHStmtWriter::VisitCastExpr(CastExpr *E) { VisitExpr(E); + Record.push_back(E->path_size()); Writer.AddStmt(E->getSubExpr()); Record.push_back(E->getCastKind()); // FIXME: stable encoding - CXXBaseSpecifierArray &BasePath = E->getBasePath(); - Record.push_back(BasePath.size()); - for (CXXBaseSpecifierArray::iterator I = BasePath.begin(), E = BasePath.end(); - I != E; ++I) - Writer.AddCXXBaseSpecifier(**I, Record); + + for (CastExpr::path_iterator + PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI) + Writer.AddCXXBaseSpecifier(**PI, Record); } void PCHStmtWriter::VisitBinaryOperator(BinaryOperator *E) { diff --git a/clang/lib/Rewrite/RewriteObjC.cpp b/clang/lib/Rewrite/RewriteObjC.cpp index 9c52aa5f52c..45c707fe29f 100644 --- a/clang/lib/Rewrite/RewriteObjC.cpp +++ b/clang/lib/Rewrite/RewriteObjC.cpp @@ -459,8 +459,8 @@ namespace { CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty, CastExpr::CastKind Kind, Expr *E) { TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation()); - return new (Ctx) CStyleCastExpr(Ty, Kind, E, CXXBaseSpecifierArray(), TInfo, - SourceLocation(), SourceLocation()); + return CStyleCastExpr::Create(*Ctx, Ty, Kind, E, 0, TInfo, + SourceLocation(), SourceLocation()); } } @@ -2106,9 +2106,8 @@ CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl( // Now, we cast the reference to a pointer to the objc_msgSend type. QualType pToFunc = Context->getPointerType(msgSendType); ImplicitCastExpr *ICE = - new (Context) ImplicitCastExpr(pToFunc, CastExpr::CK_Unknown, - DRE, CXXBaseSpecifierArray(), - ImplicitCastExpr::RValue); + ImplicitCastExpr::Create(*Context, pToFunc, CastExpr::CK_Unknown, + DRE, 0, ImplicitCastExpr::RValue); const FunctionType *FT = msgSendType->getAs<FunctionType>(); diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 244538147e5..aeb4db987db 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -159,7 +159,7 @@ Sema::~Sema() { void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty, CastExpr::CastKind Kind, ImplicitCastExpr::ResultCategory Category, - CXXBaseSpecifierArray BasePath) { + const CXXCastPath *BasePath) { QualType ExprTy = Context.getCanonicalType(Expr->getType()); QualType TypeTy = Context.getCanonicalType(Ty); @@ -178,7 +178,7 @@ void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty, // If this is a derived-to-base cast to a through a virtual base, we // need a vtable. if (Kind == CastExpr::CK_DerivedToBase && - BasePathInvolvesVirtualBase(BasePath)) { + BasePathInvolvesVirtualBase(*BasePath)) { QualType T = Expr->getType(); if (const PointerType *Pointer = T->getAs<PointerType>()) T = Pointer->getPointeeType(); @@ -188,14 +188,14 @@ void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty, } if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr)) { - if (ImpCast->getCastKind() == Kind && BasePath.empty()) { + if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) { ImpCast->setType(Ty); ImpCast->setCategory(Category); return; } } - Expr = new (Context) ImplicitCastExpr(Ty, Kind, Expr, BasePath, Category); + Expr = ImplicitCastExpr::Create(Context, Ty, Kind, Expr, BasePath, Category); } ImplicitCastExpr::ResultCategory Sema::CastCategory(Expr *E) { diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index eb84417c33a..3570a774b36 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1179,14 +1179,14 @@ public: bool CheckPointerConversion(Expr *From, QualType ToType, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray& BasePath, + CXXCastPath& BasePath, bool IgnoreBaseAccess); bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType, bool InOverloadResolution, QualType &ConvertedType); bool CheckMemberPointerConversion(Expr *From, QualType ToType, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath, + CXXCastPath &BasePath, bool IgnoreBaseAccess); bool IsQualificationConversion(QualType FromType, QualType ToType); OverloadingResult IsUserDefinedConversion(Expr *From, QualType ToType, @@ -2831,21 +2831,20 @@ public: bool IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths); // FIXME: I don't like this name. - void BuildBasePathArray(const CXXBasePaths &Paths, - CXXBaseSpecifierArray &BasePath); + void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath); - bool BasePathInvolvesVirtualBase(const CXXBaseSpecifierArray &BasePath); + bool BasePathInvolvesVirtualBase(const CXXCastPath &BasePath); bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, SourceLocation Loc, SourceRange Range, - CXXBaseSpecifierArray *BasePath = 0, + CXXCastPath *BasePath = 0, bool IgnoreAccess = false); bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, unsigned InaccessibleBaseID, unsigned AmbigiousBaseConvID, SourceLocation Loc, SourceRange Range, DeclarationName Name, - CXXBaseSpecifierArray *BasePath); + CXXCastPath *BasePath); std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths); @@ -4257,8 +4256,7 @@ public: void ImpCastExprToType(Expr *&Expr, QualType Type, CastExpr::CastKind Kind, ImplicitCastExpr::ResultCategory Category = ImplicitCastExpr::RValue, - CXXBaseSpecifierArray BasePath = - CXXBaseSpecifierArray()); + const CXXCastPath *BasePath = 0); // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts // functions and arrays to their respective pointers (C99 6.3.2.1). @@ -4524,7 +4522,7 @@ public: /// CheckCastTypes - Check type constraints for casting between types under /// C semantics, or forward to CXXCheckCStyleCast in C++. bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr, - CastExpr::CastKind &Kind, CXXBaseSpecifierArray &BasePath, + CastExpr::CastKind &Kind, CXXCastPath &BasePath, bool FunctionalStyle = false); // CheckVectorCast - check type constraints for vectors. @@ -4545,8 +4543,7 @@ public: /// CXXCheckCStyleCast - Check constraints of a C-style or function-style /// cast under C++ semantics. bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr, - CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath, + CastExpr::CastKind &Kind, CXXCastPath &BasePath, bool FunctionalStyle); /// CheckMessageArgumentTypes - Check types in an Obj-C message send. diff --git a/clang/lib/Sema/SemaCXXCast.cpp b/clang/lib/Sema/SemaCXXCast.cpp index 519d5692a3c..53352661da5 100644 --- a/clang/lib/Sema/SemaCXXCast.cpp +++ b/clang/lib/Sema/SemaCXXCast.cpp @@ -47,12 +47,12 @@ static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, const SourceRange &OpRange, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath); + CXXCastPath &BasePath); static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, const SourceRange &OpRange, const SourceRange &DestRange, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath); + CXXCastPath &BasePath); static bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType); @@ -74,27 +74,27 @@ static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, const SourceRange &OpRange, unsigned &msg, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath); + CXXCastPath &BasePath); static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType, bool CStyle, const SourceRange &OpRange, unsigned &msg, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath); + CXXCastPath &BasePath); static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, bool CStyle, const SourceRange &OpRange, QualType OrigSrcType, QualType OrigDestType, unsigned &msg, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath); + CXXCastPath &BasePath); static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType, QualType DestType,bool CStyle, const SourceRange &OpRange, unsigned &msg, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath); + CXXCastPath &BasePath); static TryCastResult TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType, bool CStyle, @@ -106,7 +106,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr, const SourceRange &OpRange, unsigned &msg, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath); + CXXCastPath &BasePath); static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, unsigned &msg); static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, @@ -153,39 +153,39 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, case tok::kw_const_cast: if (!TypeDependent) CheckConstCast(*this, Ex, DestType, OpRange, DestRange); - return Owned(new (Context) CXXConstCastExpr( + return Owned(CXXConstCastExpr::Create(Context, DestType.getNonLValueExprType(Context), - Ex, DestTInfo, OpLoc)); + Ex, DestTInfo, OpLoc)); case tok::kw_dynamic_cast: { CastExpr::CastKind Kind = CastExpr::CK_Unknown; - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (!TypeDependent) CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange, Kind, BasePath); - return Owned(new (Context)CXXDynamicCastExpr( + return Owned(CXXDynamicCastExpr::Create(Context, DestType.getNonLValueExprType(Context), - Kind, Ex, BasePath, DestTInfo, - OpLoc)); + Kind, Ex, &BasePath, DestTInfo, + OpLoc)); } case tok::kw_reinterpret_cast: { CastExpr::CastKind Kind = CastExpr::CK_Unknown; if (!TypeDependent) CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange, Kind); - return Owned(new (Context) CXXReinterpretCastExpr( + return Owned(CXXReinterpretCastExpr::Create(Context, DestType.getNonLValueExprType(Context), - Kind, Ex, CXXBaseSpecifierArray(), + Kind, Ex, 0, DestTInfo, OpLoc)); } case tok::kw_static_cast: { CastExpr::CastKind Kind = CastExpr::CK_Unknown; - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (!TypeDependent) CheckStaticCast(*this, Ex, DestType, OpRange, Kind, BasePath); - return Owned(new (Context) CXXStaticCastExpr( + return Owned(CXXStaticCastExpr::Create(Context, DestType.getNonLValueExprType(Context), - Kind, Ex, BasePath, - DestTInfo, OpLoc)); + Kind, Ex, &BasePath, + DestTInfo, OpLoc)); } } @@ -308,7 +308,7 @@ static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, const SourceRange &OpRange, const SourceRange &DestRange, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath) { + CXXCastPath &BasePath) { QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType(); DestType = Self.Context.getCanonicalType(DestType); @@ -477,7 +477,7 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, const SourceRange &OpRange, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath) { + CXXCastPath &BasePath) { // This test is outside everything else because it's the only case where // a non-lvalue-reference target type does not lead to decay. // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". @@ -503,7 +503,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, bool CStyle, const SourceRange &OpRange, unsigned &msg, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath) { + CXXCastPath &BasePath) { // The order the tests is not entirely arbitrary. There is one conversion // that can be handled in two different ways. Given: // struct A {}; @@ -664,7 +664,7 @@ TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, const SourceRange &OpRange, unsigned &msg, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath) { + CXXCastPath &BasePath) { // C++ 5.2.9p5: An lvalue of type "cv1 B", where B is a class type, can be // cast to type "reference to cv2 D", where D is a class derived from B, // if a valid standard conversion from "pointer to D" to "pointer to B" @@ -699,7 +699,7 @@ TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType, bool CStyle, const SourceRange &OpRange, unsigned &msg, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath) { + CXXCastPath &BasePath) { // C++ 5.2.9p8: An rvalue of type "pointer to cv1 B", where B is a class // type, can be converted to an rvalue of type "pointer to cv2 D", where D // is a class derived from B, if a valid standard conversion from "pointer @@ -733,7 +733,7 @@ TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, bool CStyle, const SourceRange &OpRange, QualType OrigSrcType, QualType OrigDestType, unsigned &msg, - CastExpr::CastKind &Kind, CXXBaseSpecifierArray &BasePath) { + CastExpr::CastKind &Kind, CXXCastPath &BasePath) { // We can only work with complete types. But don't complain if it doesn't work if (Self.RequireCompleteType(OpRange.getBegin(), SrcType, Self.PDiag(0)) || Self.RequireCompleteType(OpRange.getBegin(), DestType, Self.PDiag(0))) @@ -841,7 +841,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType, QualType DestType, bool CStyle, const SourceRange &OpRange, unsigned &msg, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath) { + CXXCastPath &BasePath) { const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>(); if (!DestMemPtr) return TC_NotApplicable; @@ -1254,7 +1254,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, bool Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath, + CXXCastPath &BasePath, bool FunctionalStyle) { // This test is outside everything else because it's the only case where // a non-lvalue-reference target type does not lead to decay. diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 0fcc0a75594..e8223668425 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -524,9 +524,9 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) { cast<FunctionDecl>(LazilyCreateBuiltin(NewBuiltinII, NewBuiltinID, TUScope, false, DRE->getLocStart())); - // The first argument is by definition correct, we use it's type as the type - // of the entire operation. Walk the remaining arguments promoting them to - // the deduced value type. + // The first argument --- the pointer --- has a fixed type; we + // deduce the types of the rest of the arguments accordingly. Walk + // the remaining arguments, converting them to the deduced value type. for (unsigned i = 0; i != NumFixed; ++i) { Expr *Arg = TheCall->getArg(i+1); @@ -541,7 +541,7 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) { // GCC does an implicit conversion to the pointer or integer ValType. This // can fail in some cases (1i -> int**), check for this error case now. CastExpr::CastKind Kind = CastExpr::CK_Unknown; - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, BasePath)) return ExprError(); @@ -551,7 +551,7 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) { // pass in 42. The 42 gets converted to char. This is even more strange // for things like 45.123 -> char, etc. // FIXME: Do this check. - ImpCastExprToType(Arg, ValType, Kind); + ImpCastExprToType(Arg, ValType, Kind, ImplicitCastExpr::RValue, &BasePath); TheCall->setArg(i+1, Arg); } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 5cef1505042..200b8fd6810 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6803,11 +6803,11 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, // Adjust the Expr initializer and type. if (ECD->getInitExpr()) - ECD->setInitExpr(new (Context) ImplicitCastExpr(NewTy, - CastExpr::CK_IntegralCast, - ECD->getInitExpr(), - CXXBaseSpecifierArray(), - ImplicitCastExpr::RValue)); + ECD->setInitExpr(ImplicitCastExpr::Create(Context, NewTy, + CastExpr::CK_IntegralCast, + ECD->getInitExpr(), + /*base paths*/ 0, + ImplicitCastExpr::RValue)); if (getLangOptions().CPlusPlus) // C++ [dcl.enum]p4: Following the closing brace of an // enum-specifier, each enumerator has the type of its diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index c5705dfa9e7..08fa97b5e2c 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -720,7 +720,7 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths) { } void Sema::BuildBasePathArray(const CXXBasePaths &Paths, - CXXBaseSpecifierArray &BasePathArray) { + CXXCastPath &BasePathArray) { assert(BasePathArray.empty() && "Base path array must be empty!"); assert(Paths.isRecordingPaths() && "Must record paths!"); @@ -739,14 +739,14 @@ void Sema::BuildBasePathArray(const CXXBasePaths &Paths, // Now add all bases. for (unsigned I = Start, E = Path.size(); I != E; ++I) - BasePathArray.push_back(Path[I].Base); + BasePathArray.push_back(const_cast<CXXBaseSpecifier*>(Path[I].Base)); } /// \brief Determine whether the given base path includes a virtual /// base class. -bool Sema::BasePathInvolvesVirtualBase(const CXXBaseSpecifierArray &BasePath) { - for (CXXBaseSpecifierArray::iterator B = BasePath.begin(), - BEnd = BasePath.end(); +bool Sema::BasePathInvolvesVirtualBase(const CXXCastPath &BasePath) { + for (CXXCastPath::const_iterator B = BasePath.begin(), + BEnd = BasePath.end(); B != BEnd; ++B) if ((*B)->isVirtual()) return true; @@ -768,7 +768,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, unsigned AmbigiousBaseConvID, SourceLocation Loc, SourceRange Range, DeclarationName Name, - CXXBaseSpecifierArray *BasePath) { + CXXCastPath *BasePath) { // First, determine whether the path from Derived to Base is // ambiguous. This is slightly more expensive than checking whether // the Derived to Base conversion exists, because here we need to @@ -826,7 +826,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, bool Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, SourceLocation Loc, SourceRange Range, - CXXBaseSpecifierArray *BasePath, + CXXCastPath *BasePath, bool IgnoreAccess) { return CheckDerivedToBaseConversion(Derived, Base, IgnoreAccess ? 0 @@ -1534,10 +1534,12 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, QualType ArgTy = SemaRef.Context.getQualifiedType(BaseSpec->getType().getUnqualifiedType(), ParamType.getQualifiers()); + + CXXCastPath BasePath; + BasePath.push_back(BaseSpec); SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy, CastExpr::CK_UncheckedDerivedToBase, - ImplicitCastExpr::LValue, - CXXBaseSpecifierArray(BaseSpec)); + ImplicitCastExpr::LValue, &BasePath); InitializationKind InitKind = InitializationKind::CreateDirect(Constructor->getLocation(), @@ -4856,12 +4858,15 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, continue; } + CXXCastPath BasePath; + BasePath.push_back(Base); + // Construct the "from" expression, which is an implicit cast to the // appropriately-qualified base type. Expr *From = OtherRef->Retain(); ImpCastExprToType(From, Context.getQualifiedType(BaseType, OtherQuals), CastExpr::CK_UncheckedDerivedToBase, - ImplicitCastExpr::LValue, CXXBaseSpecifierArray(Base)); + ImplicitCastExpr::LValue, &BasePath); // Dereference "this". OwningExprResult To = CreateBuiltinUnaryOp(Loc, UnaryOperator::Deref, @@ -4873,7 +4878,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, Context.getCVRQualifiedType(BaseType, CopyAssignOperator->getTypeQualifiers()), CastExpr::CK_UncheckedDerivedToBase, - ImplicitCastExpr::LValue, CXXBaseSpecifierArray(Base)); + ImplicitCastExpr::LValue, &BasePath); To = Owned(ToE); // Build the copy. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 82a2bb2982c..920c235945c 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1491,7 +1491,7 @@ Sema::PerformObjectMemberConversion(Expr *&From, // type of the object type, in which case we just ignore it. // Otherwise build the appropriate casts. if (IsDerivedFrom(FromRecordType, QRecordType)) { - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (CheckDerivedToBaseConversion(FromRecordType, QRecordType, FromLoc, FromRange, &BasePath)) return true; @@ -1499,7 +1499,7 @@ Sema::PerformObjectMemberConversion(Expr *&From, if (PointerConversions) QType = Context.getPointerType(QType); ImpCastExprToType(From, QType, CastExpr::CK_UncheckedDerivedToBase, - Category, BasePath); + Category, &BasePath); FromType = QType; FromRecordType = QRecordType; @@ -1527,7 +1527,7 @@ Sema::PerformObjectMemberConversion(Expr *&From, // conversion is non-trivial. if (!Context.hasSameUnqualifiedType(FromRecordType, URecordType)) { assert(IsDerivedFrom(FromRecordType, URecordType)); - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (CheckDerivedToBaseConversion(FromRecordType, URecordType, FromLoc, FromRange, &BasePath)) return true; @@ -1536,7 +1536,7 @@ Sema::PerformObjectMemberConversion(Expr *&From, if (PointerConversions) UType = Context.getPointerType(UType); ImpCastExprToType(From, UType, CastExpr::CK_UncheckedDerivedToBase, - Category, BasePath); + Category, &BasePath); FromType = UType; FromRecordType = URecordType; } @@ -1546,14 +1546,14 @@ Sema::PerformObjectMemberConversion(Expr *&From, IgnoreAccess = true; } - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType, FromLoc, FromRange, &BasePath, IgnoreAccess)) return true; ImpCastExprToType(From, DestType, CastExpr::CK_UncheckedDerivedToBase, - Category, BasePath); + Category, &BasePath); return false; } @@ -3894,7 +3894,7 @@ static CastExpr::CastKind getScalarCastKind(ASTContext &Context, /// CheckCastTypes - Check type constraints for casting between types. bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr, CastExpr::CastKind& Kind, - CXXBaseSpecifierArray &BasePath, + CXXCastPath &BasePath, bool FunctionalStyle) { if (getLangOptions().CPlusPlus) return CXXCheckCStyleCast(TyR, castType, castExpr, Kind, BasePath, @@ -4064,16 +4064,16 @@ Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, Expr *castExpr = static_cast<Expr*>(Op.get()); CastExpr::CastKind Kind = CastExpr::CK_Unknown; - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), Ty->getType(), castExpr, Kind, BasePath)) return ExprError(); Op.release(); - return Owned(new (Context) CStyleCastExpr( + return Owned(CStyleCastExpr::Create(Context, Ty->getType().getNonLValueExprType(Context), - Kind, castExpr, BasePath, Ty, - LParenLoc, RParenLoc)); + Kind, castExpr, &BasePath, Ty, + LParenLoc, RParenLoc)); } /// This is not an AltiVec-style cast, so turn the ParenListExpr into a sequence diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 1e5735d6f83..b1d60155141 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -533,18 +533,18 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep, // if (NumExprs == 1) { CastExpr::CastKind Kind = CastExpr::CK_Unknown; - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, BasePath, /*FunctionalStyle=*/true)) return ExprError(); exprs.release(); - return Owned(new (Context) CXXFunctionalCastExpr( + return Owned(CXXFunctionalCastExpr::Create(Context, Ty.getNonLValueExprType(Context), - TInfo, TyBeginLoc, Kind, - Exprs[0], BasePath, - RParenLoc)); + TInfo, TyBeginLoc, Kind, + Exprs[0], &BasePath, + RParenLoc)); } if (Ty->isRecordType()) { @@ -1823,22 +1823,22 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, CastExpr::CastKind Kind = CastExpr::CK_Unknown; - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (CheckPointerConversion(From, ToType, Kind, BasePath, IgnoreBaseAccess)) return true; - ImpCastExprToType(From, ToType, Kind, ImplicitCastExpr::RValue, BasePath); + ImpCastExprToType(From, ToType, Kind, ImplicitCastExpr::RValue, &BasePath); break; } case ICK_Pointer_Member: { CastExpr::CastKind Kind = CastExpr::CK_Unknown; - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (CheckMemberPointerConversion(From, ToType, Kind, BasePath, IgnoreBaseAccess)) return true; if (CheckExceptionSpecCompatibility(From, ToType)) return true; - ImpCastExprToType(From, ToType, Kind, ImplicitCastExpr::RValue, BasePath); + ImpCastExprToType(From, ToType, Kind, ImplicitCastExpr::RValue, &BasePath); break; } case ICK_Boolean_Conversion: { @@ -1851,7 +1851,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, } case ICK_Derived_To_Base: { - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (CheckDerivedToBaseConversion(From->getType(), ToType.getNonReferenceType(), From->getLocStart(), @@ -1861,7 +1861,8 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, return true; ImpCastExprToType(From, ToType.getNonReferenceType(), - CastExpr::CK_DerivedToBase, CastCategory(From), BasePath); + CastExpr::CK_DerivedToBase, CastCategory(From), + &BasePath); break; } @@ -1994,10 +1995,10 @@ QualType Sema::CheckPointerToMemberOperands( ImplicitCastExpr::ResultCategory Category = isIndirect ? ImplicitCastExpr::RValue : CastCategory(lex); - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; BuildBasePathArray(Paths, BasePath); ImpCastExprToType(lex, UseType, CastExpr::CK_DerivedToBase, Category, - BasePath); + &BasePath); } if (isa<CXXScalarValueInitExpr>(rex->IgnoreParens())) { diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 5aa649bdc92..5ffb6481206 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3585,7 +3585,7 @@ InitializationSequence::Perform(Sema &S, // We have a derived-to-base cast that produces either an rvalue or an // lvalue. Perform that cast. - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; // Casts to inaccessible base classes are allowed with C-style casts. bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast(); @@ -3610,10 +3610,11 @@ InitializationSequence::Perform(Sema &S, (Step->Kind == SK_CastDerivedToBaseXValue ? ImplicitCastExpr::XValue : ImplicitCastExpr::RValue); - CurInit = S.Owned(new (S.Context) ImplicitCastExpr(Step->Type, - CastExpr::CK_DerivedToBase, - (Expr*)CurInit.release(), - BasePath, Category)); + CurInit = S.Owned(ImplicitCastExpr::Create(S.Context, + Step->Type, + CastExpr::CK_DerivedToBase, + (Expr*)CurInit.release(), + &BasePath, Category)); break; } @@ -3748,10 +3749,9 @@ InitializationSequence::Perform(Sema &S, CurInitExpr = CurInit.takeAs<Expr>(); // FIXME: xvalues - CurInit = S.Owned(new (S.Context) ImplicitCastExpr(CurInitExpr->getType(), - CastKind, - CurInitExpr, - CXXBaseSpecifierArray(), + CurInit = S.Owned(ImplicitCastExpr::Create(S.Context, + CurInitExpr->getType(), + CastKind, CurInitExpr, 0, IsLvalue ? ImplicitCastExpr::LValue : ImplicitCastExpr::RValue)); if (RequiresCopy) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 5dfbe09709f..27e6c2c2a34 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1663,7 +1663,7 @@ bool Sema::FunctionArgTypesAreEqual(FunctionProtoType* OldType, /// error, or returns false otherwise. bool Sema::CheckPointerConversion(Expr *From, QualType ToType, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray& BasePath, + CXXCastPath& BasePath, bool IgnoreBaseAccess) { QualType FromType = From->getType(); @@ -1755,7 +1755,7 @@ bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType, /// otherwise. bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType, CastExpr::CastKind &Kind, - CXXBaseSpecifierArray &BasePath, + CXXCastPath &BasePath, bool IgnoreBaseAccess) { QualType FromType = From->getType(); const MemberPointerType *FromPtrType = FromType->getAs<MemberPointerType>(); @@ -3725,10 +3725,10 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, // well-formed. DeclRefExpr ConversionRef(Conversion, Conversion->getType(), From->getLocStart()); - ImplicitCastExpr ConversionFn(Context.getPointerType(Conversion->getType()), + ImplicitCastExpr ConversionFn(ImplicitCastExpr::OnStack, + Context.getPointerType(Conversion->getType()), CastExpr::CK_FunctionToPointerDecay, - &ConversionRef, CXXBaseSpecifierArray(), - ImplicitCastExpr::RValue); + &ConversionRef, ImplicitCastExpr::RValue); // Note that it is safe to allocate CallExpr on the stack here because // there are 0 arguments (i.e., nothing is allocated using ASTContext's @@ -7636,13 +7636,14 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, assert(Context.hasSameType(ICE->getSubExpr()->getType(), SubExpr->getType()) && "Implicit cast type cannot be determined from overload"); + assert(ICE->path_empty() && "fixing up hierarchy conversion?"); if (SubExpr == ICE->getSubExpr()) return ICE->Retain(); - return new (Context) ImplicitCastExpr(ICE->getType(), - ICE->getCastKind(), - SubExpr, CXXBaseSpecifierArray(), - ICE->getCategory()); + return ImplicitCastExpr::Create(Context, ICE->getType(), + ICE->getCastKind(), + SubExpr, 0, + ICE->getCategory()); } if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) { |

