diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 431eec03e021..313c28951dcf 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -133,6 +133,10 @@ public: void addVolatile() { ThePtr |= Volatile; } void addRestrict() { ThePtr |= Restrict; } + void removeConst() { ThePtr &= ~Const; } + void removeVolatile() { ThePtr &= ~Volatile; } + void removeRestrict() { ThePtr &= ~Restrict; } + QualType getQualifiedType(unsigned TQs) const { return QualType(getTypePtr(), TQs); } diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index abe1699fe8dc..e7033969798e 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -13,20 +13,20 @@ #include "CGDebugInfo.h" #include "CodeGenModule.h" +#include "clang/AST/ASTContext.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/FileManager.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/Module.h" -#include "llvm/Support/Dwarf.h" -#include "llvm/Support/IRBuilder.h" -#include "llvm/Target/TargetMachine.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineModuleInfo.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/FileManager.h" -#include "clang/AST/ASTContext.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/IRBuilder.h" +#include "llvm/Target/TargetMachine.h" using namespace clang; using namespace clang::CodeGen; @@ -35,13 +35,16 @@ CGDebugInfo::CGDebugInfo(CodeGenModule *m) , CurLoc() , PrevLoc() , CompileUnitCache() +, TypeCache() , StopPointFn(NULL) -, CompileUnitAnchor(NULL) -, SubProgramAnchor(NULL) +, FuncStartFn(NULL) +, DeclareFn(NULL) , RegionStartFn(NULL) , RegionEndFn(NULL) -, FuncStartFn(NULL) -, CurFuncDesc(NULL) +, CompileUnitAnchor(NULL) +, SubprogramAnchor(NULL) +, RegionStack() +, Subprogram(NULL) { SR = new llvm::DISerializer(); SR->setModule (&M->getModule()); @@ -50,19 +53,28 @@ CGDebugInfo::CGDebugInfo(CodeGenModule *m) CGDebugInfo::~CGDebugInfo() { delete SR; - // Clean up allocated debug info; we can't do this until after the - // serializer is destroyed because it caches pointers to - // the debug info + + // Free CompileUnitCache. + for (std::map::iterator I + = CompileUnitCache.begin(); I != CompileUnitCache.end(); ++I) { + delete I->second; + } + CompileUnitCache.clear(); + + // Free TypeCache. + for (std::map::iterator I + = TypeCache.begin(); I != TypeCache.end(); ++I) { + delete I->second; + } + TypeCache.clear(); + + for (std::vector::iterator I + = RegionStack.begin(); I != RegionStack.end(); ++I) { + delete *I; + } + delete CompileUnitAnchor; - delete SubProgramAnchor; - // Clean up compile unit descriptions - std::map::iterator MI; - for (MI = CompileUnitCache.begin(); MI != CompileUnitCache.end(); ++MI) - delete MI->second; - // Clean up misc allocations - std::vector::iterator VI; - for (VI = DebugAllocationList.begin(); VI != DebugAllocationList.end(); ++VI) - delete *VI; + delete SubprogramAnchor; } @@ -73,6 +85,12 @@ llvm::Value *CGDebugInfo::getCastValueFor(llvm::DebugInfoDesc *DD) { SR->getEmptyStructPtrType()); } +/// getValueFor - Return a llvm representation for a given debug information +/// descriptor. +llvm::Value *CGDebugInfo::getValueFor(llvm::DebugInfoDesc *DD) { + return SR->Serialize(DD); +} + /// getOrCreateCompileUnit - Get the compile unit from the cache or create a new /// one if necessary. llvm::CompileUnitDesc @@ -123,10 +141,313 @@ llvm::CompileUnitDesc } -void -CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder) { - if (CurLoc.isInvalid() || CurLoc.isMacroID()) return; +llvm::TypeDesc * +CGDebugInfo::getOrCreateCVRType(QualType type, llvm::CompileUnitDesc *Unit) +{ + // We will create a Derived type. + llvm::DerivedTypeDesc *DTy = NULL; + llvm::TypeDesc *FromTy = NULL; + if (type.isConstQualified()) { + DTy = new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_const_type); + type.removeConst(); + FromTy = getOrCreateType(type, Unit); + } else if (type.isVolatileQualified()) { + DTy = new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_volatile_type); + type.removeVolatile(); + FromTy = getOrCreateType(type, Unit); + } else if (type.isRestrictQualified()) { + DTy = new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_restrict_type); + type.removeRestrict(); + FromTy = getOrCreateType(type, Unit); + } + + // No need to fill in the Name, Line, Size, Alignment, Offset in case of // CVR derived types. + DTy->setContext(Unit); + DTy->setFromType(FromTy); + + return DTy; +} + + +/// getOrCreateType - Get the Basic type from the cache or create a new +/// one if necessary. +llvm::TypeDesc * +CGDebugInfo::getOrCreateBuiltinType(QualType type, llvm::CompileUnitDesc *Unit) +{ + assert (type->getTypeClass() == Type::Builtin); + + const BuiltinType *BT = type->getAsBuiltinType(); + + unsigned Encoding = 0; + switch (BT->getKind()) + { + case BuiltinType::Void: + return NULL; + case BuiltinType::UChar: + case BuiltinType::Char_U: + Encoding = llvm::dwarf::DW_ATE_unsigned_char; + break; + case BuiltinType::Char_S: + case BuiltinType::SChar: + Encoding = llvm::dwarf::DW_ATE_signed_char; + break; + case BuiltinType::UShort: + case BuiltinType::UInt: + case BuiltinType::ULong: + case BuiltinType::ULongLong: + Encoding = llvm::dwarf::DW_ATE_unsigned; + break; + case BuiltinType::Short: + case BuiltinType::Int: + case BuiltinType::Long: + case BuiltinType::LongLong: + Encoding = llvm::dwarf::DW_ATE_signed; + break; + case BuiltinType::Bool: + Encoding = llvm::dwarf::DW_ATE_boolean; + break; + case BuiltinType::Float: + case BuiltinType::Double: + Encoding = llvm::dwarf::DW_ATE_float; + break; + default: + Encoding = llvm::dwarf::DW_ATE_signed; + break; + } + + // Ty will have contain the resulting type. + llvm::BasicTypeDesc *BTy = new llvm::BasicTypeDesc(); + + // Get the name and location early to assist debugging. + const char *TyName = BT->getName(); + + // Bit size, align and offset of the type. + uint64_t Size = M->getContext().getTypeSize(type); + uint64_t Align = M->getContext().getTypeAlign(type); + uint64_t Offset = 0; + + // If the type is defined, fill in the details. + if (BTy) { + BTy->setContext(Unit); + BTy->setName(TyName); + BTy->setSize(Size); + BTy->setAlign(Align); + BTy->setOffset(Offset); + BTy->setEncoding(Encoding); + } + + return BTy; +} + +llvm::TypeDesc * +CGDebugInfo::getOrCreatePointerType(QualType type, llvm::CompileUnitDesc *Unit) +{ + // type* + llvm::DerivedTypeDesc *DTy = + new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_pointer_type); + + // Handle the derived type. + const PointerType *PTRT = type->getAsPointerType(); + llvm::TypeDesc *FromTy = getOrCreateType(PTRT->getPointeeType(), Unit); + + // Get the name and location early to assist debugging. + SourceManager &SM = M->getContext().getSourceManager(); + uint64_t Line = SM.getLogicalLineNumber(CurLoc); + + // Bit size, align and offset of the type. + uint64_t Size = M->getContext().getTypeSize(type); + uint64_t Align = M->getContext().getTypeAlign(type); + uint64_t Offset = 0; + + // If the type is defined, fill in the details. + if (DTy) { + DTy->setContext(Unit); + DTy->setLine(Line); + DTy->setSize(Size); + DTy->setAlign(Align); + DTy->setOffset(Offset); + DTy->setFromType(FromTy); + } + + return DTy; +} + +llvm::TypeDesc * +CGDebugInfo::getOrCreateTypedefType(QualType type, llvm::CompileUnitDesc *Unit) +{ + // typedefs are derived from some other type. + llvm::DerivedTypeDesc *DTy = + new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_typedef); + + // Handle derived type. + const TypedefType *TDT = type->getAsTypedefType(); + llvm::TypeDesc *FromTy = getOrCreateType(TDT->LookThroughTypedefs(), + Unit); + + // Get the name and location early to assist debugging. + const char *TyName = TDT->getDecl()->getName(); + SourceManager &SM = M->getContext().getSourceManager(); + uint64_t Line = SM.getLogicalLineNumber(TDT->getDecl()->getLocation()); + + // If the type is defined, fill in the details. + if (DTy) { + DTy->setContext(Unit); + DTy->setFile(getOrCreateCompileUnit(TDT->getDecl()->getLocation())); + DTy->setLine(Line); + DTy->setName(TyName); + DTy->setFromType(FromTy); + } + + return DTy; +} + +llvm::TypeDesc * +CGDebugInfo::getOrCreateFunctionType(QualType type, llvm::CompileUnitDesc *Unit) +{ + llvm::CompositeTypeDesc *SubrTy = + new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_subroutine_type); + + // Prepare to add the arguments for the subroutine. + std::vector &Elements = SubrTy->getElements(); + + // Get result type. + const FunctionType *FT = type->getAsFunctionType(); + llvm::TypeDesc *ArgTy = getOrCreateType(FT->getResultType(), Unit); + if (ArgTy) Elements.push_back(ArgTy); + + // Set up remainder of arguments. + if (type->getTypeClass() == Type::FunctionProto) { + const FunctionTypeProto *FTPro = dyn_cast(type); + for (unsigned int i =0; i < FTPro->getNumArgs(); i++) { + QualType ParamType = FTPro->getArgType(i); + ArgTy = getOrCreateType(ParamType, Unit); + if (ArgTy) Elements.push_back(ArgTy); + } + } + + // FIXME: set other fields file, line here. + SubrTy->setContext(Unit); + + return SubrTy; +} + + + +/// getOrCreateType - Get the type from the cache or create a new +/// one if necessary. +llvm::TypeDesc * +CGDebugInfo::getOrCreateType(QualType type, llvm::CompileUnitDesc *Unit) +{ + if (type.isNull()) + return NULL; + + // Check to see if the compile unit already has created this type. + llvm::TypeDesc *&Slot = TypeCache[type.getAsOpaquePtr()]; + if (Slot) return Slot; + + // We need to check for the CVR qualifiers as the first thing. + if (type.getCVRQualifiers()) { + Slot = getOrCreateCVRType (type, Unit); + return Slot; + } + + // Work out details of type. + switch(type->getTypeClass()) { + case Type::Complex: + case Type::Reference: + case Type::ConstantArray: + case Type::VariableArray: + case Type::IncompleteArray: + case Type::Vector: + case Type::ExtVector: + case Type::Tagged: + case Type::ASQual: + case Type::ObjCInterface: + case Type::ObjCQualifiedInterface: + case Type::ObjCQualifiedId: + case Type::TypeOfExp: + case Type::TypeOfTyp: + default: + { + assert (0 && "Unsupported type"); + return NULL; + } + + case Type::TypeName: + Slot = getOrCreateTypedefType(type, Unit); + break; + + case Type::FunctionProto: + case Type::FunctionNoProto: + Slot = getOrCreateFunctionType(type, Unit); + break; + + case Type::Builtin: + Slot = getOrCreateBuiltinType(type, Unit); + break; + + case Type::Pointer: + Slot = getOrCreatePointerType(type, Unit); + break; + } + + return Slot; +} + +/// EmitFunctionStart - Constructs the debug code for entering a function - +/// "llvm.dbg.func.start.". +void CGDebugInfo::EmitFunctionStart(const FunctionDecl *FnDecl, + llvm::Function *Fn, + llvm::IRBuilder &Builder) +{ + // Create subprogram descriptor. + Subprogram = new llvm::SubprogramDesc(); + + // Make sure we have an anchor. + if (!SubprogramAnchor) { + SubprogramAnchor = new llvm::AnchorDesc(Subprogram); + } + + // Get name information. + Subprogram->setName(FnDecl->getName()); + Subprogram->setFullName(FnDecl->getName()); + + // Gather location information. + llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc); + SourceManager &SM = M->getContext().getSourceManager(); + uint64_t Loc = SM.getLogicalLineNumber(CurLoc); + + // Get Function Type. + QualType type = FnDecl->getResultType(); + llvm::TypeDesc *SPTy = getOrCreateType(type, Unit); + + Subprogram->setAnchor(SubprogramAnchor); + Subprogram->setContext(Unit); + Subprogram->setFile(Unit); + Subprogram->setLine(Loc); + Subprogram->setType(SPTy); + Subprogram->setIsStatic(Fn->hasInternalLinkage()); + Subprogram->setIsDefinition(true); + + // Lazily construct llvm.dbg.func.start. + if (!FuncStartFn) + FuncStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(), + llvm::Intrinsic::dbg_func_start); + + // Call llvm.dbg.func.start which also implicitly calls llvm.dbg.stoppoint. + Builder.CreateCall(FuncStartFn, getCastValueFor(Subprogram), ""); + + // Push function on region stack. + RegionStack.push_back(Subprogram); +} + + +void +CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder) +{ + if (CurLoc.isInvalid() || CurLoc.isMacroID()) return; + // Don't bother if things are the same as last time. SourceManager &SM = M->getContext().getSourceManager(); if (CurLoc == PrevLoc @@ -157,35 +478,25 @@ CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder) { /// EmitRegionStart- Constructs the debug code for entering a declarative /// region - "llvm.dbg.region.start.". -void CGDebugInfo::EmitFunctionStart(llvm::Function *Fn, llvm::IRBuilder &Builder) +void CGDebugInfo::EmitRegionStart(llvm::Function *Fn, llvm::IRBuilder &Builder) { - // Get the appropriate compile unit. - llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc); + llvm::BlockDesc *Block = new llvm::BlockDesc(); + if (RegionStack.size() > 0) + Block->setContext(RegionStack.back()); + RegionStack.push_back(Block); - llvm::SubprogramDesc* Block = new llvm::SubprogramDesc; - DebugAllocationList.push_back(Block); - Block->setFile(Unit); - Block->setContext(Unit); - if (!SubProgramAnchor) { - SubProgramAnchor = new llvm::AnchorDesc(Block); - SR->Serialize(SubProgramAnchor); - } - Block->setAnchor(SubProgramAnchor); - Block->setName(Fn->getName()); - Block->setFullName(Fn->getName()); - Block->setIsDefinition(true); - SourceManager &SM = M->getContext().getSourceManager(); - Block->setLine(SM.getLogicalLineNumber(CurLoc)); - CurFuncDesc = getCastValueFor(Block); - if (!FuncStartFn) - FuncStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(), - llvm::Intrinsic::dbg_func_start); - Builder.CreateCall(FuncStartFn, CurFuncDesc); + // Lazily construct llvm.dbg.region.start function. + if (!RegionStartFn) + RegionStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(), + llvm::Intrinsic::dbg_region_start); + + // Call llvm.dbg.func.start. + Builder.CreateCall(RegionStartFn, getCastValueFor(Block), ""); } /// EmitRegionEnd - Constructs the debug code for exiting a declarative /// region - "llvm.dbg.region.end." -void CGDebugInfo::EmitFunctionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder) +void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder) { // Lazily construct llvm.dbg.region.end function. if (!RegionEndFn) @@ -196,6 +507,8 @@ void CGDebugInfo::EmitFunctionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder) EmitStopPoint(Fn, Builder); // Call llvm.dbg.func.end. - Builder.CreateCall(RegionEndFn, CurFuncDesc, ""); + llvm::DebugInfoDesc *DID = RegionStack.back(); + Builder.CreateCall(RegionEndFn, getCastValueFor(DID), ""); + RegionStack.pop_back(); } diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index ca933021a6dc..9ac77a4b0d96 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -14,6 +14,7 @@ #ifndef CLANG_CODEGEN_CGDEBUGINFO_H #define CLANG_CODEGEN_CGDEBUGINFO_H +#include "clang/AST/Type.h" #include "clang/Basic/SourceLocation.h" #include #include @@ -28,14 +29,18 @@ namespace llvm { class AnchorDesc; class DebugInfoDesc; class Value; + class TypeDesc; + class SubprogramDesc; } namespace clang { + class FunctionDecl; namespace CodeGen { class CodeGenModule; -/// DebugInfo - This class gathers all debug information during compilation and -/// is responsible for emitting to llvm globals or pass directly to the backend. +/// CGDebugInfo - This class gathers all debug information during compilation +/// and is responsible for emitting to llvm globals or pass directly to +/// the backend. class CGDebugInfo { private: CodeGenModule *M; @@ -45,41 +50,70 @@ private: /// CompileUnitCache - Cache of previously constructed CompileUnits. std::map CompileUnitCache; - std::vector DebugAllocationList; + + /// TypeCache - Cache of previously constructed Types. + std::map TypeCache; llvm::Function *StopPointFn; - llvm::AnchorDesc *CompileUnitAnchor; - llvm::AnchorDesc *SubProgramAnchor; + llvm::Function *FuncStartFn; + llvm::Function *DeclareFn; llvm::Function *RegionStartFn; llvm::Function *RegionEndFn; - llvm::Function *FuncStartFn; - llvm::Value *CurFuncDesc; + llvm::AnchorDesc *CompileUnitAnchor; + llvm::AnchorDesc *SubprogramAnchor; + std::vector RegionStack; + llvm::SubprogramDesc *Subprogram; - /// getOrCreateCompileUnit - Get the compile unit from the cache or create a - /// new one if necessary. - llvm::CompileUnitDesc *getOrCreateCompileUnit(SourceLocation loc); - - /// getCastValueFor - Return a llvm representation for a given debug - /// information descriptor cast to an empty struct pointer. - llvm::Value *getCastValueFor(llvm::DebugInfoDesc *DD); + /// Helper functions for getOrCreateType. + llvm::TypeDesc *getOrCreateCVRType(QualType type, + llvm::CompileUnitDesc *unit); + llvm::TypeDesc *getOrCreateBuiltinType(QualType type, + llvm::CompileUnitDesc *unit); + llvm::TypeDesc *getOrCreateTypedefType(QualType type, + llvm::CompileUnitDesc *unit); + llvm::TypeDesc *getOrCreatePointerType(QualType type, + llvm::CompileUnitDesc *unit); + llvm::TypeDesc *getOrCreateFunctionType(QualType type, + llvm::CompileUnitDesc *unit); public: CGDebugInfo(CodeGenModule *m); ~CGDebugInfo(); - void setLocation(SourceLocation loc) { CurLoc = loc; }; + void setLocation(SourceLocation loc) { CurLoc = loc; } /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of /// source line. void EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder); + + /// EmitFunctionStart - Emit a call to llvm.dbg.function.start to indicate + /// start of a new function + void EmitFunctionStart(const FunctionDecl *FnDecl, llvm::Function *Fn, + llvm::IRBuilder &Builder); - /// EmitFunctionStart - Emit a call to llvm.dbg.func.start to indicate start + /// EmitRegionStart - Emit a call to llvm.dbg.region.start to indicate start /// of a new block. - void EmitFunctionStart(llvm::Function *Fn, llvm::IRBuilder &Builder); + void EmitRegionStart(llvm::Function *Fn, llvm::IRBuilder &Builder); - /// EmitFunctionEnd - Emit call to llvm.dbg.region.end to indicate end of a + /// EmitRegionEnd - Emit call to llvm.dbg.region.end to indicate end of a /// block. - void EmitFunctionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder); + void EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder); + + /// getOrCreateCompileUnit - Get the compile unit from the cache or create a + /// new one if necessary. + llvm::CompileUnitDesc *getOrCreateCompileUnit(SourceLocation loc); + + /// getOrCreateType - Get the type from the cache or create a new type if + /// necessary. + llvm::TypeDesc *getOrCreateType(QualType type, llvm::CompileUnitDesc *unit); + + /// getCastValueFor - Return a llvm representation for a given debug + /// information descriptor cast to an empty struct pointer. + llvm::Value *getCastValueFor(llvm::DebugInfoDesc *DD); + + /// getValueFor - Return a llvm representation for a given debug information + /// descriptor. + llvm::Value *getValueFor(llvm::DebugInfoDesc *DD); }; } // namespace CodeGen } // namespace clang diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index c38ad04001da..067d6ebd0986 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -88,10 +88,25 @@ RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, // FIXME: handle vla's etc. if (S.body_empty() || !isa(S.body_back())) GetLast = false; + CGDebugInfo *DI = CGM.getDebugInfo(); + if (DI) { + if (S.getLBracLoc().isValid()) { + DI->setLocation(S.getLBracLoc()); + } + DI->EmitRegionStart(CurFn, Builder); + } + for (CompoundStmt::const_body_iterator I = S.body_begin(), E = S.body_end()-GetLast; I != E; ++I) EmitStmt(*I); + if (DI) { + if (S.getRBracLoc().isValid()) { + DI->setLocation(S.getRBracLoc()); + } + DI->EmitRegionEnd(CurFn, Builder); + } + if (!GetLast) return RValue::get(0); @@ -368,15 +383,6 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { EmitAggExpr(RV, SRetPtr, false); } - CGDebugInfo *DI = CGM.getDebugInfo(); - if (DI) { - CompoundStmt* body = cast(CurFuncDecl->getBody()); - if (body->getRBracLoc().isValid()) { - DI->setLocation(body->getRBracLoc()); - } - DI->EmitFunctionEnd(CurFn, Builder); - } - if (RetValue) { Builder.CreateRet(RetValue); } else { diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index b17572ce478b..0a016c6416d8 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -205,7 +205,7 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD) { if (body->getLBracLoc().isValid()) { DI->setLocation(body->getLBracLoc()); } - DI->EmitFunctionStart(CurFn, Builder); + DI->EmitFunctionStart(FD, CurFn, Builder); } // Emit allocs for param decls. Give the LLVM Argument nodes names. @@ -225,21 +225,20 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD) { // Emit the function body. EmitStmt(FD->getBody()); + if (DI) { + CompoundStmt* body = cast(CurFuncDecl->getBody()); + if (body->getRBracLoc().isValid()) { + DI->setLocation(body->getRBracLoc()); + } + DI->EmitRegionEnd(CurFn, Builder); + } + // Emit a return for code that falls off the end. If insert point // is a dummy block with no predecessors then remove the block itself. llvm::BasicBlock *BB = Builder.GetInsertBlock(); if (isDummyBlock(BB)) BB->eraseFromParent(); else { - CGDebugInfo *DI = CGM.getDebugInfo(); - if (DI) { - CompoundStmt* body = cast(CurFuncDecl->getBody()); - if (body->getRBracLoc().isValid()) { - DI->setLocation(body->getRBracLoc()); - } - DI->EmitFunctionEnd(CurFn, Builder); - } - // FIXME: if this is C++ main, this should return 0. if (CurFn->getReturnType() == llvm::Type::VoidTy) Builder.CreateRetVoid();