Updated to Clang 3.5a.
Change-Id: I8127eb568f674c2e72635b639a3295381fe8af82
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index fcb26f0..0e94b51 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -37,7 +37,7 @@
#include "llvm/IR/Module.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
+#include "llvm/Support/Path.h"
using namespace clang;
using namespace clang::CodeGen;
@@ -52,30 +52,35 @@
"Region stack mismatch, stack not empty!");
}
-
-NoLocation::NoLocation(CodeGenFunction &CGF, CGBuilderTy &B)
- : DI(CGF.getDebugInfo()), Builder(B) {
+SaveAndRestoreLocation::SaveAndRestoreLocation(CodeGenFunction &CGF,
+ CGBuilderTy &B)
+ : DI(CGF.getDebugInfo()), Builder(B) {
if (DI) {
SavedLoc = DI->getLocation();
DI->CurLoc = SourceLocation();
- Builder.SetCurrentDebugLocation(llvm::DebugLoc());
}
}
+SaveAndRestoreLocation::~SaveAndRestoreLocation() {
+ if (DI)
+ DI->EmitLocation(Builder, SavedLoc);
+}
+
+NoLocation::NoLocation(CodeGenFunction &CGF, CGBuilderTy &B)
+ : SaveAndRestoreLocation(CGF, B) {
+ if (DI)
+ Builder.SetCurrentDebugLocation(llvm::DebugLoc());
+}
+
NoLocation::~NoLocation() {
- if (DI) {
+ if (DI)
assert(Builder.getCurrentDebugLocation().isUnknown());
- DI->CurLoc = SavedLoc;
- }
}
ArtificialLocation::ArtificialLocation(CodeGenFunction &CGF, CGBuilderTy &B)
- : DI(CGF.getDebugInfo()), Builder(B) {
- if (DI) {
- SavedLoc = DI->getLocation();
- DI->CurLoc = SourceLocation();
+ : SaveAndRestoreLocation(CGF, B) {
+ if (DI)
Builder.SetCurrentDebugLocation(llvm::DebugLoc());
- }
}
void ArtificialLocation::Emit() {
@@ -91,10 +96,8 @@
}
ArtificialLocation::~ArtificialLocation() {
- if (DI) {
+ if (DI)
assert(Builder.getCurrentDebugLocation().getLine() == 0);
- DI->CurLoc = SavedLoc;
- }
}
void CGDebugInfo::setLocation(SourceLocation Loc) {
@@ -225,34 +228,20 @@
/// getClassName - Get class name including template argument list.
StringRef
CGDebugInfo::getClassName(const RecordDecl *RD) {
- const ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(RD);
- if (!Spec)
+ // quick optimization to avoid having to intern strings that are already
+ // stored reliably elsewhere
+ if (!isa<ClassTemplateSpecializationDecl>(RD))
return RD->getName();
- const TemplateArgument *Args;
- unsigned NumArgs;
- if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
- const TemplateSpecializationType *TST =
- cast<TemplateSpecializationType>(TAW->getType());
- Args = TST->getArgs();
- NumArgs = TST->getNumArgs();
- } else {
- const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- Args = TemplateArgs.data();
- NumArgs = TemplateArgs.size();
- }
- StringRef Name = RD->getIdentifier()->getName();
- PrintingPolicy Policy(CGM.getLangOpts());
- SmallString<128> TemplateArgList;
+ SmallString<128> Name;
{
- llvm::raw_svector_ostream OS(TemplateArgList);
- TemplateSpecializationType::PrintTemplateArgumentList(OS, Args, NumArgs,
- Policy);
+ llvm::raw_svector_ostream OS(Name);
+ RD->getNameForDiagnostic(OS, CGM.getContext().getPrintingPolicy(),
+ /*Qualified*/ false);
}
// Copy this name on the side and use its reference.
- return internString(Name, TemplateArgList);
+ return internString(Name);
}
/// getOrCreateFile - Get the file debug info descriptor for the input location.
@@ -342,9 +331,9 @@
if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
MainFileDir = MainFile->getDir()->getName();
if (MainFileDir != ".") {
- llvm::SmallString<1024> MainFileDirSS(MainFileDir);
- llvm::sys::path::append(MainFileDirSS, MainFileName);
- MainFileName = MainFileDirSS.str();
+ llvm::SmallString<1024> MainFileDirSS(MainFileDir);
+ llvm::sys::path::append(MainFileDirSS, MainFileName);
+ MainFileName = MainFileDirSS.str();
}
}
@@ -379,10 +368,12 @@
// Create new compile unit.
// FIXME - Eliminate TheCU.
- TheCU = DBuilder.createCompileUnit(LangTag, Filename, getCurrentDirname(),
- Producer, LO.Optimize,
- CGM.getCodeGenOpts().DwarfDebugFlags,
- RuntimeVers, SplitDwarfFilename);
+ TheCU = DBuilder.createCompileUnit(
+ LangTag, Filename, getCurrentDirname(), Producer, LO.Optimize,
+ CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers, SplitDwarfFilename,
+ DebugKind == CodeGenOptions::DebugLineTablesOnly
+ ? llvm::DIBuilder::LineTablesOnly
+ : llvm::DIBuilder::FullDebug);
}
/// CreateType - Get the Basic type from the cache or create a new
@@ -736,14 +727,16 @@
return llvm::DIType();
// We don't set size information, but do specify where the typedef was
// declared.
- unsigned Line = getLineNumber(Ty->getDecl()->getLocation());
+ SourceLocation Loc = Ty->getDecl()->getLocation();
+ llvm::DIFile File = getOrCreateFile(Loc);
+ unsigned Line = getLineNumber(Loc);
const TypedefNameDecl *TyDecl = Ty->getDecl();
llvm::DIDescriptor TypedefContext =
getContextDescriptor(cast<Decl>(Ty->getDecl()->getDeclContext()));
return
- DBuilder.createTypedef(Src, TyDecl->getName(), Unit, Line, TypedefContext);
+ DBuilder.createTypedef(Src, TyDecl->getName(), File, Line, TypedefContext);
}
llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
@@ -751,15 +744,17 @@
SmallVector<llvm::Value *, 16> EltTys;
// Add the result type at least.
- EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit));
+ EltTys.push_back(getOrCreateType(Ty->getReturnType(), Unit));
// Set up remainder of arguments if there is a prototype.
- // FIXME: IF NOT, HOW IS THIS REPRESENTED? llvm-gcc doesn't represent '...'!
+ // otherwise emit it as a variadic function.
if (isa<FunctionNoProtoType>(Ty))
EltTys.push_back(DBuilder.createUnspecifiedParameter());
else if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(Ty)) {
- for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i)
- EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit));
+ for (unsigned i = 0, e = FPT->getNumParams(); i != e; ++i)
+ EltTys.push_back(getOrCreateType(FPT->getParamType(i), Unit));
+ if (FPT->isVariadic())
+ EltTys.push_back(DBuilder.createUnspecifiedParameter());
}
llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys);
@@ -784,7 +779,7 @@
uint64_t sizeInBits = 0;
unsigned alignInBits = 0;
if (!type->isIncompleteArrayType()) {
- llvm::tie(sizeInBits, alignInBits) = CGM.getContext().getTypeInfo(type);
+ std::tie(sizeInBits, alignInBits) = CGM.getContext().getTypeInfo(type);
if (sizeInBitsOverride)
sizeInBits = sizeInBitsOverride;
@@ -926,9 +921,8 @@
// Static and non-static members should appear in the same order as
// the corresponding declarations in the source program.
- for (RecordDecl::decl_iterator I = record->decls_begin(),
- E = record->decls_end(); I != E; ++I)
- if (const VarDecl *V = dyn_cast<VarDecl>(*I)) {
+ for (const auto *I : record->decls())
+ if (const auto *V = dyn_cast<VarDecl>(I)) {
// Reuse the existing static member declaration if one exists
llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator MI =
StaticDataMemberCache.find(V->getCanonicalDecl());
@@ -939,7 +933,7 @@
llvm::DIDerivedType(cast<llvm::MDNode>(MI->second)));
} else
elements.push_back(CreateRecordStaticField(V, RecordTy));
- } else if (FieldDecl *field = dyn_cast<FieldDecl>(*I)) {
+ } else if (const auto *field = dyn_cast<FieldDecl>(I)) {
CollectRecordNormalField(field, layout.getFieldOffset(fieldNo),
tunit, elements, RecordTy);
@@ -1005,7 +999,13 @@
llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);
- return DBuilder.createSubroutineType(Unit, EltTypeArray);
+ unsigned Flags = 0;
+ if (Func->getExtProtoInfo().RefQualifier == RQ_LValue)
+ Flags |= llvm::DIDescriptor::FlagLValueReference;
+ if (Func->getExtProtoInfo().RefQualifier == RQ_RValue)
+ Flags |= llvm::DIDescriptor::FlagRValueReference;
+
+ return DBuilder.createSubroutineType(Unit, EltTypeArray, Flags);
}
/// isFunctionLocalClass - Return true if CXXRecordDecl is defined
@@ -1084,6 +1084,10 @@
}
if (Method->hasPrototype())
Flags |= llvm::DIDescriptor::FlagPrototyped;
+ if (Method->getRefQualifier() == RQ_LValue)
+ Flags |= llvm::DIDescriptor::FlagLValueReference;
+ if (Method->getRefQualifier() == RQ_RValue)
+ Flags |= llvm::DIDescriptor::FlagRValueReference;
llvm::DIArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
llvm::DISubprogram SP =
@@ -1111,9 +1115,8 @@
// Since we want more than just the individual member decls if we
// have templated functions iterate over every declaration to gather
// the functions.
- for(DeclContext::decl_iterator I = RD->decls_begin(),
- E = RD->decls_end(); I != E; ++I) {
- if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*I)) {
+ for(const auto *I : RD->decls()) {
+ if (const auto *Method = dyn_cast<CXXMethodDecl>(I)) {
// Reuse the existing member function declaration if it exists.
// It may be associated with the declaration of the type & should be
// reused as we're building the definition.
@@ -1130,16 +1133,13 @@
EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy));
} else
EltTys.push_back(MI->second);
- } else if (const FunctionTemplateDecl *FTD =
- dyn_cast<FunctionTemplateDecl>(*I)) {
+ } else if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(I)) {
// Add any template specializations that have already been seen. Like
// implicit member functions, these may have been added to a declaration
// in the case of vtable-based debug info reduction.
- for (FunctionTemplateDecl::spec_iterator SI = FTD->spec_begin(),
- SE = FTD->spec_end();
- SI != SE; ++SI) {
+ for (const auto *SI : FTD->specializations()) {
llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator MI =
- SPCache.find(cast<CXXMethodDecl>(*SI)->getCanonicalDecl());
+ SPCache.find(cast<CXXMethodDecl>(SI)->getCanonicalDecl());
if (MI != SPCache.end())
EltTys.push_back(MI->second);
}
@@ -1156,15 +1156,14 @@
llvm::DIType RecordTy) {
const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
- for (CXXRecordDecl::base_class_const_iterator BI = RD->bases_begin(),
- BE = RD->bases_end(); BI != BE; ++BI) {
+ for (const auto &BI : RD->bases()) {
unsigned BFlags = 0;
uint64_t BaseOffset;
const CXXRecordDecl *Base =
- cast<CXXRecordDecl>(BI->getType()->getAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(BI.getType()->getAs<RecordType>()->getDecl());
- if (BI->isVirtual()) {
+ if (BI.isVirtual()) {
// virtual base offset offset is -ve. The code generator emits dwarf
// expression where it expects +ve number.
BaseOffset =
@@ -1176,7 +1175,7 @@
// FIXME: Inconsistent units for BaseOffset. It is in bytes when
// BI->isVirtual() and bits when not.
- AccessSpecifier Access = BI->getAccessSpecifier();
+ AccessSpecifier Access = BI.getAccessSpecifier();
if (Access == clang::AS_private)
BFlags |= llvm::DIDescriptor::FlagPrivate;
else if (Access == clang::AS_protected)
@@ -1184,7 +1183,7 @@
llvm::DIType DTy =
DBuilder.createInheritance(RecordTy,
- getOrCreateType(BI->getType(), Unit),
+ getOrCreateType(BI.getType(), Unit),
BaseOffset, BFlags);
EltTys.push_back(DTy);
}
@@ -1239,7 +1238,7 @@
V = CGM.GetAddrOfFunction(FD);
// Member data pointers have special handling too to compute the fixed
// offset within the object.
- if (isa<FieldDecl>(D)) {
+ if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
// These five lines (& possibly the above member function pointer
// handling) might be able to be refactored to use similar code in
// CodeGenModule::getMemberPointerConstant
@@ -1416,6 +1415,9 @@
}
void CGDebugInfo::completeRequiredType(const RecordDecl *RD) {
+ if (DebugKind <= CodeGenOptions::DebugLineTablesOnly)
+ return;
+
if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
if (CXXDecl->isDynamicClass())
return;
@@ -1439,32 +1441,57 @@
TypeCache[TyPtr] = Res;
}
+static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I,
+ CXXRecordDecl::method_iterator End) {
+ for (; I != End; ++I)
+ if (FunctionDecl *Tmpl = I->getInstantiatedFromMemberFunction())
+ if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
+ !I->getMemberSpecializationInfo()->isExplicitSpecialization())
+ return true;
+ return false;
+}
+
+static bool shouldOmitDefinition(CodeGenOptions::DebugInfoKind DebugKind,
+ const RecordDecl *RD,
+ const LangOptions &LangOpts) {
+ if (DebugKind > CodeGenOptions::LimitedDebugInfo)
+ return false;
+
+ if (!LangOpts.CPlusPlus)
+ return false;
+
+ if (!RD->isCompleteDefinitionRequired())
+ return true;
+
+ const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
+
+ if (!CXXDecl)
+ return false;
+
+ if (CXXDecl->hasDefinition() && CXXDecl->isDynamicClass())
+ return true;
+
+ TemplateSpecializationKind Spec = TSK_Undeclared;
+ if (const ClassTemplateSpecializationDecl *SD =
+ dyn_cast<ClassTemplateSpecializationDecl>(RD))
+ Spec = SD->getSpecializationKind();
+
+ if (Spec == TSK_ExplicitInstantiationDeclaration &&
+ hasExplicitMemberDefinition(CXXDecl->method_begin(),
+ CXXDecl->method_end()))
+ return true;
+
+ return false;
+}
+
/// CreateType - get structure or union type.
llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {
RecordDecl *RD = Ty->getDecl();
- const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
- // Always emit declarations for types that aren't required to be complete when
- // in limit-debug-info mode. If the type is later found to be required to be
- // complete this declaration will be upgraded to a definition by
- // `completeRequiredType`.
- // If the type is dynamic, only emit the definition in TUs that require class
- // data. This is handled by `completeClassData`.
llvm::DICompositeType T(getTypeOrNull(QualType(Ty, 0)));
- // If we've already emitted the type, just use that, even if it's only a
- // declaration. The completeType, completeRequiredType, and completeClassData
- // callbacks will handle promoting the declaration to a definition.
- if (T ||
- (DebugKind <= CodeGenOptions::LimitedDebugInfo &&
- // Under -flimit-debug-info, emit only a declaration unless the type is
- // required to be complete.
- !RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) ||
- // If the class is dynamic, only emit a declaration. A definition will be
- // emitted whenever the vtable is emitted.
- (CXXDecl && CXXDecl->hasDefinition() && CXXDecl->isDynamicClass()) || T) {
- llvm::DIDescriptor FDContext =
- getContextDescriptor(cast<Decl>(RD->getDeclContext()));
+ if (T || shouldOmitDefinition(DebugKind, RD, CGM.getLangOpts())) {
if (!T)
- T = getOrCreateRecordFwdDecl(Ty, FDContext);
+ T = getOrCreateRecordFwdDecl(
+ Ty, getContextDescriptor(cast<Decl>(RD->getDeclContext())));
return T;
}
@@ -1625,9 +1652,7 @@
}
// Create entries for all of the properties.
- for (ObjCContainerDecl::prop_iterator I = ID->prop_begin(),
- E = ID->prop_end(); I != E; ++I) {
- const ObjCPropertyDecl *PD = *I;
+ for (const auto *PD : ID->properties()) {
SourceLocation Loc = PD->getLocation();
llvm::DIFile PUnit = getOrCreateFile(Loc);
unsigned PLine = getLineNumber(Loc);
@@ -1829,11 +1854,13 @@
if (!Ty->getPointeeType()->isFunctionType())
return DBuilder.createMemberPointerType(
getOrCreateType(Ty->getPointeeType(), U), ClassType);
+
+ const FunctionProtoType *FPT =
+ Ty->getPointeeType()->getAs<FunctionProtoType>();
return DBuilder.createMemberPointerType(getOrCreateInstanceMethodType(
- CGM.getContext().getPointerType(
- QualType(Ty->getClass(), Ty->getPointeeType().getCVRQualifiers())),
- Ty->getPointeeType()->getAs<FunctionProtoType>(), U),
- ClassType);
+ CGM.getContext().getPointerType(QualType(Ty->getClass(),
+ FPT->getTypeQuals())),
+ FPT, U), ClassType);
}
llvm::DIType CGDebugInfo::CreateType(const AtomicType *Ty,
@@ -1871,9 +1898,7 @@
// Create DIEnumerator elements for each enumerator.
SmallVector<llvm::Value *, 16> Enumerators;
ED = ED->getDefinition();
- for (EnumDecl::enumerator_iterator
- Enum = ED->enumerator_begin(), EnumEnd = ED->enumerator_end();
- Enum != EnumEnd; ++Enum) {
+ for (const auto *Enum : ED->enumerators()) {
Enumerators.push_back(
DBuilder.createEnumerator(Enum->getName(),
Enum->getInitVal().getSExtValue()));
@@ -1994,6 +2019,17 @@
return llvm::DIType(cast_or_null<llvm::MDNode>(V));
}
+void CGDebugInfo::completeTemplateDefinition(
+ const ClassTemplateSpecializationDecl &SD) {
+ if (DebugKind <= CodeGenOptions::DebugLineTablesOnly)
+ return;
+
+ completeClassData(&SD);
+ // In case this type has no member function definitions being emitted, ensure
+ // it is retained
+ 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) {
@@ -2123,10 +2159,11 @@
return CreateType(cast<ComplexType>(Ty));
case Type::Pointer:
return CreateType(cast<PointerType>(Ty), Unit);
+ case Type::Adjusted:
case Type::Decayed:
- // Decayed types are just pointers in LLVM and DWARF.
+ // Decayed and adjusted types use the adjusted type in LLVM and DWARF.
return CreateType(
- cast<PointerType>(cast<DecayedType>(Ty)->getDecayedType()), Unit);
+ cast<PointerType>(cast<AdjustedType>(Ty)->getAdjustedType()), Unit);
case Type::BlockPointer:
return CreateType(cast<BlockPointerType>(Ty), Unit);
case Type::Typedef:
@@ -2233,9 +2270,10 @@
if (T && (!T.isForwardDecl() || !RD->getDefinition()))
return T;
- // If this is just a forward declaration, construct an appropriately
- // marked node and just return it.
- if (!RD->getDefinition())
+ // If this is just a forward or incomplete declaration, construct an
+ // appropriately marked node and just return it.
+ const RecordDecl *D = RD->getDefinition();
+ if (!D || !D->isCompleteDefinition())
return getOrCreateRecordFwdDecl(Ty, RDContext);
uint64_t Size = CGM.getContext().getTypeSize(Ty);
@@ -2277,7 +2315,7 @@
llvm::DICompositeType ContainingType;
const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {
- // Seek non virtual primary base root.
+ // Seek non-virtual primary base root.
while (1) {
const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
const CXXRecordDecl *PBT = BRL.getPrimaryBase();
@@ -2309,7 +2347,7 @@
return Ty;
}
-llvm::DIDescriptor CGDebugInfo::getDeclarationOrDefinition(const Decl *D) {
+llvm::DIScope CGDebugInfo::getDeclarationOrDefinition(const Decl *D) {
// We only need a declaration (not a definition) of the type - so use whatever
// we would otherwise do to get a type for a pointee. (forward declarations in
// limited debug info, full definitions (if the type definition is available)
@@ -2327,9 +2365,9 @@
llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator I =
DeclCache.find(D->getCanonicalDecl());
if (I == DeclCache.end())
- return llvm::DIDescriptor();
+ return llvm::DIScope();
llvm::Value *V = I->second;
- return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(V));
+ return llvm::DIScope(dyn_cast_or_null<llvm::MDNode>(V));
}
/// getFunctionDeclaration - Return debug info descriptor to describe method
@@ -2352,7 +2390,6 @@
llvm::DICompositeType T(S);
llvm::DISubprogram SP =
CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()), T);
- T.addMember(SP);
return SP;
}
}
@@ -2363,9 +2400,7 @@
return SP;
}
- for (FunctionDecl::redecl_iterator I = FD->redecls_begin(),
- E = FD->redecls_end(); I != E; ++I) {
- const FunctionDecl *NextFD = *I;
+ for (auto NextFD : FD->redecls()) {
llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
MI = SPCache.find(NextFD->getCanonicalDecl());
if (MI != SPCache.end()) {
@@ -2397,7 +2432,7 @@
SmallVector<llvm::Value *, 16> Elts;
// First element is always return type. For 'void' functions it is NULL.
- QualType ResultTy = OMethod->getResultType();
+ QualType ResultTy = OMethod->getReturnType();
// Replace the instancetype keyword with the actual type.
if (ResultTy == CGM.getContext().getObjCInstanceType())
@@ -2413,13 +2448,27 @@
llvm::DIType CmdTy = getOrCreateType(OMethod->getCmdDecl()->getType(), F);
Elts.push_back(DBuilder.createArtificialType(CmdTy));
// Get rest of the arguments.
- for (ObjCMethodDecl::param_const_iterator PI = OMethod->param_begin(),
- PE = OMethod->param_end(); PI != PE; ++PI)
- Elts.push_back(getOrCreateType((*PI)->getType(), F));
+ for (const auto *PI : OMethod->params())
+ Elts.push_back(getOrCreateType(PI->getType(), F));
llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);
return DBuilder.createSubroutineType(F, EltTypeArray);
}
+
+ // Handle variadic function types; they need an additional
+ // unspecified parameter.
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (FD->isVariadic()) {
+ SmallVector<llvm::Value *, 16> EltTys;
+ EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
+ if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FnType))
+ for (unsigned i = 0, e = FPT->getNumParams(); i != e; ++i)
+ EltTys.push_back(getOrCreateType(FPT->getParamType(i), F));
+ EltTys.push_back(DBuilder.createUnspecifiedParameter());
+ llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys);
+ return DBuilder.createSubroutineType(F, EltTypeArray);
+ }
+
return llvm::DICompositeType(getOrCreateType(FnType, F));
}
@@ -2434,14 +2483,25 @@
FnBeginRegionCount.push_back(LexicalBlockStack.size());
const Decl *D = GD.getDecl();
- // Function may lack declaration in source code if it is created by Clang
- // CodeGen (examples: _GLOBAL__I_a, __cxx_global_array_dtor, thunk).
+
+ // 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);
- // Use the location of the declaration.
SourceLocation Loc;
- if (HasDecl)
+ 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();
+ }
+
unsigned Flags = 0;
llvm::DIFile Unit = getOrCreateFile(Loc);
llvm::DIDescriptor FDContext(Unit);
@@ -2504,6 +2564,11 @@
if (!HasDecl || D->isImplicit())
Flags |= llvm::DIDescriptor::FlagArtificial;
+ // FIXME: The function declaration we're constructing here is mostly reusing
+ // declarations from CXXMethodDecl and not constructing new ones for arbitrary
+ // FunctionDecls. When/if we fix this we can have FDContext be TheCU/null for
+ // all subprograms instead of the actual context since subprogram definitions
+ // are emitted as CU level entities by the backend.
llvm::DISubprogram SP =
DBuilder.createFunction(FDContext, Name, LinkageName, Unit, LineNo,
getOrCreateFunctionType(D, FnType, Unit),
@@ -2514,9 +2579,10 @@
if (HasDecl)
DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(SP)));
- // Push function on region stack.
+ // Push the function onto the lexical block stack.
llvm::MDNode *SPN = SP;
LexicalBlockStack.push_back(SPN);
+
if (HasDecl)
RegionMap[D] = llvm::WeakVH(SP);
}
@@ -2560,7 +2626,8 @@
llvm::DIDescriptor(LexicalBlockStack.back()),
getOrCreateFile(CurLoc),
getLineNumber(CurLoc),
- getColumnNumber(CurLoc));
+ getColumnNumber(CurLoc),
+ 0);
llvm::MDNode *DN = D;
LexicalBlockStack.push_back(DN);
}
@@ -2768,10 +2835,7 @@
// all union fields.
const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
if (RD->isUnion() && RD->isAnonymousStructOrUnion()) {
- for (RecordDecl::field_iterator I = RD->field_begin(),
- E = RD->field_end();
- I != E; ++I) {
- FieldDecl *Field = *I;
+ for (const auto *Field : RD->fields()) {
llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
StringRef FieldName = Field->getName();
@@ -2970,10 +3034,7 @@
}
// Variable captures.
- for (BlockDecl::capture_const_iterator
- i = blockDecl->capture_begin(), e = blockDecl->capture_end();
- i != e; ++i) {
- const BlockDecl::Capture &capture = *i;
+ for (const auto &capture : blockDecl->captures()) {
const VarDecl *variable = capture.getVariable();
const CGBlockInfo::Capture &captureInfo = block.getCapture(variable);
@@ -3085,7 +3146,6 @@
llvm::DICompositeType Ctxt(
getContextDescriptor(cast<Decl>(D->getDeclContext())));
llvm::DIDerivedType T = CreateRecordStaticField(D, Ctxt);
- Ctxt.addMember(T);
return T;
}
@@ -3196,7 +3256,7 @@
// Emitting one decl is sufficient - debuggers can detect that this is an
// overloaded name & provide lookup for all the overloads.
const UsingShadowDecl &USD = **UD.shadow_begin();
- if (llvm::DIDescriptor Target =
+ if (llvm::DIScope Target =
getDeclarationOrDefinition(USD.getUnderlyingDecl()))
DBuilder.createImportedDeclaration(
getCurrentContextDescriptor(cast<Decl>(USD.getDeclContext())), Target,