diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-03-10 17:45:58 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-03-10 17:45:58 +0000 |
commit | 27c39af73c0d7d0b97e57b3a905040d4cefc9708 (patch) | |
tree | 56c1dd85a159948815817b5a90bedb39cf9ad105 /lib/CodeGen | |
parent | d2e6cf1d1c6468396ec057119c32aa58b1ee5ac9 (diff) | |
download | FreeBSD-src-27c39af73c0d7d0b97e57b3a905040d4cefc9708.zip FreeBSD-src-27c39af73c0d7d0b97e57b3a905040d4cefc9708.tar.gz |
Update clang to r98164.
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 253 | ||||
-rw-r--r-- | lib/CodeGen/CGDebugInfo.h | 73 | ||||
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 24 | ||||
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 225 | ||||
-rw-r--r-- | lib/CodeGen/CGVtable.h | 18 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 10 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 4 | ||||
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 6 |
9 files changed, 348 insertions, 267 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 0f3502e..c3302e6 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -36,8 +36,9 @@ using namespace clang; using namespace clang::CodeGen; CGDebugInfo::CGDebugInfo(CodeGenModule &CGM) - : CGM(CGM), isMainCompileUnitCreated(false), DebugFactory(CGM.getModule()), - BlockLiteralGenericSet(false) { + : CGM(CGM), DebugFactory(CGM.getModule()), + FwdDeclCount(0), BlockLiteralGenericSet(false) { + CreateCompileUnit(); } CGDebugInfo::~CGDebugInfo() { @@ -85,45 +86,29 @@ llvm::StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) { return llvm::StringRef(StrPtr, NS.length()); } -/// getOrCreateCompileUnit - Get the compile unit from the cache or create a new -/// one if necessary. This returns null for invalid source locations. -llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) { - // Get source file information. - const char *FileName = "<unknown>"; +/// getOrCreateFile - Get the file debug info descriptor for the input location. +llvm::DIFile CGDebugInfo::getOrCreateFile(SourceLocation Loc) { + if (!Loc.isValid()) + // If Location is not valid then use main input file. + return DebugFactory.CreateFile(TheCU.getFilename(), TheCU.getDirectory(), + TheCU); SourceManager &SM = CGM.getContext().getSourceManager(); - if (Loc.isValid()) { - PresumedLoc PLoc = SM.getPresumedLoc(Loc); - FileName = PLoc.getFilename(); - unsigned FID = PLoc.getIncludeLoc().getRawEncoding(); - - // See if this compile unit has been used before for this valid location. - llvm::DICompileUnit &Unit = CompileUnitCache[FID]; - if (!Unit.isNull()) return Unit; - } + PresumedLoc PLoc = SM.getPresumedLoc(Loc); + llvm::sys::Path AbsFileName(PLoc.getFilename()); + AbsFileName.makeAbsolute(); + + return DebugFactory.CreateFile(AbsFileName.getLast(), + AbsFileName.getDirname(), TheCU); +} +/// CreateCompileUnit - Create new compile unit. +void CGDebugInfo::CreateCompileUnit() { // Get absolute path name. - llvm::sys::Path AbsFileName(FileName); + llvm::sys::Path AbsFileName(CGM.getCodeGenOpts().MainFileName); AbsFileName.makeAbsolute(); - // See if thie compile unit is representing main source file. Each source - // file has corresponding compile unit. There is only one main source - // file at a time. - bool isMain = false; - const LangOptions &LO = CGM.getLangOptions(); - const CodeGenOptions &CGO = CGM.getCodeGenOpts(); - if (isMainCompileUnitCreated == false) { - if (!CGO.MainFileName.empty()) { - if (AbsFileName.getLast() == CGO.MainFileName) - isMain = true; - } else { - if (Loc.isValid() && SM.isFromMainFile(Loc)) - isMain = true; - } - if (isMain) - isMainCompileUnitCreated = true; - } - unsigned LangTag; + const LangOptions &LO = CGM.getLangOptions(); if (LO.CPlusPlus) { if (LO.ObjC1) LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus; @@ -149,22 +134,15 @@ llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) { RuntimeVers = LO.ObjCNonFragileABI ? 2 : 1; // Create new compile unit. - llvm::DICompileUnit Unit = DebugFactory.CreateCompileUnit( - LangTag, AbsFileName.getLast(), AbsFileName.getDirname(), Producer, isMain, + TheCU = DebugFactory.CreateCompileUnit( + LangTag, AbsFileName.getLast(), AbsFileName.getDirname(), Producer, true, LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers); - - if (Loc.isValid()) { - PresumedLoc PLoc = SM.getPresumedLoc(Loc); - unsigned FID = PLoc.getIncludeLoc().getRawEncoding(); - CompileUnitCache[FID] = Unit; - } - return Unit; } /// CreateType - Get the Basic type from the cache or create a new /// one if necessary. llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { unsigned Encoding = 0; switch (BT->getKind()) { default: @@ -201,7 +179,7 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT, } llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { // Bit size, align and offset of the type. unsigned Encoding = llvm::dwarf::DW_ATE_complex_float; if (Ty->isComplexIntegerType()) @@ -220,7 +198,7 @@ llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty, /// CreateCVRType - Get the qualified type from the cache or create /// a new one if necessary. -llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DICompileUnit Unit) { +llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) { QualifierCollector Qc; const Type *T = Qc.strip(Ty); @@ -250,13 +228,13 @@ llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DICompileUnit U // No need to fill in the Name, Line, Size, Alignment, Offset in case of // CVR derived types. llvm::DIType DbgTy = - DebugFactory.CreateDerivedType(Tag, Unit, "", llvm::DICompileUnit(), + DebugFactory.CreateDerivedType(Tag, Unit, "", Unit, 0, 0, 0, 0, 0, FromTy); return DbgTy; } llvm::DIType CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { llvm::DIType DbgTy = CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty, Ty->getPointeeType(), Unit); @@ -264,7 +242,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty, } llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty, Ty->getPointeeType(), Unit); } @@ -272,7 +250,7 @@ llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty, llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag, const Type *Ty, QualType PointeeTy, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { llvm::DIType EltTy = getOrCreateType(PointeeTy, Unit); // Bit size, align and offset of the type. @@ -284,17 +262,16 @@ llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag, uint64_t Align = CGM.getContext().getTypeAlign(Ty); return - DebugFactory.CreateDerivedType(Tag, Unit, "", llvm::DICompileUnit(), + DebugFactory.CreateDerivedType(Tag, Unit, "", Unit, 0, Size, Align, 0, 0, EltTy); } llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { if (BlockLiteralGenericSet) return BlockLiteralGeneric; - llvm::DICompileUnit DefUnit; unsigned Tag = llvm::dwarf::DW_TAG_structure_type; llvm::SmallVector<llvm::DIDescriptor, 5> EltTys; @@ -314,7 +291,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "reserved", DefUnit, + "reserved", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -325,7 +302,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "Size", DefUnit, + "Size", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -337,7 +314,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, unsigned Flags = llvm::DIType::FlagAppleBlock; EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_descriptor", - DefUnit, 0, FieldOffset, 0, 0, Flags, + Unit, 0, FieldOffset, 0, 0, Flags, llvm::DIType(), Elements); // Bit size, align and offset of the type. @@ -345,7 +322,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, uint64_t Align = CGM.getContext().getTypeAlign(Ty); DescTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, - Unit, "", llvm::DICompileUnit(), + Unit, "", Unit, 0, Size, Align, 0, 0, EltTy); FieldOffset = 0; @@ -354,7 +331,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "__isa", DefUnit, + "__isa", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -365,7 +342,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "__flags", DefUnit, + "__flags", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -376,7 +353,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "__reserved", DefUnit, + "__reserved", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -387,7 +364,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "__FuncPtr", DefUnit, + "__FuncPtr", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -398,7 +375,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, FieldSize = CGM.getContext().getTypeSize(Ty); FieldAlign = CGM.getContext().getTypeAlign(Ty); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "__descriptor", DefUnit, + "__descriptor", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -407,19 +384,19 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size()); EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_literal_generic", - DefUnit, 0, FieldOffset, 0, 0, Flags, + Unit, 0, FieldOffset, 0, 0, Flags, llvm::DIType(), Elements); BlockLiteralGenericSet = true; BlockLiteralGeneric = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit, - "", llvm::DICompileUnit(), + "", Unit, 0, Size, Align, 0, 0, EltTy); return BlockLiteralGeneric; } llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { // Typedefs are derived from some other type. If we have a typedef of a // typedef, make sure to emit the whole chain. llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit); @@ -442,7 +419,7 @@ llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, } llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { llvm::SmallVector<llvm::DIDescriptor, 16> EltTys; // Add the result type at least. @@ -462,7 +439,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty, llvm::DIType DbgTy = DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type, - Unit, "", llvm::DICompileUnit(), + Unit, "", Unit, 0, 0, 0, 0, 0, llvm::DIType(), EltTypeArray); return DbgTy; @@ -471,7 +448,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty, /// CollectRecordFields - A helper function to collect debug info for /// record fields. This is used while creating debug info entry for a Record. void CGDebugInfo:: -CollectRecordFields(const RecordDecl *RD, llvm::DICompileUnit Unit, +CollectRecordFields(const RecordDecl *RD, llvm::DIFile Unit, llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys) { unsigned FieldNo = 0; SourceManager &SM = CGM.getContext().getSourceManager(); @@ -491,11 +468,11 @@ CollectRecordFields(const RecordDecl *RD, llvm::DICompileUnit Unit, // Get the location for the field. SourceLocation FieldDefLoc = Field->getLocation(); PresumedLoc PLoc = SM.getPresumedLoc(FieldDefLoc); - llvm::DICompileUnit FieldDefUnit; + llvm::DIFile FieldDefUnit; unsigned FieldLine = 0; if (!PLoc.isInvalid()) { - FieldDefUnit = getOrCreateCompileUnit(FieldDefLoc); + FieldDefUnit = getOrCreateFile(FieldDefLoc); FieldLine = PLoc.getLine(); } @@ -531,7 +508,7 @@ CollectRecordFields(const RecordDecl *RD, llvm::DICompileUnit Unit, /// routine to get a method type which includes "this" pointer. llvm::DIType CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { llvm::DIType FnTy = getOrCreateType(Method->getType(), Unit); // Static methods do not need "this" pointer argument. @@ -566,7 +543,7 @@ CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method, return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type, - Unit, "", llvm::DICompileUnit(), + Unit, "", Unit, 0, 0, 0, 0, 0, llvm::DIType(), EltTypeArray); } @@ -575,7 +552,7 @@ CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method, /// a single member function GlobalDecl. llvm::DISubprogram CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method, - llvm::DICompileUnit Unit, + llvm::DIFile Unit, llvm::DICompositeType &RecordTy) { bool IsCtorOrDtor = isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method); @@ -594,11 +571,11 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method, // Get the location for the method. SourceLocation MethodDefLoc = Method->getLocation(); PresumedLoc PLoc = SM.getPresumedLoc(MethodDefLoc); - llvm::DICompileUnit MethodDefUnit; + llvm::DIFile MethodDefUnit; unsigned MethodLine = 0; if (!PLoc.isInvalid()) { - MethodDefUnit = getOrCreateCompileUnit(MethodDefLoc); + MethodDefUnit = getOrCreateFile(MethodDefLoc); MethodLine = PLoc.getLine(); } @@ -640,7 +617,7 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method, /// C++ member functions.This is used while creating debug info entry for /// a Record. void CGDebugInfo:: -CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DICompileUnit Unit, +CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit, llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys, llvm::DICompositeType &RecordTy) { for(CXXRecordDecl::method_iterator I = RD->method_begin(), @@ -658,7 +635,7 @@ CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DICompileUnit Unit, /// C++ base classes. This is used while creating debug info entry for /// a Record. void CGDebugInfo:: -CollectCXXBases(const CXXRecordDecl *RD, llvm::DICompileUnit Unit, +CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit, llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys, llvm::DICompositeType &RecordTy) { @@ -688,7 +665,7 @@ CollectCXXBases(const CXXRecordDecl *RD, llvm::DICompileUnit Unit, llvm::DIType DTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_inheritance, RecordTy, llvm::StringRef(), - llvm::DICompileUnit(), 0, 0, 0, + Unit, 0, 0, 0, BaseOffset, BFlags, getOrCreateType(BI->getType(), Unit)); @@ -697,8 +674,8 @@ CollectCXXBases(const CXXRecordDecl *RD, llvm::DICompileUnit Unit, } /// getOrCreateVTablePtrType - Return debug info descriptor for vtable. -llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DICompileUnit Unit) { - if (!VTablePtrType.isNull()) +llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile Unit) { + if (VTablePtrType.isValid()) return VTablePtrType; ASTContext &Context = CGM.getContext(); @@ -710,18 +687,19 @@ llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DICompileUnit Unit) { DebugFactory.GetOrCreateArray(STys.data(), STys.size()); llvm::DIType SubTy = DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type, - Unit, "", llvm::DICompileUnit(), + Unit, "", Unit, 0, 0, 0, 0, 0, llvm::DIType(), SElements); unsigned Size = Context.getTypeSize(Context.VoidPtrTy); llvm::DIType vtbl_ptr_type = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, - Unit, "__vtbl_ptr_type", llvm::DICompileUnit(), + Unit, "__vtbl_ptr_type", Unit, 0, Size, 0, 0, 0, SubTy); - VTablePtrType = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, - Unit, "", llvm::DICompileUnit(), - 0, Size, 0, 0, 0, vtbl_ptr_type); + VTablePtrType = + DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, + Unit, "", Unit, + 0, Size, 0, 0, 0, vtbl_ptr_type); return VTablePtrType; } @@ -740,7 +718,7 @@ llvm::StringRef CGDebugInfo::getVtableName(const CXXRecordDecl *RD) { /// CollectVtableInfo - If the C++ class has vtable info then insert appropriate /// debug info entry in EltTys vector. void CGDebugInfo:: -CollectVtableInfo(const CXXRecordDecl *RD, llvm::DICompileUnit Unit, +CollectVtableInfo(const CXXRecordDecl *RD, llvm::DIFile Unit, llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys) { const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); @@ -755,7 +733,7 @@ CollectVtableInfo(const CXXRecordDecl *RD, llvm::DICompileUnit Unit, unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy); llvm::DIType VPTR = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - getVtableName(RD), llvm::DICompileUnit(), + getVtableName(RD), Unit, 0, Size, 0, 0, 0, getOrCreateVTablePtrType(Unit)); EltTys.push_back(VPTR); @@ -763,7 +741,7 @@ CollectVtableInfo(const CXXRecordDecl *RD, llvm::DICompileUnit Unit, /// CreateType - get structure or union type. llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { RecordDecl *RD = Ty->getDecl(); unsigned Tag; @@ -780,10 +758,10 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, // Get overall information about the record type for the debug info. PresumedLoc PLoc = SM.getPresumedLoc(RD->getLocation()); - llvm::DICompileUnit DefUnit; + llvm::DIFile DefUnit; unsigned Line = 0; if (!PLoc.isInvalid()) { - DefUnit = getOrCreateCompileUnit(RD->getLocation()); + DefUnit = getOrCreateFile(RD->getLocation()); Line = PLoc.getLine(); } @@ -796,12 +774,13 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, // A RD->getName() is not unique. However, the debug info descriptors // are uniqued so use type name to ensure uniquness. - std::string STy = QualType(Ty, 0).getAsString(); + llvm::SmallString<256> FwdDeclName; + FwdDeclName.resize(256); + sprintf(&FwdDeclName[0], "fwd.type.%d", FwdDeclCount++); llvm::DIDescriptor FDContext = getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()), Unit); llvm::DICompositeType FwdDecl = - DebugFactory.CreateCompositeType(Tag, FDContext, - STy.c_str(), + DebugFactory.CreateCompositeType(Tag, FDContext, FwdDeclName, DefUnit, Line, 0, 0, 0, 0, llvm::DIType(), llvm::DIArray()); @@ -861,19 +840,19 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, /// CreateType - get objective-c interface type. llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { ObjCInterfaceDecl *ID = Ty->getDecl(); unsigned Tag = llvm::dwarf::DW_TAG_structure_type; SourceManager &SM = CGM.getContext().getSourceManager(); // Get overall information about the record type for the debug info. - llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(ID->getLocation()); + llvm::DIFile DefUnit = getOrCreateFile(ID->getLocation()); PresumedLoc PLoc = SM.getPresumedLoc(ID->getLocation()); unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine(); - unsigned RuntimeLang = DefUnit.getLanguage(); + unsigned RuntimeLang = TheCU.getLanguage(); // To handle recursive interface, we // first generate a debug descriptor for the struct as a forward declaration. @@ -905,7 +884,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit); llvm::DIType InhTag = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_inheritance, - Unit, "", llvm::DICompileUnit(), 0, 0, 0, + Unit, "", Unit, 0, 0, 0, 0 /* offset */, 0, SClassTy); EltTys.push_back(InhTag); } @@ -926,7 +905,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, // Get the location for the field. SourceLocation FieldDefLoc = Field->getLocation(); - llvm::DICompileUnit FieldDefUnit = getOrCreateCompileUnit(FieldDefLoc); + llvm::DIFile FieldDefUnit = getOrCreateFile(FieldDefLoc); PresumedLoc PLoc = SM.getPresumedLoc(FieldDefLoc); unsigned FieldLine = PLoc.isInvalid() ? 0 : PLoc.getLine(); @@ -984,7 +963,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, } llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { EnumDecl *ED = Ty->getDecl(); llvm::SmallVector<llvm::DIDescriptor, 32> Enumerators; @@ -1002,7 +981,7 @@ llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty, DebugFactory.GetOrCreateArray(Enumerators.data(), Enumerators.size()); SourceLocation DefLoc = ED->getLocation(); - llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(DefLoc); + llvm::DIFile DefUnit = getOrCreateFile(DefLoc); SourceManager &SM = CGM.getContext().getSourceManager(); PresumedLoc PLoc = SM.getPresumedLoc(DefLoc); unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine(); @@ -1025,7 +1004,7 @@ llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty, } llvm::DIType CGDebugInfo::CreateType(const TagType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { if (const RecordType *RT = dyn_cast<RecordType>(Ty)) return CreateType(RT, Unit); else if (const EnumType *ET = dyn_cast<EnumType>(Ty)) @@ -1035,7 +1014,7 @@ llvm::DIType CGDebugInfo::CreateType(const TagType *Ty, } llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { llvm::DIType ElementTy = getOrCreateType(Ty->getElementType(), Unit); uint64_t NumElems = Ty->getNumElements(); if (NumElems > 0) @@ -1051,13 +1030,13 @@ llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty, return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_vector_type, - Unit, "", llvm::DICompileUnit(), + Unit, "", Unit, 0, Size, Align, 0, 0, ElementTy, SubscriptArray); } llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { uint64_t Size; uint64_t Align; @@ -1096,7 +1075,7 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty, llvm::DIType DbgTy = DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_array_type, - Unit, "", llvm::DICompileUnit(), + Unit, "", Unit, 0, Size, Align, 0, 0, getOrCreateType(EltTy, Unit), SubscriptArray); @@ -1104,13 +1083,13 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty, } llvm::DIType CGDebugInfo::CreateType(const LValueReferenceType *Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type, Ty, Ty->getPointeeType(), Unit); } llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty, - llvm::DICompileUnit U) { + llvm::DIFile U) { QualType PointerDiffTy = CGM.getContext().getPointerDiffType(); llvm::DIType PointerDiffDITy = getOrCreateType(PointerDiffTy, U); @@ -1129,14 +1108,14 @@ llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty, // FIXME: This should probably be a function type instead. ElementTypes[0] = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, U, - "ptr", llvm::DICompileUnit(), 0, + "ptr", U, 0, Info.first, Info.second, FieldOffset, 0, PointerDiffDITy); FieldOffset += Info.first; ElementTypes[1] = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, U, - "ptr", llvm::DICompileUnit(), 0, + "ptr", U, 0, Info.first, Info.second, FieldOffset, 0, PointerDiffDITy); @@ -1146,7 +1125,7 @@ llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty, return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_structure_type, U, llvm::StringRef("test"), - llvm::DICompileUnit(), 0, FieldOffset, + U, 0, FieldOffset, 0, 0, 0, llvm::DIType(), Elements); } @@ -1192,7 +1171,7 @@ static QualType UnwrapTypeForDebugInfo(QualType T) { /// getOrCreateType - Get the type from the cache or create a new /// one if necessary. llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { if (Ty.isNull()) return llvm::DIType(); @@ -1218,7 +1197,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, /// CreateTypeNode - Create a new debug type node. llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, - llvm::DICompileUnit Unit) { + llvm::DIFile Unit) { // Handle qualifiers, which recursively handles what they refer to. if (Ty.hasLocalQualifiers()) return CreateQualifiedType(Ty, Unit); @@ -1267,6 +1246,7 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, case Type::MemberPointer: return CreateType(cast<MemberPointerType>(Ty), Unit); + case Type::InjectedClassName: case Type::TemplateSpecialization: case Type::Elaborated: case Type::QualifiedName: @@ -1306,8 +1286,8 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator FI = SPCache.find(FD); if (FI != SPCache.end()) { - llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(FI->second)); - if (!SP.isNull() && SP.isSubprogram() && SP.isDefinition()) { + llvm::DIDescriptor SP(dyn_cast_or_null<llvm::MDNode>(FI->second)); + if (SP.isSubprogram() && llvm::DISubprogram(SP.getNode()).isDefinition()) { RegionStack.push_back(SP.getNode()); RegionMap[D] = llvm::WeakVH(SP.getNode()); return; @@ -1329,7 +1309,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, // It is expected that CurLoc is set before using EmitFunctionStart. // Usually, CurLoc points to the left bracket location of compound // statement representing function body. - llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc); + llvm::DIFile Unit = getOrCreateFile(CurLoc); SourceManager &SM = CGM.getContext().getSourceManager(); unsigned LineNo = SM.getPresumedLoc(CurLoc).getLine(); @@ -1359,7 +1339,7 @@ void CGDebugInfo::EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder) { PrevLoc = CurLoc; // Get the appropriate compile unit. - llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc); + llvm::DIFile Unit = getOrCreateFile(CurLoc); PresumedLoc PLoc = SM.getPresumedLoc(CurLoc); llvm::DIDescriptor DR(RegionStack.back()); @@ -1406,7 +1386,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD, uint64_t FieldSize, FieldOffset; unsigned FieldAlign; - llvm::DICompileUnit Unit = getOrCreateCompileUnit(VD->getLocation()); + llvm::DIFile Unit = getOrCreateFile(VD->getLocation()); QualType Type = VD->getType(); FieldOffset = 0; @@ -1415,7 +1395,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "__isa", llvm::DICompileUnit(), + "__isa", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -1426,7 +1406,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "__forwarding", llvm::DICompileUnit(), + "__forwarding", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -1437,7 +1417,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "__flags", llvm::DICompileUnit(), + "__flags", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -1448,7 +1428,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "__size", llvm::DICompileUnit(), + "__size", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -1461,8 +1441,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "__copy_helper", - llvm::DICompileUnit(), + "__copy_helper", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -1473,8 +1452,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - "__destroy_helper", - llvm::DICompileUnit(), + "__destroy_helper", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -1497,7 +1475,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD, FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().getTypeAlign(FType); FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, - Unit, "", llvm::DICompileUnit(), + Unit, "", Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -1512,7 +1490,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD, *XOffset = FieldOffset; FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, - VD->getName(), llvm::DICompileUnit(), + VD->getName(), Unit, 0, FieldSize, FieldAlign, FieldOffset, 0, FieldTy); EltTys.push_back(FieldTy); @@ -1524,8 +1502,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD, unsigned Flags = llvm::DIType::FlagBlockByrefStruct; return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_structure_type, - Unit, "", - llvm::DICompileUnit(), + Unit, "", Unit, 0, FieldOffset, 0, 0, Flags, llvm::DIType(), Elements); @@ -1542,7 +1519,7 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag, if (CGO.OptimizationLevel) return; - llvm::DICompileUnit Unit = getOrCreateCompileUnit(VD->getLocation()); + llvm::DIFile Unit = getOrCreateFile(VD->getLocation()); llvm::DIType Ty; uint64_t XOffset = 0; if (VD->hasAttr<BlocksAttr>()) @@ -1560,9 +1537,9 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag, if (PLoc.isValid()) { Line = PLoc.getLine(); Column = PLoc.getColumn(); - Unit = getOrCreateCompileUnit(CurLoc); + Unit = getOrCreateFile(CurLoc); } else { - Unit = llvm::DICompileUnit(); + Unit = llvm::DIFile(); } // Create the descriptor for the variable. @@ -1596,7 +1573,7 @@ void CGDebugInfo::EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag, return; uint64_t XOffset = 0; - llvm::DICompileUnit Unit = getOrCreateCompileUnit(VD->getLocation()); + llvm::DIFile Unit = getOrCreateFile(VD->getLocation()); llvm::DIType Ty; if (VD->hasAttr<BlocksAttr>()) Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset); @@ -1610,7 +1587,7 @@ void CGDebugInfo::EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag, if (!PLoc.isInvalid()) Line = PLoc.getLine(); else - Unit = llvm::DICompileUnit(); + Unit = llvm::DIFile(); CharUnits offset = CGF->BlockDecls[VD]; llvm::SmallVector<llvm::Value *, 9> addr; @@ -1675,7 +1652,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, const VarDecl *D) { // Create global variable debug descriptor. - llvm::DICompileUnit Unit = getOrCreateCompileUnit(D->getLocation()); + llvm::DIFile Unit = getOrCreateFile(D->getLocation()); SourceManager &SM = CGM.getContext().getSourceManager(); PresumedLoc PLoc = SM.getPresumedLoc(D->getLocation()); unsigned LineNo = PLoc.isInvalid() ? 0 : PLoc.getLine(); @@ -1706,7 +1683,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, ObjCInterfaceDecl *ID) { // Create global variable debug descriptor. - llvm::DICompileUnit Unit = getOrCreateCompileUnit(ID->getLocation()); + llvm::DIFile Unit = getOrCreateFile(ID->getLocation()); SourceManager &SM = CGM.getContext().getSourceManager(); PresumedLoc PLoc = SM.getPresumedLoc(ID->getLocation()); unsigned LineNo = PLoc.isInvalid() ? 0 : PLoc.getLine(); @@ -1750,7 +1727,7 @@ CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl, getContextDescriptor(dyn_cast<Decl>(NSDecl->getDeclContext()), Unit); llvm::DINameSpace NS = DebugFactory.CreateNameSpace(Context, NSDecl->getName(), - llvm::DICompileUnit(Unit.getNode()), LineNo); + llvm::DIFile(Unit.getNode()), LineNo); NameSpaceCache[NSDecl] = llvm::WeakVH(NS.getNode()); return NS; } diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index 50f5759..47a4620 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -43,16 +43,14 @@ namespace CodeGen { /// the backend. class CGDebugInfo { CodeGenModule &CGM; - bool isMainCompileUnitCreated; llvm::DIFactory DebugFactory; - + llvm::DICompileUnit TheCU; SourceLocation CurLoc, PrevLoc; - llvm::DIType VTablePtrType; - - /// CompileUnitCache - Cache of previously constructed CompileUnits. - llvm::DenseMap<unsigned, llvm::DICompileUnit> CompileUnitCache; - + /// FwdDeclCount - This counter is used to ensure unique names for forward + /// record decls. + unsigned FwdDeclCount; + /// TypeCache - Cache of previously constructed Types. // FIXME: Eliminate this map. Be careful of iterator invalidation. std::map<void *, llvm::WeakVH> TypeCache; @@ -71,52 +69,52 @@ class CGDebugInfo { llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH> NameSpaceCache; /// Helper functions for getOrCreateType. - llvm::DIType CreateType(const BuiltinType *Ty, llvm::DICompileUnit U); - llvm::DIType CreateType(const ComplexType *Ty, llvm::DICompileUnit U); - llvm::DIType CreateQualifiedType(QualType Ty, llvm::DICompileUnit U); - llvm::DIType CreateType(const TypedefType *Ty, llvm::DICompileUnit U); + llvm::DIType CreateType(const BuiltinType *Ty, llvm::DIFile F); + llvm::DIType CreateType(const ComplexType *Ty, llvm::DIFile F); + llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile F); + llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile F); llvm::DIType CreateType(const ObjCObjectPointerType *Ty, - llvm::DICompileUnit Unit); - llvm::DIType CreateType(const PointerType *Ty, llvm::DICompileUnit U); - llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DICompileUnit U); - llvm::DIType CreateType(const FunctionType *Ty, llvm::DICompileUnit U); - llvm::DIType CreateType(const TagType *Ty, llvm::DICompileUnit U); - llvm::DIType CreateType(const RecordType *Ty, llvm::DICompileUnit U); - llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DICompileUnit U); - llvm::DIType CreateType(const EnumType *Ty, llvm::DICompileUnit U); - llvm::DIType CreateType(const VectorType *Ty, llvm::DICompileUnit Unit); - llvm::DIType CreateType(const ArrayType *Ty, llvm::DICompileUnit U); - llvm::DIType CreateType(const LValueReferenceType *Ty, llvm::DICompileUnit U); - llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DICompileUnit U); + llvm::DIFile F); + llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F); + llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F); + llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F); + llvm::DIType CreateType(const TagType *Ty, llvm::DIFile F); + llvm::DIType CreateType(const RecordType *Ty, llvm::DIFile F); + llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F); + llvm::DIType CreateType(const EnumType *Ty, llvm::DIFile F); + llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F); + llvm::DIType CreateType(const ArrayType *Ty, llvm::DIFile F); + llvm::DIType CreateType(const LValueReferenceType *Ty, llvm::DIFile F); + llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DIFile F); llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method, - llvm::DICompileUnit Unit); - llvm::DIType getOrCreateVTablePtrType(llvm::DICompileUnit Unit); + llvm::DIFile F); + llvm::DIType getOrCreateVTablePtrType(llvm::DIFile F); llvm::DINameSpace getOrCreateNameSpace(const NamespaceDecl *N, llvm::DIDescriptor Unit); llvm::DIType CreatePointerLikeType(unsigned Tag, const Type *Ty, QualType PointeeTy, - llvm::DICompileUnit U); + llvm::DIFile F); llvm::DISubprogram CreateCXXMemberFunction(const CXXMethodDecl *Method, - llvm::DICompileUnit Unit, + llvm::DIFile F, llvm::DICompositeType &RecordTy); void CollectCXXMemberFunctions(const CXXRecordDecl *Decl, - llvm::DICompileUnit U, + llvm::DIFile F, llvm::SmallVectorImpl<llvm::DIDescriptor> &E, llvm::DICompositeType &T); void CollectCXXBases(const CXXRecordDecl *Decl, - llvm::DICompileUnit Unit, + llvm::DIFile F, llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys, llvm::DICompositeType &RecordTy); - void CollectRecordFields(const RecordDecl *Decl, llvm::DICompileUnit U, + void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile F, llvm::SmallVectorImpl<llvm::DIDescriptor> &E); void CollectVtableInfo(const CXXRecordDecl *Decl, - llvm::DICompileUnit Unit, + llvm::DIFile F, llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys); public: @@ -185,16 +183,19 @@ private: llvm::DIDescriptor getContextDescriptor(const Decl *Decl, llvm::DIDescriptor &CU); - /// getOrCreateCompileUnit - Get the compile unit from the cache or create a - /// new one if necessary. - llvm::DICompileUnit getOrCreateCompileUnit(SourceLocation Loc); + /// CreateCompileUnit - Create new compile unit. + void CreateCompileUnit(); + + /// getOrCreateFile - Get the file debug info descriptor for the input + /// location. + llvm::DIFile getOrCreateFile(SourceLocation Loc); /// getOrCreateType - Get the type from the cache or create a new type if /// necessary. - llvm::DIType getOrCreateType(QualType Ty, llvm::DICompileUnit Unit); + llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F); /// CreateTypeNode - Create type metadata for a source language type. - llvm::DIType CreateTypeNode(QualType Ty, llvm::DICompileUnit Unit); + llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F); /// getFunctionName - Get function name for the given FunctionDecl. If the /// name is constructred on demand (e.g. C++ destructor) then the name diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index ac189a0..4847ca3 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -178,6 +178,11 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) { //===----------------------------------------------------------------------===// void AggExprEmitter::VisitCastExpr(CastExpr *E) { + if (!DestPtr) { + Visit(E->getSubExpr()); + return; + } + switch (E->getCastKind()) { default: assert(0 && "Unhandled cast kind!"); @@ -205,6 +210,11 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { break; case CastExpr::CK_NullToMemberPointer: { + // If the subexpression's type is the C++0x nullptr_t, emit the + // subexpression, which may have side effects. + if (E->getSubExpr()->getType()->isNullPtrType()) + Visit(E->getSubExpr()); + const llvm::Type *PtrDiffTy = CGF.ConvertType(CGF.getContext().getPointerDiffType()); @@ -652,6 +662,16 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { return; } + + // If we're initializing the whole aggregate, just do it in place. + // FIXME: This is a hack around an AST bug (PR6537). + if (NumInitElements == 1 && E->getType() == E->getInit(0)->getType()) { + EmitInitializationToLValue(E->getInit(0), + LValue::MakeAddr(DestPtr, Qualifiers()), + E->getType()); + return; + } + // Here we iterate over the fields; this makes it simpler to both // default-initialize fields and skip over unnamed fields. @@ -670,8 +690,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { // We never generate write-barries for initialized fields. LValue::SetObjCNonGC(FieldLoc, true); if (CurInitVal < NumInitElements) { - // Store the initializer into the field - EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc, + // Store the initializer into the field. + EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc, Field->getType()); } else { // We're out of initalizers; default-initialize to null diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index b62e6ed..3ff77f0 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -59,7 +59,7 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) { // Find the receiver llvm::Value *Receiver; if (!ReceiverExpr) { - const ObjCInterfaceDecl *OID = E->getClassInfo().first; + const ObjCInterfaceDecl *OID = E->getClassInfo().Decl; // Very special case, super send in class method. The receiver is // self (the class object) and the send uses super semantics. diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 932bd07..4500ec0 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -60,10 +60,13 @@ public: /// Method - The method decl of the overrider. const CXXMethodDecl *Method; - /// Offset - the base offset of the overrider relative to the layout class. - int64_t Offset; + /// Offset - the base offset of the overrider in the layout class. + uint64_t Offset; - OverriderInfo() : Method(0), Offset(0) { } + /// OldOffset - FIXME: Remove this. + int64_t OldOffset; + + OverriderInfo() : Method(0), Offset(0), OldOffset(0) { } }; private: @@ -71,6 +74,16 @@ private: /// are stored. const CXXRecordDecl *MostDerivedClass; + /// MostDerivedClassOffset - If we're building final overriders for a + /// construction vtable, this holds the offset from the layout class to the + /// most derived class. + const uint64_t MostDerivedClassOffset; + + /// LayoutClass - The class we're using for layout information. Will be + /// different than the most derived class if the final overriders are for a + /// construction vtable. + const CXXRecordDecl *LayoutClass; + ASTContext &Context; /// MostDerivedClassLayout - the AST record layout of the most derived class. @@ -122,11 +135,13 @@ private: /// subobject (and all its direct and indirect bases). void ComputeFinalOverriders(BaseSubobject Base, bool BaseSubobjectIsVisitedVBase, + uint64_t OffsetInLayoutClass, SubobjectOffsetsMapTy &Offsets); /// AddOverriders - Add the final overriders for this base subobject to the /// map of final overriders. - void AddOverriders(BaseSubobject Base, SubobjectOffsetsMapTy &Offsets); + void AddOverriders(BaseSubobject Base,uint64_t OffsetInLayoutClass, + SubobjectOffsetsMapTy &Offsets); /// PropagateOverrider - Propagate the NewMD overrider to all the functions /// that OldMD overrides. For example, if we have: @@ -139,6 +154,7 @@ private: /// C::f. void PropagateOverrider(const CXXMethodDecl *OldMD, BaseSubobject NewBase, + uint64_t OverriderOffsetInLayoutClass, const CXXMethodDecl *NewMD, SubobjectOffsetsMapTy &Offsets); @@ -146,7 +162,9 @@ private: SubobjectOffsetsMapTy &Offsets); public: - explicit FinalOverriders(const CXXRecordDecl *MostDerivedClass); + FinalOverriders(const CXXRecordDecl *MostDerivedClass, + uint64_t MostDerivedClassOffset, + const CXXRecordDecl *LayoutClass); /// getOverrider - Get the final overrider for the given method declaration in /// the given base subobject. @@ -181,15 +199,19 @@ public: #define DUMP_OVERRIDERS 0 -FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass) +FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass, + uint64_t MostDerivedClassOffset, + const CXXRecordDecl *LayoutClass) : MostDerivedClass(MostDerivedClass), + MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)) { // Compute the final overriders. SubobjectOffsetsMapTy Offsets; ComputeFinalOverriders(BaseSubobject(MostDerivedClass, 0), - /*BaseSubobjectIsVisitedVBase=*/false, Offsets); + /*BaseSubobjectIsVisitedVBase=*/false, + MostDerivedClassOffset, Offsets); VisitedVirtualBases.clear(); #if DUMP_OVERRIDERS @@ -199,18 +221,19 @@ FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass) // Also dump the base offsets (for now). for (SubobjectOffsetsMapTy::const_iterator I = Offsets.begin(), E = Offsets.end(); I != E; ++I) { - const OffsetVectorTy& OffsetVector = I->second; + const OffsetSetVectorTy& OffsetSetVector = I->second; llvm::errs() << "Base offsets for "; llvm::errs() << I->first->getQualifiedNameAsString() << '\n'; - for (unsigned I = 0, E = OffsetVector.size(); I != E; ++I) - llvm::errs() << " " << I << " - " << OffsetVector[I] << '\n'; + for (unsigned I = 0, E = OffsetSetVector.size(); I != E; ++I) + llvm::errs() << " " << I << " - " << OffsetSetVector[I] / 8 << '\n'; } #endif } void FinalOverriders::AddOverriders(BaseSubobject Base, + uint64_t OffsetInLayoutClass, SubobjectOffsetsMapTy &Offsets) { const CXXRecordDecl *RD = Base.getBase(); @@ -222,13 +245,14 @@ void FinalOverriders::AddOverriders(BaseSubobject Base, continue; // First, propagate the overrider. - PropagateOverrider(MD, Base, MD, Offsets); + PropagateOverrider(MD, Base, OffsetInLayoutClass, MD, Offsets); // Add the overrider as the final overrider of itself. OverriderInfo& Overrider = OverridersMap[std::make_pair(Base, MD)]; assert(!Overrider.Method && "Overrider should not exist yet!"); - Overrider.Offset = Base.getBaseOffset(); + Overrider.OldOffset = Base.getBaseOffset(); + Overrider.Offset = OffsetInLayoutClass; Overrider.Method = MD; } } @@ -346,6 +370,7 @@ ComputeReturnAdjustmentBaseOffset(ASTContext &Context, void FinalOverriders::PropagateOverrider(const CXXMethodDecl *OldMD, BaseSubobject NewBase, + uint64_t OverriderOffsetInLayoutClass, const CXXMethodDecl *NewMD, SubobjectOffsetsMapTy &Offsets) { for (CXXMethodDecl::method_iterator I = OldMD->begin_overridden_methods(), @@ -389,11 +414,13 @@ void FinalOverriders::PropagateOverrider(const CXXMethodDecl *OldMD, } // Set the new overrider. - Overrider.Offset = NewBase.getBaseOffset(); + Overrider.Offset = OverriderOffsetInLayoutClass; + Overrider.OldOffset = NewBase.getBaseOffset(); Overrider.Method = NewMD; // And propagate it further. - PropagateOverrider(OverriddenMD, NewBase, NewMD, Offsets); + PropagateOverrider(OverriddenMD, NewBase, OverriderOffsetInLayoutClass, + NewMD, Offsets); } } } @@ -416,6 +443,7 @@ FinalOverriders::MergeSubobjectOffsets(const SubobjectOffsetsMapTy &NewOffsets, void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base, bool BaseSubobjectIsVisitedVBase, + uint64_t OffsetInLayoutClass, SubobjectOffsetsMapTy &Offsets) { const CXXRecordDecl *RD = Base.getBase(); const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); @@ -433,12 +461,20 @@ void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base, bool IsVisitedVirtualBase = BaseSubobjectIsVisitedVBase; uint64_t BaseOffset; + uint64_t BaseOffsetInLayoutClass; if (I->isVirtual()) { if (!VisitedVirtualBases.insert(BaseDecl)) IsVisitedVirtualBase = true; BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); + + const ASTRecordLayout &LayoutClassLayout = + Context.getASTRecordLayout(LayoutClass); + BaseOffsetInLayoutClass = + LayoutClassLayout.getVBaseClassOffset(BaseDecl); } else { BaseOffset = Layout.getBaseClassOffset(BaseDecl) + Base.getBaseOffset(); + BaseOffsetInLayoutClass = Layout.getBaseClassOffset(BaseDecl) + + OffsetInLayoutClass; } // Compute the final overriders for this base. @@ -463,13 +499,14 @@ void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base, // Here, we still want to compute the overriders for A as a base of C, // because otherwise we'll miss that C::g overrides A::f. ComputeFinalOverriders(BaseSubobject(BaseDecl, BaseOffset), - IsVisitedVirtualBase, NewOffsets); + IsVisitedVirtualBase, BaseOffsetInLayoutClass, + NewOffsets); } /// Now add the overriders for this particular subobject. /// (We don't want to do this more than once for a virtual base). if (!BaseSubobjectIsVisitedVBase) - AddOverriders(Base, NewOffsets); + AddOverriders(Base, OffsetInLayoutClass, NewOffsets); // And merge the newly discovered subobject offsets. MergeSubobjectOffsets(NewOffsets, Offsets); @@ -508,7 +545,7 @@ void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base) { } Out << "Final overriders for (" << RD->getQualifiedNameAsString() << ", "; - Out << Base.getBaseOffset() << ")\n"; + Out << Base.getBaseOffset() / 8 << ")\n"; // Now dump the overriders for this base subobject. for (CXXRecordDecl::method_iterator I = RD->method_begin(), @@ -522,7 +559,7 @@ void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base) { Out << " " << MD->getQualifiedNameAsString() << " - ("; Out << Overrider.Method->getQualifiedNameAsString(); - Out << ", " << Overrider.Offset << ')'; + Out << ", " << Overrider.OldOffset / 8 << ", " << Overrider.Offset / 8 << ')'; AdjustmentOffsetsMapTy::const_iterator AI = ReturnAdjustments.find(std::make_pair(Base, MD)); @@ -1173,15 +1210,17 @@ private: /// thunk. Since we require that a call to C::f() first convert to A*, /// C-in-D's copy of A's vtable is never referenced, so this is not /// necessary. - bool IsOverriderUsed(BaseSubobject Base, - BaseSubobject FirstBaseInPrimaryBaseChain, - uint64_t OffsetInLayoutClass, - FinalOverriders::OverriderInfo Overrider) const; + bool IsOverriderUsed(const CXXMethodDecl *Overrider, + uint64_t BaseOffsetInLayoutClass, + const CXXRecordDecl *FirstBaseInPrimaryBaseChain, + uint64_t FirstBaseOffsetInLayoutClass) const; + /// AddMethods - Add the methods of this base subobject and all its /// primary bases to the vtable components vector. - void AddMethods(BaseSubobject Base, BaseSubobject FirstBaseInPrimaryBaseChain, - uint64_t OffsetInLayoutClass, + void AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass, + const CXXRecordDecl *FirstBaseInPrimaryBaseChain, + uint64_t FirstBaseOffsetInLayoutClass, PrimaryBasesSetVectorTy &PrimaryBases); // LayoutVtable - Layout the vtable for the given base class, including its @@ -1201,6 +1240,7 @@ private: /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this /// class hierarchy. void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, + uint64_t OffsetInLayoutClass, VisitedVirtualBasesSetTy &VBases); /// LayoutVtablesForVirtualBases - Layout vtables for all virtual bases of the @@ -1222,7 +1262,7 @@ public: MostDerivedClassOffset(MostDerivedClassOffset), MostDerivedClassIsVirtual(MostDerivedClassIsVirtual), LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), - Overriders(MostDerivedClass) { + Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass) { LayoutVtable(); } @@ -1269,7 +1309,7 @@ void VtableBuilder::ComputeThisAdjustments() { Overriders.getOverrider(OverriddenBaseSubobject, MD); // Check if we need an adjustment. - if (Overrider.Offset == (int64_t)MethodInfo.BaseOffset) + if (Overrider.OldOffset == (int64_t)MethodInfo.BaseOffset) continue; uint64_t VtableIndex = MethodInfo.VtableIndex; @@ -1284,7 +1324,7 @@ void VtableBuilder::ComputeThisAdjustments() { continue; BaseSubobject OverriderBaseSubobject(Overrider.Method->getParent(), - Overrider.Offset); + Overrider.OldOffset); // Compute the adjustment offset. BaseOffset ThisAdjustmentOffset = @@ -1473,13 +1513,13 @@ OverridesIndirectMethodInBases(const CXXMethodDecl *MD, } bool -VtableBuilder::IsOverriderUsed(BaseSubobject Base, - BaseSubobject FirstBaseInPrimaryBaseChain, - uint64_t OffsetInLayoutClass, - FinalOverriders::OverriderInfo Overrider) const { +VtableBuilder::IsOverriderUsed(const CXXMethodDecl *Overrider, + uint64_t BaseOffsetInLayoutClass, + const CXXRecordDecl *FirstBaseInPrimaryBaseChain, + uint64_t FirstBaseOffsetInLayoutClass) const { // If the base and the first base in the primary base chain have the same // offsets, then this overrider will be used. - if (Base.getBaseOffset() == OffsetInLayoutClass) + if (BaseOffsetInLayoutClass == FirstBaseOffsetInLayoutClass) return true; // We know now that Base (or a direct or indirect base of it) is a primary @@ -1488,12 +1528,12 @@ VtableBuilder::IsOverriderUsed(BaseSubobject Base, // If the overrider is the first base in the primary base chain, we know // that the overrider will be used. - if (Overrider.Method->getParent() == FirstBaseInPrimaryBaseChain.getBase()) + if (Overrider->getParent() == FirstBaseInPrimaryBaseChain) return true; VtableBuilder::PrimaryBasesSetVectorTy PrimaryBases; - const CXXRecordDecl *RD = FirstBaseInPrimaryBaseChain.getBase(); + const CXXRecordDecl *RD = FirstBaseInPrimaryBaseChain; PrimaryBases.insert(RD); // Now traverse the base chain, starting with the first base, until we find @@ -1515,7 +1555,7 @@ VtableBuilder::IsOverriderUsed(BaseSubobject Base, // Now check if this is the primary base that is not a primary base in the // most derived class. if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) != - OffsetInLayoutClass) { + FirstBaseOffsetInLayoutClass) { // We found it, stop walking the chain. break; } @@ -1532,7 +1572,7 @@ VtableBuilder::IsOverriderUsed(BaseSubobject Base, // If the final overrider is an override of one of the primary bases, // then we know that it will be used. - return OverridesIndirectMethodInBases(Overrider.Method, PrimaryBases); + return OverridesIndirectMethodInBases(Overrider, PrimaryBases); } /// FindNearestOverriddenMethod - Given a method, returns the overridden method @@ -1557,17 +1597,17 @@ FindNearestOverriddenMethod(const CXXMethodDecl *MD, return 0; } -void -VtableBuilder::AddMethods(BaseSubobject Base, - BaseSubobject FirstBaseInPrimaryBaseChain, - uint64_t OffsetInLayoutClass, +void +VtableBuilder::AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass, + const CXXRecordDecl *FirstBaseInPrimaryBaseChain, + uint64_t FirstBaseOffsetInLayoutClass, PrimaryBasesSetVectorTy &PrimaryBases) { const CXXRecordDecl *RD = Base.getBase(); - const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { - uint64_t BaseOffset; + uint64_t PrimaryBaseOffset; + uint64_t PrimaryBaseOffsetInLayoutClass; if (Layout.getPrimaryBaseWasVirtual()) { assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 && "Primary vbase should have a zero offset!"); @@ -1575,17 +1615,25 @@ VtableBuilder::AddMethods(BaseSubobject Base, const ASTRecordLayout &MostDerivedClassLayout = Context.getASTRecordLayout(MostDerivedClass); - BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); + PrimaryBaseOffset = + MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); + + const ASTRecordLayout &LayoutClassLayout = + Context.getASTRecordLayout(LayoutClass); + + PrimaryBaseOffsetInLayoutClass = + LayoutClassLayout.getVBaseClassOffset(PrimaryBase); } else { assert(Layout.getBaseClassOffset(PrimaryBase) == 0 && "Primary base should have a zero offset!"); - BaseOffset = Base.getBaseOffset(); + PrimaryBaseOffset = Base.getBaseOffset(); + PrimaryBaseOffsetInLayoutClass = BaseOffsetInLayoutClass; } - // FIXME: OffsetInLayoutClass is not right here. - AddMethods(BaseSubobject(PrimaryBase, BaseOffset), - FirstBaseInPrimaryBaseChain, OffsetInLayoutClass, PrimaryBases); + AddMethods(BaseSubobject(PrimaryBase, PrimaryBaseOffset), + PrimaryBaseOffsetInLayoutClass, FirstBaseInPrimaryBaseChain, + FirstBaseOffsetInLayoutClass, PrimaryBases); if (!PrimaryBases.insert(PrimaryBase)) assert(false && "Found a duplicate primary base!"); @@ -1636,9 +1684,10 @@ VtableBuilder::AddMethods(BaseSubobject Base, MethodInfoMap.insert(std::make_pair(MD, MethodInfo)); // Check if this overrider is going to be used. - if (!IsOverriderUsed(Base, FirstBaseInPrimaryBaseChain, OffsetInLayoutClass, - Overrider)) { - const CXXMethodDecl *OverriderMD = Overrider.Method; + const CXXMethodDecl *OverriderMD = Overrider.Method; + if (!IsOverriderUsed(OverriderMD, BaseOffsetInLayoutClass, + FirstBaseInPrimaryBaseChain, + FirstBaseOffsetInLayoutClass)) { Components.push_back(VtableComponent::MakeUnusedFunction(OverriderMD)); continue; } @@ -1662,7 +1711,8 @@ void VtableBuilder::LayoutVtable() { VisitedVirtualBasesSetTy VBases; // Determine the primary virtual bases. - DeterminePrimaryVirtualBases(MostDerivedClass, VBases); + DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset, + VBases); VBases.clear(); LayoutVtablesForVirtualBases(MostDerivedClass, VBases); @@ -1700,7 +1750,8 @@ VtableBuilder::LayoutPrimaryAndSecondaryVtables(BaseSubobject Base, // Now go through all virtual member functions and add them. PrimaryBasesSetVectorTy PrimaryBases; - AddMethods(Base, Base, OffsetInLayoutClass, PrimaryBases); + AddMethods(Base, OffsetInLayoutClass, Base.getBase(), OffsetInLayoutClass, + PrimaryBases); // Compute 'this' pointer adjustments. ComputeThisAdjustments(); @@ -1771,7 +1822,8 @@ void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base, } void -VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, +VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, + uint64_t OffsetInLayoutClass, VisitedVirtualBasesSetTy &VBases) { const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); @@ -1785,8 +1837,15 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, if (isBuildingConstructorVtable()) { // Check if the base is actually a primary base in the class we use for // layout. - // FIXME: Is this check enough? - if (MostDerivedClassOffset != 0) + const ASTRecordLayout &LayoutClassLayout = + Context.getASTRecordLayout(LayoutClass); + + uint64_t PrimaryBaseOffsetInLayoutClass = + LayoutClassLayout.getVBaseClassOffset(PrimaryBase); + + // We know that the base is not a primary base in the layout class if + // the base offsets are different. + if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass) IsPrimaryVirtualBase = false; } @@ -1801,10 +1860,22 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); - if (I->isVirtual() && !VBases.insert(BaseDecl)) - continue; + uint64_t BaseOffsetInLayoutClass; + + if (I->isVirtual()) { + if (!VBases.insert(BaseDecl)) + continue; + + const ASTRecordLayout &LayoutClassLayout = + Context.getASTRecordLayout(LayoutClass); - DeterminePrimaryVirtualBases(BaseDecl, VBases); + BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl); + } else { + BaseOffsetInLayoutClass = + OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl); + } + + DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases); } } @@ -3405,7 +3476,22 @@ void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0, /*IsVirtual=*/false, AddressPoints); - GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); + GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); + + for (CXXRecordDecl::method_iterator i = RD->method_begin(), + e = RD->method_end(); i != e; ++i) { + if (!(*i)->isVirtual()) + continue; + if(!(*i)->hasInlineBody() && !(*i)->isImplicit()) + continue; + + if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) { + CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete)); + CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting)); + } else { + CGM.BuildThunksForVirtual(GlobalDecl(*i)); + } + } } llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) { @@ -3438,19 +3524,12 @@ void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) { return; } - // Emit the data. - GenerateClassData(CGM.getVtableLinkage(RD), RD); + if (Vtables.count(RD)) + return; - for (CXXRecordDecl::method_iterator i = RD->method_begin(), - e = RD->method_end(); i != e; ++i) { - if ((*i)->isVirtual() && ((*i)->hasInlineBody() || (*i)->isImplicit())) { - if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) { - CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete)); - CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting)); - } else { - CGM.BuildThunksForVirtual(GlobalDecl(*i)); - } - } - } + TemplateSpecializationKind kind = RD->getTemplateSpecializationKind(); + if (kind == TSK_ImplicitInstantiation) + CGM.DeferredVtables.push_back(RD); + else + GenerateClassData(CGM.getVtableLinkage(RD), RD); } - diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h index 6ccb011..57220d9 100644 --- a/lib/CodeGen/CGVtable.h +++ b/lib/CodeGen/CGVtable.h @@ -173,15 +173,7 @@ private: uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD); void ComputeMethodVtableIndices(const CXXRecordDecl *RD); - - /// GenerateClassData - Generate all the class data requires to be generated - /// upon definition of a KeyFunction. This includes the vtable, the - /// rtti data structure and the VTT. - /// - /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT. - void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, - const CXXRecordDecl *RD); - + llvm::GlobalVariable * GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, bool GenerateDefinition, const CXXRecordDecl *LayoutClass, @@ -245,6 +237,14 @@ public: llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD); void MaybeEmitVtable(GlobalDecl GD); + + /// GenerateClassData - Generate all the class data requires to be generated + /// upon definition of a KeyFunction. This includes the vtable, the + /// rtti data structure and the VTT. + /// + /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT. + void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, + const CXXRecordDecl *RD); }; } // end namespace CodeGen diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index d6a56da..c67948d 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -488,7 +488,15 @@ void CodeGenModule::EmitDeferred() { // Emit code for any potentially referenced deferred decls. Since a // previously unused static decl may become used during the generation of code // for a static function, iterate until no changes are made. - while (!DeferredDeclsToEmit.empty()) { + + while (!DeferredDeclsToEmit.empty() || !DeferredVtables.empty()) { + if (!DeferredVtables.empty()) { + const CXXRecordDecl *RD = DeferredVtables.back(); + DeferredVtables.pop_back(); + getVtableInfo().GenerateClassData(getVtableLinkage(RD), RD); + continue; + } + GlobalDecl D = DeferredDeclsToEmit.back(); DeferredDeclsToEmit.pop_back(); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index c86f8b4..40dc563 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -451,7 +451,9 @@ public: /// GetTargetTypeStoreSize - Return the store size, in character units, of /// the given LLVM type. CharUnits GetTargetTypeStoreSize(const llvm::Type *Ty) const; - + + std::vector<const CXXRecordDecl*> DeferredVtables; + private: /// UniqueMangledName - Unique a name by (if necessary) inserting it into the /// MangledNames string map. diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 20d54b3..2e0580f 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -214,12 +214,6 @@ bool MangleContext::shouldMangleDeclName(const NamedDecl *D) { if (!getASTContext().getLangOptions().CPlusPlus) return false; - // No mangling in an "implicit extern C" header. - if (D->getLocation().isValid() && - getASTContext().getSourceManager(). - isInExternCSystemHeader(D->getLocation())) - return false; - // Variables at global scope with non-internal linkage are not mangled if (!FD) { const DeclContext *DC = D->getDeclContext(); |