Update Clang for 3.5 rebase (r209713).
Change-Id: I8c9133b0f8f776dc915f270b60f94962e771bc83
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 0e94b51..e2ba70a 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -112,17 +112,14 @@
if (LexicalBlockStack.empty()) return;
SourceManager &SM = CGM.getContext().getSourceManager();
+ llvm::DIScope Scope(LexicalBlockStack.back());
PresumedLoc PCLoc = SM.getPresumedLoc(CurLoc);
- PresumedLoc PPLoc = SM.getPresumedLoc(PrevLoc);
- if (PCLoc.isInvalid() || PPLoc.isInvalid() ||
- !strcmp(PPLoc.getFilename(), PCLoc.getFilename()))
+ if (PCLoc.isInvalid() || Scope.getFilename() == PCLoc.getFilename())
return;
- llvm::MDNode *LB = LexicalBlockStack.back();
- llvm::DIScope Scope = llvm::DIScope(LB);
if (Scope.isLexicalBlockFile()) {
- llvm::DILexicalBlockFile LBF = llvm::DILexicalBlockFile(LB);
+ llvm::DILexicalBlockFile LBF = llvm::DILexicalBlockFile(Scope);
llvm::DIDescriptor D
= DBuilder.createLexicalBlockFile(LBF.getScope(),
getOrCreateFile(CurLoc));
@@ -317,11 +314,18 @@
/// CreateCompileUnit - Create new compile unit.
void CGDebugInfo::CreateCompileUnit() {
+ // Should we be asking the SourceManager for the main file name, instead of
+ // accepting it as an argument? This just causes the main file name to
+ // mismatch with source locations and create extra lexical scopes or
+ // mismatched debug info (a CU with a DW_AT_file of "-", because that's what
+ // the driver passed, but functions/other things have DW_AT_file of "<stdin>"
+ // because that's what the SourceManager says)
+
// Get absolute path name.
SourceManager &SM = CGM.getContext().getSourceManager();
std::string MainFileName = CGM.getCodeGenOpts().MainFileName;
if (MainFileName.empty())
- MainFileName = "<unknown>";
+ MainFileName = "<stdin>";
// The main file name provided via the "-main-file-name" option contains just
// the file name itself with no path information. This file name may have had
@@ -344,7 +348,7 @@
std::string SplitDwarfFile = CGM.getCodeGenOpts().SplitDwarfFile;
StringRef SplitDwarfFilename = internString(SplitDwarfFile);
- unsigned LangTag;
+ llvm::dwarf::SourceLanguage LangTag;
const LangOptions &LO = CGM.getLangOpts();
if (LO.CPlusPlus) {
if (LO.ObjC1)
@@ -379,7 +383,7 @@
/// CreateType - Get the Basic type from the cache or create a new
/// one if necessary.
llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) {
- unsigned Encoding = 0;
+ llvm::dwarf::TypeKind Encoding;
StringRef BTName;
switch (BT->getKind()) {
#define BUILTIN_TYPE(Id, SingletonId)
@@ -393,11 +397,10 @@
case BuiltinType::Void:
return llvm::DIType();
case BuiltinType::ObjCClass:
- if (ClassTy)
- return ClassTy;
- ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
- "objc_class", TheCU,
- getOrCreateMainFile(), 0);
+ if (!ClassTy)
+ ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
+ "objc_class", TheCU,
+ getOrCreateMainFile(), 0);
return ClassTy;
case BuiltinType::ObjCId: {
// typedef struct objc_class *Class;
@@ -426,12 +429,10 @@
return ObjTy;
}
case BuiltinType::ObjCSel: {
- if (SelTy)
- return SelTy;
- SelTy =
- DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
- "objc_selector", TheCU, getOrCreateMainFile(),
- 0);
+ if (!SelTy)
+ SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
+ "objc_selector", TheCU,
+ getOrCreateMainFile(), 0);
return SelTy;
}
@@ -506,7 +507,7 @@
llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty) {
// Bit size, align and offset of the type.
- unsigned Encoding = llvm::dwarf::DW_ATE_complex_float;
+ llvm::dwarf::TypeKind Encoding = llvm::dwarf::DW_ATE_complex_float;
if (Ty->isComplexIntegerType())
Encoding = llvm::dwarf::DW_ATE_lo_user;
@@ -531,7 +532,7 @@
// We will create one Derived type for one qualifier and recurse to handle any
// additional ones.
- unsigned Tag;
+ llvm::dwarf::Tag Tag;
if (Qc.hasConst()) {
Tag = llvm::dwarf::DW_TAG_const_type;
Qc.removeConst();
@@ -611,7 +612,7 @@
unsigned Line = getLineNumber(RD->getLocation());
StringRef RDName = getClassName(RD);
- unsigned Tag = 0;
+ llvm::dwarf::Tag Tag;
if (RD->isStruct() || RD->isInterface())
Tag = llvm::dwarf::DW_TAG_structure_type;
else if (RD->isUnion())
@@ -623,11 +624,13 @@
// Create the type.
SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
- return DBuilder.createForwardDecl(Tag, RDName, Ctx, DefUnit, Line, 0, 0, 0,
- FullName);
+ llvm::DICompositeType RetTy = DBuilder.createReplaceableForwardDecl(
+ Tag, RDName, Ctx, DefUnit, Line, 0, 0, 0, FullName);
+ ReplaceMap.push_back(std::make_pair(Ty, static_cast<llvm::Value *>(RetTy)));
+ return RetTy;
}
-llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,
+llvm::DIType CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
const Type *Ty,
QualType PointeeTy,
llvm::DIFile Unit) {
@@ -719,12 +722,35 @@
return BlockLiteralGeneric;
}
+llvm::DIType CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, llvm::DIFile Unit) {
+ assert(Ty->isTypeAlias());
+ llvm::DIType Src = getOrCreateType(Ty->getAliasedType(), Unit);
+
+ SmallString<128> NS;
+ llvm::raw_svector_ostream OS(NS);
+ Ty->getTemplateName().print(OS, CGM.getContext().getPrintingPolicy(), /*qualified*/ false);
+
+ TemplateSpecializationType::PrintTemplateArgumentList(
+ OS, Ty->getArgs(), Ty->getNumArgs(),
+ CGM.getContext().getPrintingPolicy());
+
+ TypeAliasDecl *AliasDecl =
+ cast<TypeAliasTemplateDecl>(Ty->getTemplateName().getAsTemplateDecl())
+ ->getTemplatedDecl();
+
+ SourceLocation Loc = AliasDecl->getLocation();
+ llvm::DIFile File = getOrCreateFile(Loc);
+ unsigned Line = getLineNumber(Loc);
+
+ llvm::DIDescriptor Ctxt = getContextDescriptor(cast<Decl>(AliasDecl->getDeclContext()));
+
+ return DBuilder.createTypedef(Src, internString(OS.str()), File, Line, Ctxt);
+}
+
llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, 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);
- if (!Src)
- return llvm::DIType();
// We don't set size information, but do specify where the typedef was
// declared.
SourceLocation Loc = Ty->getDecl()->getLocation();
@@ -808,7 +834,7 @@
unsigned fieldno = 0;
for (CXXRecordDecl::capture_const_iterator I = CXXDecl->captures_begin(),
E = CXXDecl->captures_end(); I != E; ++I, ++Field, ++fieldno) {
- const LambdaExpr::Capture C = *I;
+ const LambdaCapture &C = *I;
if (C.capturesVariable()) {
VarDecl *V = C.getCapturedVar();
llvm::DIFile VUnit = getOrCreateFile(C.getLocation());
@@ -852,7 +878,7 @@
unsigned LineNumber = getLineNumber(Var->getLocation());
StringRef VName = Var->getName();
- llvm::Constant *C = NULL;
+ llvm::Constant *C = nullptr;
if (Var->getInit()) {
const APValue *Value = Var->evaluateValue();
if (Value) {
@@ -1096,7 +1122,7 @@
MethodTy, /*isLocalToUnit=*/false,
/* isDefinition=*/ false,
Virtuality, VIndex, ContainingType,
- Flags, CGM.getLangOpts().Optimize, NULL,
+ Flags, CGM.getLangOpts().Optimize, nullptr,
TParamsArray);
SPCache[Method->getCanonicalDecl()] = llvm::WeakVH(SP);
@@ -1224,7 +1250,7 @@
->getTypeForDecl())
: CGM.getContext().getPointerType(D->getType());
llvm::DIType TTy = getOrCreateType(T, Unit);
- llvm::Value *V = 0;
+ llvm::Value *V = nullptr;
// Variable pointer template parameters have a value that is the address
// of the variable.
if (const VarDecl *VD = dyn_cast<VarDecl>(D))
@@ -1256,7 +1282,7 @@
case TemplateArgument::NullPtr: {
QualType T = TA.getNullPtrType();
llvm::DIType TTy = getOrCreateType(T, Unit);
- llvm::Value *V = 0;
+ llvm::Value *V = nullptr;
// Special case member data pointer null values since they're actually -1
// instead of zero.
if (const MemberPointerType *MPT =
@@ -1286,7 +1312,7 @@
llvm::DITemplateValueParameter TVP =
DBuilder.createTemplateParameterPack(
TheCU, Name, llvm::DIType(),
- CollectTemplateParams(NULL, TA.getPackAsArray(), Unit));
+ CollectTemplateParams(nullptr, TA.getPackAsArray(), Unit));
TemplateParams.push_back(TVP);
} break;
case TemplateArgument::Expression: {
@@ -1330,14 +1356,11 @@
llvm::DIArray CGDebugInfo::
CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TSpecial,
llvm::DIFile Unit) {
- llvm::PointerUnion<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *>
- PU = TSpecial->getSpecializedTemplateOrPartial();
-
- TemplateParameterList *TPList = PU.is<ClassTemplateDecl *>() ?
- PU.get<ClassTemplateDecl *>()->getTemplateParameters() :
- PU.get<ClassTemplatePartialSpecializationDecl *>()->getTemplateParameters();
- const TemplateArgumentList &TAList = TSpecial->getTemplateInstantiationArgs();
+ // Always get the full list of parameters, not just the ones from
+ // the specialization.
+ TemplateParameterList *TPList =
+ TSpecial->getSpecializedTemplate()->getTemplateParameters();
+ const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
return CollectTemplateParams(TPList, TAList.asArray(), Unit);
}
@@ -1408,6 +1431,21 @@
return T;
}
+void CGDebugInfo::completeType(const EnumDecl *ED) {
+ if (DebugKind <= CodeGenOptions::DebugLineTablesOnly)
+ return;
+ QualType Ty = CGM.getContext().getEnumType(ED);
+ void* TyPtr = Ty.getAsOpaquePtr();
+ auto I = TypeCache.find(TyPtr);
+ if (I == TypeCache.end() ||
+ !llvm::DIType(cast<llvm::MDNode>(static_cast<llvm::Value *>(I->second)))
+ .isForwardDecl())
+ return;
+ llvm::DIType Res = CreateTypeDefinition(Ty->castAs<EnumType>());
+ assert(!Res.isForwardDecl());
+ TypeCache[TyPtr] = Res;
+}
+
void CGDebugInfo::completeType(const RecordDecl *RD) {
if (DebugKind > CodeGenOptions::LimitedDebugInfo ||
!CGM.getLangOpts().CPlusPlus)
@@ -1433,11 +1471,13 @@
return;
QualType Ty = CGM.getContext().getRecordType(RD);
void* TyPtr = Ty.getAsOpaquePtr();
- if (CompletedTypeCache.count(TyPtr))
+ auto I = TypeCache.find(TyPtr);
+ if (I != TypeCache.end() &&
+ !llvm::DIType(cast<llvm::MDNode>(static_cast<llvm::Value *>(I->second)))
+ .isForwardDecl())
return;
llvm::DIType Res = CreateTypeDefinition(Ty->castAs<RecordType>());
assert(!Res.isForwardDecl());
- CompletedTypeCache[TyPtr] = Res;
TypeCache[TyPtr] = Res;
}
@@ -1525,9 +1565,6 @@
LexicalBlockStack.push_back(&*FwdDecl);
RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
- // Add this to the completed-type cache while we're completing it recursively.
- CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
-
// Convert all the elements.
SmallVector<llvm::Value *, 16> EltTys;
// what about nested types?
@@ -1599,20 +1636,28 @@
// Get overall information about the record type for the debug info.
llvm::DIFile DefUnit = getOrCreateFile(ID->getLocation());
unsigned Line = getLineNumber(ID->getLocation());
- unsigned RuntimeLang = TheCU.getLanguage();
+ llvm::dwarf::SourceLanguage RuntimeLang = TheCU.getLanguage();
// If this is just a forward declaration return a special forward-declaration
// debug type since we won't be able to lay out the entire type.
ObjCInterfaceDecl *Def = ID->getDefinition();
- if (!Def) {
- llvm::DIType FwdDecl =
- DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
- ID->getName(), TheCU, DefUnit, Line,
- RuntimeLang);
+ if (!Def || !Def->getImplementation()) {
+ llvm::DIType FwdDecl = DBuilder.createReplaceableForwardDecl(
+ llvm::dwarf::DW_TAG_structure_type, ID->getName(), TheCU, DefUnit, Line,
+ RuntimeLang);
+ ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
return FwdDecl;
}
- ID = Def;
+
+ return CreateTypeDefinition(Ty, Unit);
+}
+
+llvm::DIType CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty, llvm::DIFile Unit) {
+ ObjCInterfaceDecl *ID = Ty->getDecl();
+ llvm::DIFile DefUnit = getOrCreateFile(ID->getLocation());
+ unsigned Line = getLineNumber(ID->getLocation());
+ unsigned RuntimeLang = TheCU.getLanguage();
// Bit size, align and offset of the type.
uint64_t Size = CGM.getContext().getTypeSize(Ty);
@@ -1627,10 +1672,8 @@
Line, Size, Align, Flags,
llvm::DIType(), llvm::DIArray(), RuntimeLang);
- // Otherwise, insert it into the CompletedTypeCache so that recursive uses
- // will find it and we're emitting the complete type.
- QualType QualTy = QualType(Ty, 0);
- CompletedTypeCache[QualTy.getAsOpaquePtr()] = RealDecl;
+ QualType QTy(Ty, 0);
+ TypeCache[QTy.getAsOpaquePtr()] = RealDecl;
// Push the struct on region stack.
LexicalBlockStack.push_back(static_cast<llvm::MDNode*>(RealDecl));
@@ -1722,7 +1765,7 @@
else if (Field->getAccessControl() == ObjCIvarDecl::Private)
Flags = llvm::DIDescriptor::FlagPrivate;
- llvm::MDNode *PropertyNode = NULL;
+ llvm::MDNode *PropertyNode = nullptr;
if (ObjCImplementationDecl *ImpD = ID->getImplementation()) {
if (ObjCPropertyImplDecl *PImpD =
ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) {
@@ -1754,12 +1797,6 @@
llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
RealDecl.setTypeArray(Elements);
- // If the implementation is not yet set, we do not want to mark it
- // as complete. An implementation may declare additional
- // private ivars that we would miss otherwise.
- if (ID->getImplementation() == 0)
- CompletedTypeCache.erase(QualTy.getAsOpaquePtr());
-
LexicalBlockStack.pop_back();
return RealDecl;
}
@@ -1890,11 +1927,27 @@
llvm::DIFile DefUnit = getOrCreateFile(ED->getLocation());
unsigned Line = getLineNumber(ED->getLocation());
StringRef EDName = ED->getName();
- return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_enumeration_type,
- EDName, EDContext, DefUnit, Line, 0,
- Size, Align, FullName);
+ llvm::DIType RetTy = DBuilder.createReplaceableForwardDecl(
+ llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line,
+ 0, Size, Align, FullName);
+ ReplaceMap.push_back(std::make_pair(Ty, static_cast<llvm::Value *>(RetTy)));
+ return RetTy;
}
+ return CreateTypeDefinition(Ty);
+}
+
+llvm::DIType CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) {
+ const EnumDecl *ED = Ty->getDecl();
+ uint64_t Size = 0;
+ uint64_t Align = 0;
+ if (!ED->getTypeForDecl()->isIncompleteType()) {
+ Size = CGM.getContext().getTypeSize(ED->getTypeForDecl());
+ Align = CGM.getContext().getTypeAlign(ED->getTypeForDecl());
+ }
+
+ SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
+
// Create DIEnumerator elements for each enumerator.
SmallVector<llvm::Value *, 16> Enumerators;
ED = ED->getDefinition();
@@ -1932,9 +1985,12 @@
switch (T->getTypeClass()) {
default:
return C.getQualifiedType(T.getTypePtr(), Quals);
- case Type::TemplateSpecialization:
- T = cast<TemplateSpecializationType>(T)->desugar();
- break;
+ case Type::TemplateSpecialization: {
+ const auto *Spec = cast<TemplateSpecializationType>(T);
+ if (Spec->isTypeAlias())
+ return C.getQualifiedType(T.getTypePtr(), Quals);
+ T = Spec->desugar();
+ break; }
case Type::TypeOfExpr:
T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();
break;
@@ -1979,16 +2035,7 @@
// Unwrap the type as needed for debug information.
Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());
- // Check for existing entry.
- if (Ty->getTypeClass() == Type::ObjCInterface) {
- llvm::Value *V = getCachedInterfaceTypeOrNull(Ty);
- if (V)
- return llvm::DIType(cast<llvm::MDNode>(V));
- else return llvm::DIType();
- }
-
- llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
- TypeCache.find(Ty.getAsOpaquePtr());
+ auto it = TypeCache.find(Ty.getAsOpaquePtr());
if (it != TypeCache.end()) {
// Verify that the debug info still exists.
if (llvm::Value *V = it->second)
@@ -1998,27 +2045,6 @@
return llvm::DIType();
}
-/// getCompletedTypeOrNull - Get the type from the cache or return null if it
-/// doesn't exist.
-llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) {
-
- // Unwrap the type as needed for debug information.
- Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());
-
- // Check for existing entry.
- llvm::Value *V = 0;
- llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
- CompletedTypeCache.find(Ty.getAsOpaquePtr());
- if (it != CompletedTypeCache.end())
- V = it->second;
- else {
- V = getCachedInterfaceTypeOrNull(Ty);
- }
-
- // Verify that any cached debug info still exists.
- return llvm::DIType(cast_or_null<llvm::MDNode>(V));
-}
-
void CGDebugInfo::completeTemplateDefinition(
const ClassTemplateSpecializationDecl &SD) {
if (DebugKind <= CodeGenOptions::DebugLineTablesOnly)
@@ -2030,22 +2056,6 @@
RetainedTypes.push_back(CGM.getContext().getRecordType(&SD).getAsOpaquePtr());
}
-/// getCachedInterfaceTypeOrNull - Get the type from the interface
-/// cache, unless it needs to regenerated. Otherwise return null.
-llvm::Value *CGDebugInfo::getCachedInterfaceTypeOrNull(QualType Ty) {
- // Is there a cached interface that hasn't changed?
- llvm::DenseMap<void *, std::pair<llvm::WeakVH, unsigned > >
- ::iterator it1 = ObjCInterfaceCache.find(Ty.getAsOpaquePtr());
-
- if (it1 != ObjCInterfaceCache.end())
- if (ObjCInterfaceDecl* Decl = getObjCInterfaceDecl(Ty))
- if (Checksum(Decl) == it1->second.second)
- // Return cached forward declaration.
- return it1->second.first;
-
- return 0;
-}
-
/// getOrCreateType - Get the type from the cache or create a new
/// one if necessary.
llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
@@ -2055,7 +2065,7 @@
// Unwrap the type as needed for debug information.
Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());
- if (llvm::DIType T = getCompletedTypeOrNull(Ty))
+ if (llvm::DIType T = getTypeOrNull(Ty))
return T;
// Otherwise create the type.
@@ -2065,39 +2075,6 @@
// And update the type cache.
TypeCache[TyPtr] = Res;
- // FIXME: this getTypeOrNull call seems silly when we just inserted the type
- // into the cache - but getTypeOrNull has a special case for cached interface
- // types. We should probably just pull that out as a special case for the
- // "else" block below & skip the otherwise needless lookup.
- llvm::DIType TC = getTypeOrNull(Ty);
- if (TC && TC.isForwardDecl())
- ReplaceMap.push_back(std::make_pair(TyPtr, static_cast<llvm::Value*>(TC)));
- else if (ObjCInterfaceDecl* Decl = getObjCInterfaceDecl(Ty)) {
- // Interface types may have elements added to them by a
- // subsequent implementation or extension, so we keep them in
- // the ObjCInterfaceCache together with a checksum. Instead of
- // the (possibly) incomplete interface type, we return a forward
- // declaration that gets RAUW'd in CGDebugInfo::finalize().
- std::pair<llvm::WeakVH, unsigned> &V = ObjCInterfaceCache[TyPtr];
- if (V.first)
- return llvm::DIType(cast<llvm::MDNode>(V.first));
- TC = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
- Decl->getName(), TheCU, Unit,
- getLineNumber(Decl->getLocation()),
- TheCU.getLanguage());
- // Store the forward declaration in the cache.
- V.first = TC;
- V.second = Checksum(Decl);
-
- // Register the type for replacement in finalize().
- ReplaceMap.push_back(std::make_pair(TyPtr, static_cast<llvm::Value*>(TC)));
-
- return TC;
- }
-
- if (!Res.isForwardDecl())
- CompletedTypeCache[TyPtr] = Res;
-
return Res;
}
@@ -2109,7 +2086,7 @@
// a checksum.
unsigned Sum = 0;
for (const ObjCIvarDecl *Ivar = ID->all_declared_ivar_begin();
- Ivar != 0; Ivar = Ivar->getNextIvar())
+ Ivar != nullptr; Ivar = Ivar->getNextIvar())
++Sum;
return Sum;
@@ -2123,7 +2100,7 @@
case Type::ObjCInterface:
return cast<ObjCInterfaceType>(Ty)->getDecl();
default:
- return 0;
+ return nullptr;
}
}
@@ -2133,7 +2110,7 @@
if (Ty.hasLocalQualifiers())
return CreateQualifiedType(Ty, Unit);
- const char *Diag = 0;
+ const char *Diag = nullptr;
// Work out details of type.
switch (Ty->getTypeClass()) {
@@ -2191,8 +2168,10 @@
case Type::Atomic:
return CreateType(cast<AtomicType>(Ty), Unit);
- case Type::Attributed:
case Type::TemplateSpecialization:
+ return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
+
+ case Type::Attributed:
case Type::Elaborated:
case Type::Paren:
case Type::SubstTemplateTypeParm:
@@ -2236,10 +2215,6 @@
// correct order if the full type is needed.
Res.setTypeArray(T.getTypeArray());
- if (T && T.isForwardDecl())
- ReplaceMap.push_back(
- std::make_pair(QTy.getAsOpaquePtr(), static_cast<llvm::Value *>(T)));
-
// And update the type cache.
TypeCache[QTy.getAsOpaquePtr()] = Res;
return Res;
@@ -2259,13 +2234,6 @@
// If we ended up creating the type during the context chain construction,
// just return that.
- // FIXME: this could be dealt with better if the type was recorded as
- // completed before we started this (see the CompletedTypeCache usage in
- // CGDebugInfo::CreateTypeDefinition(const RecordType*) - that would need to
- // be pushed to before context creation, but after it was known to be
- // destined for completion (might still have an issue if this caller only
- // required a declaration but the context construction ended up creating a
- // definition)
llvm::DICompositeType T(getTypeOrNull(CGM.getContext().getRecordType(RD)));
if (T && (!T.isForwardDecl() || !RD->getDefinition()))
return T;
@@ -2473,7 +2441,10 @@
}
/// EmitFunctionStart - Constructs the debug code for entering a function.
-void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
+void CGDebugInfo::EmitFunctionStart(GlobalDecl GD,
+ SourceLocation Loc,
+ SourceLocation ScopeLoc,
+ QualType FnType,
llvm::Function *Fn,
CGBuilderTy &Builder) {
@@ -2483,24 +2454,7 @@
FnBeginRegionCount.push_back(LexicalBlockStack.size());
const Decl *D = GD.getDecl();
-
- // Use the location of the start of the function to determine where
- // the function definition is located. By default use the location
- // of the declaration as the location for the subprogram. A function
- // may lack a declaration in the source code if it is created by code
- // gen. (examples: _GLOBAL__I_a, __cxx_global_array_dtor, thunk).
- bool HasDecl = (D != 0);
- SourceLocation Loc;
- if (HasDecl) {
- Loc = D->getLocation();
-
- // If this is a function specialization then use the pattern body
- // as the location for the function.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- if (const FunctionDecl *SpecDecl = FD->getTemplateInstantiationPattern())
- if (SpecDecl->hasBody(SpecDecl))
- Loc = SpecDecl->getLocation();
- }
+ bool HasDecl = (D != nullptr);
unsigned Flags = 0;
llvm::DIFile Unit = getOrCreateFile(Loc);
@@ -2560,9 +2514,14 @@
if (!Name.empty() && Name[0] == '\01')
Name = Name.substr(1);
- unsigned LineNo = getLineNumber(Loc);
- if (!HasDecl || D->isImplicit())
+ if (!HasDecl || D->isImplicit()) {
Flags |= llvm::DIDescriptor::FlagArtificial;
+ // Artificial functions without a location should not silently reuse CurLoc.
+ if (Loc.isInvalid())
+ CurLoc = SourceLocation();
+ }
+ unsigned LineNo = getLineNumber(Loc);
+ unsigned ScopeLine = getLineNumber(ScopeLoc);
// FIXME: The function declaration we're constructing here is mostly reusing
// declarations from CXXMethodDecl and not constructing new ones for arbitrary
@@ -2573,7 +2532,7 @@
DBuilder.createFunction(FDContext, Name, LinkageName, Unit, LineNo,
getOrCreateFunctionType(D, FnType, Unit),
Fn->hasInternalLinkage(), true /*definition*/,
- getLineNumber(CurLoc), Flags,
+ ScopeLine, Flags,
CGM.getLangOpts().Optimize, Fn, TParamsArray,
getFunctionDeclaration(D));
if (HasDecl)
@@ -2731,7 +2690,7 @@
}
FType = Type;
- llvm::DIType FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+ llvm::DIType FieldTy = getOrCreateType(FType, Unit);
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().toBits(Align);
@@ -2751,7 +2710,7 @@
}
/// EmitDeclare - Emit local variable declaration debug info.
-void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,
+void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::dwarf::LLVMConstants Tag,
llvm::Value *Storage,
unsigned ArgNo, CGBuilderTy &Builder) {
assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);
@@ -2888,7 +2847,6 @@
llvm::DIType Ty) {
llvm::DIType CachedTy = getTypeOrNull(QualTy);
if (CachedTy) Ty = CachedTy;
- else DEBUG(llvm::dbgs() << "No cached type for self.");
return DBuilder.createObjectPointerType(Ty);
}
@@ -2899,7 +2857,7 @@
assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);
assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
- if (Builder.GetInsertBlock() == 0)
+ if (Builder.GetInsertBlock() == nullptr)
return;
bool isByRef = VD->hasAttr<BlocksAttr>();
@@ -3029,7 +2987,7 @@
BlockLayoutChunk chunk;
chunk.OffsetInBits =
blockLayout->getElementOffsetInBits(block.CXXThisIndex);
- chunk.Capture = 0;
+ chunk.Capture = nullptr;
chunks.push_back(chunk);
}
@@ -3149,6 +3107,37 @@
return T;
}
+/// Recursively collect all of the member fields of a global anonymous decl and
+/// create static variables for them. The first time this is called it needs
+/// to be on a union and then from there we can have additional unnamed fields.
+llvm::DIGlobalVariable
+CGDebugInfo::CollectAnonRecordDecls(const RecordDecl *RD, llvm::DIFile Unit,
+ unsigned LineNo, StringRef LinkageName,
+ llvm::GlobalVariable *Var,
+ llvm::DIDescriptor DContext) {
+ llvm::DIGlobalVariable GV;
+
+ for (const auto *Field : RD->fields()) {
+ llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
+ StringRef FieldName = Field->getName();
+
+ // Ignore unnamed fields, but recurse into anonymous records.
+ if (FieldName.empty()) {
+ const RecordType *RT = dyn_cast<RecordType>(Field->getType());
+ if (RT)
+ GV = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
+ Var, DContext);
+ continue;
+ }
+ // Use VarDecl's Tag, Scope and Line number.
+ GV = DBuilder.createStaticVariable(DContext, FieldName, LinkageName, Unit,
+ LineNo, FieldTy,
+ Var->hasInternalLinkage(), Var,
+ llvm::DIDerivedType());
+ }
+ return GV;
+}
+
/// EmitGlobalVariable - Emit information about a global variable.
void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
const VarDecl *D) {
@@ -3169,19 +3158,35 @@
T = CGM.getContext().getConstantArrayType(ET, ConstVal,
ArrayType::Normal, 0);
}
+
StringRef DeclName = D->getName();
StringRef LinkageName;
- if (D->getDeclContext() && !isa<FunctionDecl>(D->getDeclContext())
- && !isa<ObjCMethodDecl>(D->getDeclContext()))
+ if (D->getDeclContext() && !isa<FunctionDecl>(D->getDeclContext()) &&
+ !isa<ObjCMethodDecl>(D->getDeclContext()))
LinkageName = Var->getName();
if (LinkageName == DeclName)
LinkageName = StringRef();
+
llvm::DIDescriptor DContext =
getContextDescriptor(dyn_cast<Decl>(D->getDeclContext()));
- llvm::DIGlobalVariable GV = DBuilder.createStaticVariable(
- DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
- Var->hasInternalLinkage(), Var,
- getOrCreateStaticDataMemberDeclarationOrNull(D));
+
+ // Attempt to store one global variable for the declaration - even if we
+ // emit a lot of fields.
+ llvm::DIGlobalVariable GV;
+
+ // If this is an anonymous union then we'll want to emit a global
+ // variable for each member of the anonymous union so that it's possible
+ // to find the name of any field in the union.
+ if (T->isUnionType() && DeclName.empty()) {
+ const RecordDecl *RD = cast<RecordType>(T)->getDecl();
+ assert(RD->isAnonymousStructOrUnion() && "unnamed non-anonymous struct or union?");
+ GV = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
+ } else {
+ GV = DBuilder.createStaticVariable(
+ DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
+ Var->hasInternalLinkage(), Var,
+ getOrCreateStaticDataMemberDeclarationOrNull(D));
+ }
DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(GV)));
}
@@ -3227,10 +3232,20 @@
// Do not use DIGlobalVariable for enums.
if (Ty.getTag() == llvm::dwarf::DW_TAG_enumeration_type)
return;
+ // Do not emit separate definitions for function local const/statics.
+ if (isa<FunctionDecl>(VD->getDeclContext()))
+ return;
+ VD = cast<ValueDecl>(VD->getCanonicalDecl());
+ auto pair = DeclCache.insert(std::make_pair(VD, llvm::WeakVH()));
+ if (!pair.second)
+ return;
+ llvm::DIDescriptor DContext =
+ getContextDescriptor(dyn_cast<Decl>(VD->getDeclContext()));
llvm::DIGlobalVariable GV = DBuilder.createStaticVariable(
- Unit, Name, Name, Unit, getLineNumber(VD->getLocation()), Ty, true, Init,
+ DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty,
+ true, Init,
getOrCreateStaticDataMemberDeclarationOrNull(cast<VarDecl>(VD)));
- DeclCache.insert(std::make_pair(VD->getCanonicalDecl(), llvm::WeakVH(GV)));
+ pair.first->second = llvm::WeakVH(GV);
}
llvm::DIScope CGDebugInfo::getCurrentContextDescriptor(const Decl *D) {
@@ -3266,20 +3281,20 @@
llvm::DIImportedEntity
CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) {
if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo)
- return llvm::DIImportedEntity(0);
+ return llvm::DIImportedEntity(nullptr);
llvm::WeakVH &VH = NamespaceAliasCache[&NA];
if (VH)
return llvm::DIImportedEntity(cast<llvm::MDNode>(VH));
- llvm::DIImportedEntity R(0);
+ llvm::DIImportedEntity R(nullptr);
if (const NamespaceAliasDecl *Underlying =
dyn_cast<NamespaceAliasDecl>(NA.getAliasedNamespace()))
// This could cache & dedup here rather than relying on metadata deduping.
- R = DBuilder.createImportedModule(
+ R = DBuilder.createImportedDeclaration(
getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())),
EmitNamespaceAlias(*Underlying), getLineNumber(NA.getLocation()),
NA.getName());
else
- R = DBuilder.createImportedModule(
+ R = DBuilder.createImportedDeclaration(
getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())),
getOrCreateNameSpace(cast<NamespaceDecl>(NA.getAliasedNamespace())),
getLineNumber(NA.getLocation()), NA.getName());
@@ -3308,23 +3323,27 @@
}
void CGDebugInfo::finalize() {
- for (std::vector<std::pair<void *, llvm::WeakVH> >::const_iterator VI
- = ReplaceMap.begin(), VE = ReplaceMap.end(); VI != VE; ++VI) {
- llvm::DIType Ty, RepTy;
- // Verify that the debug info still exists.
- if (llvm::Value *V = VI->second)
- Ty = llvm::DIType(cast<llvm::MDNode>(V));
+ // Creating types might create further types - invalidating the current
+ // element and the size(), so don't cache/reference them.
+ for (size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
+ ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
+ E.Decl.replaceAllUsesWith(CGM.getLLVMContext(),
+ E.Type->getDecl()->getDefinition()
+ ? CreateTypeDefinition(E.Type, E.Unit)
+ : E.Decl);
+ }
- llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
- TypeCache.find(VI->first);
- if (it != TypeCache.end()) {
- // Verify that the debug info still exists.
- if (llvm::Value *V = it->second)
- RepTy = llvm::DIType(cast<llvm::MDNode>(V));
- }
+ for (auto p : ReplaceMap) {
+ assert(p.second);
+ llvm::DIType Ty(cast<llvm::MDNode>(p.second));
+ assert(Ty.isForwardDecl());
- if (Ty && Ty.isForwardDecl() && RepTy)
- Ty.replaceAllUsesWith(RepTy);
+ auto it = TypeCache.find(p.first);
+ assert(it != TypeCache.end());
+ assert(it->second);
+
+ llvm::DIType RepTy(cast<llvm::MDNode>(it->second));
+ Ty.replaceAllUsesWith(CGM.getLLVMContext(), RepTy);
}
// We keep our own list of retained types, because we need to look