summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-03-10 17:45:58 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-03-10 17:45:58 +0000
commit27c39af73c0d7d0b97e57b3a905040d4cefc9708 (patch)
tree56c1dd85a159948815817b5a90bedb39cf9ad105 /lib/CodeGen
parentd2e6cf1d1c6468396ec057119c32aa58b1ee5ac9 (diff)
downloadFreeBSD-src-27c39af73c0d7d0b97e57b3a905040d4cefc9708.zip
FreeBSD-src-27c39af73c0d7d0b97e57b3a905040d4cefc9708.tar.gz
Update clang to r98164.
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp253
-rw-r--r--lib/CodeGen/CGDebugInfo.h73
-rw-r--r--lib/CodeGen/CGExprAgg.cpp24
-rw-r--r--lib/CodeGen/CGObjC.cpp2
-rw-r--r--lib/CodeGen/CGVtable.cpp225
-rw-r--r--lib/CodeGen/CGVtable.h18
-rw-r--r--lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--lib/CodeGen/CodeGenModule.h4
-rw-r--r--lib/CodeGen/Mangle.cpp6
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();
OpenPOWER on IntegriCloud