summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp55
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.h3
-rw-r--r--clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp42
3 files changed, 97 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index d9101f833c7..cc57f27d60a 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2515,11 +2515,17 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(const Decl *D,
Elts.push_back(getOrCreateType(ResultTy, F));
// "self" pointer is always first argument.
- QualType SelfDeclTy = OMethod->getSelfDecl()->getType();
- Elts.push_back(CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
+ QualType SelfDeclTy;
+ if (auto *SelfDecl = OMethod->getSelfDecl())
+ SelfDeclTy = SelfDecl->getType();
+ else if (auto *FPT = dyn_cast<FunctionProtoType>(FnType))
+ if (FPT->getNumParams() > 1)
+ SelfDeclTy = FPT->getParamType(0);
+ if (!SelfDeclTy.isNull())
+ Elts.push_back(CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
// "_cmd" pointer is always second argument.
Elts.push_back(DBuilder.createArtificialType(
- getOrCreateType(OMethod->getCmdDecl()->getType(), F)));
+ getOrCreateType(CGM.getContext().getObjCSelType(), F)));
// Get rest of the arguments.
for (const auto *PI : OMethod->params())
Elts.push_back(getOrCreateType(PI->getType(), F));
@@ -2623,6 +2629,49 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc,
RegionMap[D].reset(SP);
}
+void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
+ QualType FnType) {
+ StringRef Name;
+ StringRef LinkageName;
+
+ const Decl *D = GD.getDecl();
+ if (!D)
+ return;
+
+ unsigned Flags = 0;
+ llvm::DIFile *Unit = getOrCreateFile(Loc);
+ llvm::DIScope *FDContext = Unit;
+ llvm::DINodeArray TParamsArray;
+ if (isa<FunctionDecl>(D)) {
+ // If there is a DISubprogram for this function available then use it.
+ collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
+ TParamsArray, Flags);
+ } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
+ Name = getObjCMethodName(OMD);
+ Flags |= llvm::DINode::FlagPrototyped;
+ } else {
+ llvm_unreachable("not a function or ObjC method");
+ }
+ if (!Name.empty() && Name[0] == '\01')
+ Name = Name.substr(1);
+
+ if (D->isImplicit()) {
+ Flags |= llvm::DINode::FlagArtificial;
+ // Artificial functions without a location should not silently reuse CurLoc.
+ if (Loc.isInvalid())
+ CurLoc = SourceLocation();
+ }
+ unsigned LineNo = getLineNumber(Loc);
+ unsigned ScopeLine = 0;
+
+ DBuilder.createFunction(FDContext, Name, LinkageName, Unit, LineNo,
+ getOrCreateFunctionType(D, FnType, Unit),
+ false /*internalLinkage*/, true /*definition*/,
+ ScopeLine, Flags, CGM.getLangOpts().Optimize, nullptr,
+ TParamsArray.get(),
+ getFunctionDeclaration(D));
+}
+
void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
// Update our current location
setLocation(Loc);
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 1880335cc0b..99272e60ebd 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -281,6 +281,9 @@ public:
SourceLocation ScopeLoc, QualType FnType,
llvm::Function *Fn, CGBuilderTy &Builder);
+ /// Emit debug info for a function declaration.
+ void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType);
+
/// Constructs the debug code for exiting a function.
void EmitFunctionEnd(CGBuilderTy &Builder);
diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
index a7c8230dc66..54a38308694 100644
--- a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
+++ b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
@@ -76,6 +76,48 @@ class PCHContainerGenerator : public ASTConsumer {
return true;
}
+ bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+ QualType QualTy(D->getTypeForDecl(), 0);
+ if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
+ DI.getOrCreateStandaloneType(QualTy, D->getLocation());
+ return true;
+ }
+
+ bool VisitFunctionDecl(FunctionDecl *D) {
+ if (isa<CXXMethodDecl>(D))
+ // This is not yet supported. Constructing the `this' argument
+ // mandates a CodeGenFunction.
+ return true;
+
+ SmallVector<QualType, 16> ArgTypes;
+ for (auto i : D->params())
+ ArgTypes.push_back(i->getType());
+ QualType RetTy = D->getReturnType();
+ QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
+ FunctionProtoType::ExtProtoInfo());
+ if (CanRepresent(FnTy.getTypePtr()))
+ DI.EmitFunctionDecl(D, D->getLocation(), FnTy);
+ return true;
+ }
+
+ bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
+ if (!D->getClassInterface())
+ return true;
+
+ bool selfIsPseudoStrong, selfIsConsumed;
+ SmallVector<QualType, 16> ArgTypes;
+ ArgTypes.push_back(D->getSelfType(Ctx, D->getClassInterface(),
+ selfIsPseudoStrong, selfIsConsumed));
+ ArgTypes.push_back(Ctx.getObjCSelType());
+ for (auto i : D->params())
+ ArgTypes.push_back(i->getType());
+ QualType RetTy = D->getReturnType();
+ QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
+ FunctionProtoType::ExtProtoInfo());
+ if (CanRepresent(FnTy.getTypePtr()))
+ DI.EmitFunctionDecl(D, D->getLocation(), FnTy);
+ return true;
+ }
};
public:
OpenPOWER on IntegriCloud