[cfe-commits] r126255 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGBlocks.h lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CGDecl.cpp lib/CodeGen/CodeGenModule.h
John McCall
rjmccall at apple.com
Tue Feb 22 14:38:33 PST 2011
Author: rjmccall
Date: Tue Feb 22 16:38:33 2011
New Revision: 126255
URL: http://llvm.org/viewvc/llvm-project?rev=126255&view=rev
Log:
Emit the structure layout of the block literal parameter to a block
invocation function into the debug info. Rather than faking up a class,
which is tricky because of the custom layout we do, we just emit a struct
directly from the layout information we've already got.
Also, don't emit an unnecessarily parameter alloca for this "variable".
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/CodeGen/CGBlocks.cpp
cfe/trunk/lib/CodeGen/CGBlocks.h
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.h
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Feb 22 16:38:33 2011
@@ -552,11 +552,6 @@
return cudaConfigureCallDecl;
}
- /// This gets the struct used to keep track of pointer to blocks, complete
- /// with captured variables.
- QualType getBlockParmType(bool BlockHasCopyDispose,
- llvm::SmallVectorImpl<const Expr *> &Layout) const;
-
/// This builds the struct used for __block variables.
QualType BuildByRefType(llvm::StringRef DeclName, QualType Ty) const;
@@ -1526,7 +1521,6 @@
/// \brief A counter used to uniquely identify "blocks".
mutable unsigned int UniqueBlockByRefTypeID;
- mutable unsigned int UniqueBlockParmTypeID;
friend class DeclContext;
friend class DeclarationNameTable;
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Feb 22 16:38:33 2011
@@ -205,7 +205,7 @@
DeclarationNames(*this),
ExternalSource(0), Listener(0), PrintingPolicy(LOpts),
LastSDM(0, 0),
- UniqueBlockByRefTypeID(0), UniqueBlockParmTypeID(0) {
+ UniqueBlockByRefTypeID(0) {
ObjCIdRedefinitionType = QualType();
ObjCClassRedefinitionType = QualType();
ObjCSelRedefinitionType = QualType();
@@ -3619,78 +3619,6 @@
return getPointerType(getTagDeclType(T));
}
-
-QualType ASTContext::getBlockParmType(
- bool BlockHasCopyDispose,
- llvm::SmallVectorImpl<const Expr *> &Layout) const {
-
- // FIXME: Move up
- llvm::SmallString<36> Name;
- llvm::raw_svector_ostream(Name) << "__block_literal_"
- << ++UniqueBlockParmTypeID;
- RecordDecl *T;
- T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
- &Idents.get(Name.str()));
- T->startDefinition();
- QualType FieldTypes[] = {
- getPointerType(VoidPtrTy),
- IntTy,
- IntTy,
- getPointerType(VoidPtrTy),
- (BlockHasCopyDispose ?
- getPointerType(getBlockDescriptorExtendedType()) :
- getPointerType(getBlockDescriptorType()))
- };
-
- const char *FieldNames[] = {
- "__isa",
- "__flags",
- "__reserved",
- "__FuncPtr",
- "__descriptor"
- };
-
- for (size_t i = 0; i < 5; ++i) {
- FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
- &Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0, /*Mutable=*/false);
- Field->setAccess(AS_public);
- T->addDecl(Field);
- }
-
- for (unsigned i = 0; i < Layout.size(); ++i) {
- const Expr *E = Layout[i];
-
- QualType FieldType = E->getType();
- IdentifierInfo *FieldName = 0;
- if (isa<CXXThisExpr>(E)) {
- FieldName = &Idents.get("this");
- } else if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E)) {
- const ValueDecl *D = BDRE->getDecl();
- FieldName = D->getIdentifier();
- if (BDRE->isByRef())
- FieldType = BuildByRefType(D->getName(), FieldType);
- } else {
- // Padding.
- assert(isa<ConstantArrayType>(FieldType) &&
- isa<DeclRefExpr>(E) &&
- !cast<DeclRefExpr>(E)->getDecl()->getDeclName() &&
- "doesn't match characteristics of padding decl");
- }
-
- FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
- FieldName, FieldType, /*TInfo=*/0,
- /*BitWidth=*/0, /*Mutable=*/false);
- Field->setAccess(AS_public);
- T->addDecl(Field);
- }
-
- T->completeDefinition();
-
- return getPointerType(getTagDeclType(T));
-}
-
void ASTContext::setObjCFastEnumerationStateType(QualType T) {
const RecordType *Rec = T->getAs<RecordType>();
assert(Rec && "Invalid ObjCFAstEnumerationStateType");
Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Tue Feb 22 16:38:33 2011
@@ -895,12 +895,9 @@
QualType selfTy = getContext().VoidPtrTy;
IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
- // FIXME: this leaks, and we only need it very temporarily.
- ImplicitParamDecl *selfDecl =
- ImplicitParamDecl::Create(getContext(),
- const_cast<BlockDecl*>(blockDecl),
- SourceLocation(), II, selfTy);
- args.push_back(std::make_pair(selfDecl, selfTy));
+ ImplicitParamDecl selfDecl(const_cast<BlockDecl*>(blockDecl),
+ SourceLocation(), II, selfTy);
+ args.push_back(std::make_pair(&selfDecl, selfTy));
// Now add the rest of the parameters.
for (BlockDecl::param_const_iterator i = blockDecl->param_begin(),
@@ -928,12 +925,11 @@
blockInfo.getBlockExpr()->getBody()->getLocEnd());
CurFuncDecl = outerFnDecl; // StartFunction sets this to blockDecl
- // Okay. Undo some of what StartFunction did. We really don't need
- // an alloca for the block address; in theory we could remove it,
- // but that might do unpleasant things to debug info.
- llvm::AllocaInst *blockAddrAlloca
- = cast<llvm::AllocaInst>(LocalDeclMap[selfDecl]);
- llvm::Value *blockAddr = Builder.CreateLoad(blockAddrAlloca);
+ // Okay. Undo some of what StartFunction did.
+
+ // Pull the 'self' reference out of the local decl map.
+ llvm::Value *blockAddr = LocalDeclMap[&selfDecl];
+ LocalDeclMap.erase(&selfDecl);
BlockPointer = Builder.CreateBitCast(blockAddr,
blockInfo.StructureType->getPointerTo(),
"block");
@@ -1010,7 +1006,7 @@
continue;
}
- DI->EmitDeclareOfBlockDeclRefVariable(variable, blockAddrAlloca,
+ DI->EmitDeclareOfBlockDeclRefVariable(variable, BlockPointer,
Builder, blockInfo);
}
}
Modified: cfe/trunk/lib/CodeGen/CGBlocks.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.h?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.h (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.h Tue Feb 22 16:38:33 2011
@@ -177,7 +177,6 @@
const BlockExpr *Block;
CharUnits BlockSize;
CharUnits BlockAlign;
- llvm::SmallVector<const Expr*, 8> BlockLayout;
const Capture &getCapture(const VarDecl *var) const {
llvm::DenseMap<const VarDecl*, Capture>::const_iterator
Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue Feb 22 16:38:33 2011
@@ -430,7 +430,7 @@
llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
unsigned Line = getLineNumber(RD->getLocation());
llvm::DIDescriptor FDContext =
- getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()));
+ getContextDescriptor(cast<Decl>(RD->getDeclContext()));
if (RD->isStruct())
return DBuilder.createStructType(FDContext, RD->getName(), DefUnit,
@@ -571,53 +571,63 @@
return DbgTy;
}
+llvm::DIType CGDebugInfo::createFieldType(llvm::StringRef name,
+ QualType type,
+ Expr *bitWidth,
+ SourceLocation loc,
+ AccessSpecifier AS,
+ uint64_t offsetInBits,
+ llvm::DIFile tunit) {
+ llvm::DIType debugType = getOrCreateType(type, tunit);
+
+ // Get the location for the field.
+ llvm::DIFile file = getOrCreateFile(loc);
+ unsigned line = getLineNumber(loc);
+
+ uint64_t sizeInBits = 0;
+ unsigned alignInBits = 0;
+ if (!type->isIncompleteArrayType()) {
+ llvm::tie(sizeInBits, alignInBits) = CGM.getContext().getTypeInfo(type);
+
+ if (bitWidth)
+ sizeInBits = bitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
+ }
+
+ unsigned flags = 0;
+ if (AS == clang::AS_private)
+ flags |= llvm::DIDescriptor::FlagPrivate;
+ else if (AS == clang::AS_protected)
+ flags |= llvm::DIDescriptor::FlagProtected;
+
+ return DBuilder.createMemberType(name, file, line, sizeInBits, alignInBits,
+ offsetInBits, flags, debugType);
+}
+
/// 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::DIFile Unit,
- llvm::SmallVectorImpl<llvm::Value *> &EltTys) {
- unsigned FieldNo = 0;
- const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
- for (RecordDecl::field_iterator I = RD->field_begin(),
- E = RD->field_end();
- I != E; ++I, ++FieldNo) {
- FieldDecl *Field = *I;
- llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
- llvm::StringRef FieldName = Field->getName();
-
- // Ignore unnamed fields. Do not ignore unnamed records.
- if (FieldName.empty() && !isa<RecordType>(Field->getType()))
- continue;
-
- // Get the location for the field.
- llvm::DIFile FieldDefUnit = getOrCreateFile(Field->getLocation());
- unsigned FieldLine = getLineNumber(Field->getLocation());
- QualType FType = Field->getType();
- uint64_t FieldSize = 0;
- unsigned FieldAlign = 0;
- if (!FType->isIncompleteArrayType()) {
+CollectRecordFields(const RecordDecl *record, llvm::DIFile tunit,
+ llvm::SmallVectorImpl<llvm::Value *> &elements) {
+ unsigned fieldNo = 0;
+ const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
+ for (RecordDecl::field_iterator I = record->field_begin(),
+ E = record->field_end();
+ I != E; ++I, ++fieldNo) {
+ FieldDecl *field = *I;
- // Bit size, align and offset of the type.
- FieldSize = CGM.getContext().getTypeSize(FType);
- Expr *BitWidth = Field->getBitWidth();
- if (BitWidth)
- FieldSize = BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
- FieldAlign = CGM.getContext().getTypeAlign(FType);
- }
+ llvm::StringRef name = field->getName();
+ QualType type = field->getType();
- uint64_t FieldOffset = RL.getFieldOffset(FieldNo);
+ // Ignore unnamed fields unless they're anonymous structs/unions.
+ if (name.empty() && !type->isRecordType())
+ continue;
- unsigned Flags = 0;
- AccessSpecifier Access = I->getAccess();
- if (Access == clang::AS_private)
- Flags |= llvm::DIDescriptor::FlagPrivate;
- else if (Access == clang::AS_protected)
- Flags |= llvm::DIDescriptor::FlagProtected;
+ llvm::DIType fieldType
+ = createFieldType(name, type, field->getBitWidth(),
+ field->getLocation(), field->getAccess(),
+ layout.getFieldOffset(fieldNo), tunit);
- FieldTy = DBuilder.createMemberType(FieldName, FieldDefUnit,
- FieldLine, FieldSize, FieldAlign,
- FieldOffset, Flags, FieldTy);
- EltTys.push_back(FieldTy);
+ elements.push_back(fieldType);
}
}
@@ -902,7 +912,7 @@
// may refer to the forward decl if the struct is recursive) and replace all
// uses of the forward declaration with the final definition.
llvm::DIDescriptor FDContext =
- getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()));
+ getContextDescriptor(cast<Decl>(RD->getDeclContext()));
// If this is just a forward declaration, construct an appropriately
// marked node and just return it.
@@ -994,7 +1004,7 @@
RegionMap.erase(RI);
llvm::DIDescriptor RDContext =
- getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()));
+ getContextDescriptor(cast<Decl>(RD->getDeclContext()));
llvm::StringRef RDName = RD->getName();
uint64_t Size = CGM.getContext().getTypeSize(Ty);
uint64_t Align = CGM.getContext().getTypeAlign(Ty);
@@ -1329,7 +1339,7 @@
Align = CGM.getContext().getTypeAlign(ED->getTypeForDecl());
}
llvm::DIDescriptor EnumContext =
- getContextDescriptor(dyn_cast<Decl>(ED->getDeclContext()));
+ getContextDescriptor(cast<Decl>(ED->getDeclContext()));
llvm::DIType DbgTy =
DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, Line,
Size, Align, EltArray);
@@ -1827,33 +1837,34 @@
// If VD is an anonymous union then Storage represents value for
// all union fields.
- if (const RecordType *RT = dyn_cast<RecordType>(VD->getType()))
- if (const RecordDecl *RD = dyn_cast<RecordDecl>(RT->getDecl()))
- if (RD->isUnion()) {
- for (RecordDecl::field_iterator I = RD->field_begin(),
- E = RD->field_end();
- I != E; ++I) {
- FieldDecl *Field = *I;
- llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
- llvm::StringRef FieldName = Field->getName();
+ if (const RecordType *RT = dyn_cast<RecordType>(VD->getType())) {
+ const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
+ if (RD->isUnion()) {
+ for (RecordDecl::field_iterator I = RD->field_begin(),
+ E = RD->field_end();
+ I != E; ++I) {
+ FieldDecl *Field = *I;
+ llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
+ llvm::StringRef FieldName = Field->getName();
- // Ignore unnamed fields. Do not ignore unnamed records.
- if (FieldName.empty() && !isa<RecordType>(Field->getType()))
- continue;
+ // Ignore unnamed fields. Do not ignore unnamed records.
+ if (FieldName.empty() && !isa<RecordType>(Field->getType()))
+ continue;
- // Use VarDecl's Tag, Scope and Line number.
- llvm::DIVariable D =
- DBuilder.createLocalVariable(Tag, llvm::DIDescriptor(Scope),
- FieldName, Unit, Line, FieldTy,
- CGM.getLangOptions().Optimize, Flags);
+ // Use VarDecl's Tag, Scope and Line number.
+ llvm::DIVariable D =
+ DBuilder.createLocalVariable(Tag, llvm::DIDescriptor(Scope),
+ FieldName, Unit, Line, FieldTy,
+ CGM.getLangOptions().Optimize, Flags);
- // Insert an llvm.dbg.declare into the current block.
- llvm::Instruction *Call =
- DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());
+ // Insert an llvm.dbg.declare into the current block.
+ llvm::Instruction *Call =
+ DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());
- Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));
- }
+ Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));
}
+ }
+ }
}
/// EmitDeclare - Emit local variable declaration debug info.
@@ -1887,7 +1898,6 @@
llvm::SmallVector<llvm::Value *, 9> addr;
const llvm::Type *Int64Ty = llvm::Type::getInt64Ty(CGM.getLLVMContext());
- addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpDeref));
addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpPlus));
addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
if (isByRef) {
@@ -1936,7 +1946,146 @@
EmitDeclare(VD, llvm::dwarf::DW_TAG_arg_variable, AI, Builder);
}
+namespace {
+ struct BlockLayoutChunk {
+ uint64_t OffsetInBits;
+ const BlockDecl::Capture *Capture;
+ };
+ bool operator<(const BlockLayoutChunk &l, const BlockLayoutChunk &r) {
+ return l.OffsetInBits < r.OffsetInBits;
+ }
+}
+
+void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
+ llvm::Value *addr,
+ CGBuilderTy &Builder) {
+ ASTContext &C = CGM.getContext();
+ const BlockDecl *blockDecl = block.getBlockDecl();
+
+ // Collect some general information about the block's location.
+ SourceLocation loc = blockDecl->getCaretLocation();
+ llvm::DIFile tunit = getOrCreateFile(loc);
+ unsigned line = getLineNumber(loc);
+ unsigned column = getColumnNumber(loc);
+
+ // Build the debug-info type for the block literal.
+ llvm::DIDescriptor enclosingContext =
+ getContextDescriptor(cast<Decl>(blockDecl->getDeclContext()));
+
+ const llvm::StructLayout *blockLayout =
+ CGM.getTargetData().getStructLayout(block.StructureType);
+
+ llvm::SmallVector<llvm::Value*, 16> fields;
+ fields.push_back(createFieldType("__isa", C.VoidPtrTy, 0, loc, AS_public,
+ blockLayout->getElementOffsetInBits(0),
+ tunit));
+ fields.push_back(createFieldType("__flags", C.IntTy, 0, loc, AS_public,
+ blockLayout->getElementOffsetInBits(1),
+ tunit));
+ fields.push_back(createFieldType("__reserved", C.IntTy, 0, loc, AS_public,
+ blockLayout->getElementOffsetInBits(2),
+ tunit));
+ fields.push_back(createFieldType("__FuncPtr", C.VoidPtrTy, 0, loc, AS_public,
+ blockLayout->getElementOffsetInBits(3),
+ tunit));
+ fields.push_back(createFieldType("__descriptor",
+ C.getPointerType(block.NeedsCopyDispose ?
+ C.getBlockDescriptorExtendedType() :
+ C.getBlockDescriptorType()),
+ 0, loc, AS_public,
+ blockLayout->getElementOffsetInBits(4),
+ tunit));
+
+ // We want to sort the captures by offset, not because DWARF
+ // requires this, but because we're paranoid about debuggers.
+ llvm::SmallVector<BlockLayoutChunk, 8> chunks;
+
+ // 'this' capture.
+ if (blockDecl->capturesCXXThis()) {
+ BlockLayoutChunk chunk;
+ chunk.OffsetInBits =
+ blockLayout->getElementOffsetInBits(block.CXXThisIndex);
+ chunk.Capture = 0;
+ chunks.push_back(chunk);
+ }
+
+ // Variable captures.
+ for (BlockDecl::capture_const_iterator
+ i = blockDecl->capture_begin(), e = blockDecl->capture_end();
+ i != e; ++i) {
+ const BlockDecl::Capture &capture = *i;
+ const VarDecl *variable = capture.getVariable();
+ const CGBlockInfo::Capture &captureInfo = block.getCapture(variable);
+
+ // Ignore constant captures.
+ if (captureInfo.isConstant())
+ continue;
+
+ BlockLayoutChunk chunk;
+ chunk.OffsetInBits =
+ blockLayout->getElementOffsetInBits(captureInfo.getIndex());
+ chunk.Capture = &capture;
+ chunks.push_back(chunk);
+ }
+
+ // Sort by offset.
+ llvm::array_pod_sort(chunks.begin(), chunks.end());
+
+ for (llvm::SmallVectorImpl<BlockLayoutChunk>::iterator
+ i = chunks.begin(), e = chunks.end(); i != e; ++i) {
+ uint64_t offsetInBits = i->OffsetInBits;
+ const BlockDecl::Capture *capture = i->Capture;
+
+ // If we have a null capture, this must be the C++ 'this' capture.
+ if (!capture) {
+ const CXXMethodDecl *method =
+ cast<CXXMethodDecl>(blockDecl->getNonClosureContext());
+ QualType type = method->getThisType(C);
+ fields.push_back(createFieldType("this", type, 0, loc, AS_public,
+ offsetInBits, tunit));
+ continue;
+ }
+
+ const VarDecl *variable = capture->getVariable();
+ QualType type = (capture->isByRef() ? C.VoidPtrTy : variable->getType());
+ llvm::StringRef name = variable->getName();
+ fields.push_back(createFieldType(name, type, 0, loc, AS_public,
+ offsetInBits, tunit));
+ }
+
+ llvm::SmallString<36> typeName;
+ llvm::raw_svector_ostream(typeName)
+ << "__block_literal_" << CGM.getUniqueBlockCount();
+
+ llvm::DIArray fieldsArray =
+ DBuilder.getOrCreateArray(fields.data(), fields.size());
+
+ llvm::DIType type =
+ DBuilder.createStructType(tunit, typeName.str(), tunit, line,
+ CGM.getContext().toBits(block.BlockSize),
+ CGM.getContext().toBits(block.BlockAlign),
+ 0, fieldsArray);
+ type = DBuilder.createPointerType(type, CGM.PointerWidthInBits);
+
+ // Get overall information about the block.
+ unsigned flags = llvm::DIDescriptor::FlagArtificial;
+ llvm::MDNode *scope = RegionStack.back();
+ llvm::StringRef name = ".block_descriptor";
+
+ // Create the descriptor for the parameter.
+ llvm::DIVariable debugVar =
+ DBuilder.createLocalVariable(llvm::dwarf::DW_TAG_arg_variable,
+ llvm::DIDescriptor(scope),
+ name, tunit, line, type,
+ CGM.getLangOptions().Optimize, flags);
+
+ // Insert an llvm.dbg.value into the current block.
+ llvm::Instruction *declare =
+ DBuilder.insertDbgValueIntrinsic(addr, 0, debugVar,
+ Builder.GetInsertBlock());
+ declare->setDebugLoc(llvm::DebugLoc::get(line, column, scope));
+}
/// EmitGlobalVariable - Emit information about a global variable.
void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Tue Feb 22 16:38:33 2011
@@ -123,7 +123,10 @@
llvm::SmallVectorImpl<llvm::Value *> &EltTys,
llvm::DIType RecordTy);
-
+ llvm::DIType createFieldType(llvm::StringRef name, QualType type,
+ Expr *bitWidth, SourceLocation loc,
+ AccessSpecifier AS, uint64_t offsetInBits,
+ llvm::DIFile tunit);
void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile F,
llvm::SmallVectorImpl<llvm::Value *> &E);
@@ -180,6 +183,13 @@
void EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,
CGBuilderTy &Builder);
+ /// EmitDeclareOfBlockLiteralArgVariable - Emit call to
+ /// llvm.dbg.declare for the block-literal argument to a block
+ /// invocation function.
+ void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
+ llvm::Value *addr,
+ CGBuilderTy &Builder);
+
/// EmitGlobalVariable - Emit information about a global variable.
void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue Feb 22 16:38:33 2011
@@ -1004,6 +1004,24 @@
// FIXME: Why isn't ImplicitParamDecl a ParmVarDecl?
assert((isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)) &&
"Invalid argument to EmitParmDecl");
+
+ Arg->setName(D.getName());
+
+ // Use better IR generation for certain implicit parameters.
+ if (isa<ImplicitParamDecl>(D)) {
+ // The only implicit argument a block has is its literal.
+ if (BlockInfo) {
+ LocalDeclMap[&D] = Arg;
+
+ if (CGDebugInfo *DI = getDebugInfo()) {
+ DI->setLocation(D.getLocation());
+ DI->EmitDeclareOfBlockLiteralArgVariable(*BlockInfo, Arg, Builder);
+ }
+
+ return;
+ }
+ }
+
QualType Ty = D.getType();
llvm::Value *DeclPtr;
@@ -1020,7 +1038,6 @@
getContext().getDeclAlign(&D).getQuantity(), Ty,
CGM.getTBAAInfo(Ty));
}
- Arg->setName(D.getName());
llvm::Value *&DMEntry = LocalDeclMap[&D];
assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Feb 22 16:38:33 2011
@@ -389,8 +389,8 @@
unsigned Align,
const VarDecl *variable);
- /// getGlobalUniqueCount - Fetches the global unique block count.
- int getGlobalUniqueCount() { return ++Block.GlobalUniqueCount; }
+ /// getUniqueBlockCount - Fetches the global unique block count.
+ int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; }
/// getBlockDescriptorType - Fetches the type of a generic block
/// descriptor.
More information about the cfe-commits
mailing list