зеркало из https://github.com/microsoft/clang-1.git
Temporarily revert r176116 for compile-time performance regression.
This reverts commit ea95e4587fd13606fbf63b10a07a7d02026aa39c. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176151 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
b7a3f74bbb
Коммит
10b4df7ff2
|
@ -651,10 +651,6 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||||
/// completed by the external AST source when required.
|
/// completed by the external AST source when required.
|
||||||
mutable bool ExternallyCompleted : 1;
|
mutable bool ExternallyCompleted : 1;
|
||||||
|
|
||||||
/// \brief Indicates that the ivar cache does not yet include ivars
|
|
||||||
/// declared in the implementation.
|
|
||||||
mutable bool IvarListMissingImplementation : 1;
|
|
||||||
|
|
||||||
/// \brief The location of the superclass, if any.
|
/// \brief The location of the superclass, if any.
|
||||||
SourceLocation SuperClassLoc;
|
SourceLocation SuperClassLoc;
|
||||||
|
|
||||||
|
@ -664,8 +660,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||||
SourceLocation EndLoc;
|
SourceLocation EndLoc;
|
||||||
|
|
||||||
DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(),
|
DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(),
|
||||||
ExternallyCompleted(),
|
ExternallyCompleted() { }
|
||||||
IvarListMissingImplementation(true) { }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
|
ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
|
||||||
|
|
|
@ -1093,51 +1093,38 @@ namespace {
|
||||||
/// all_declared_ivar_begin - return first ivar declared in this class,
|
/// all_declared_ivar_begin - return first ivar declared in this class,
|
||||||
/// its extensions and its implementation. Lazily build the list on first
|
/// its extensions and its implementation. Lazily build the list on first
|
||||||
/// access.
|
/// access.
|
||||||
///
|
|
||||||
/// Caveat: The list returned by this method reflects the current
|
|
||||||
/// state of the parser. The cache will be updated for every ivar
|
|
||||||
/// added by an extension or the implementation when they are
|
|
||||||
/// encountered.
|
|
||||||
/// See also ObjCIvarDecl::Create().
|
|
||||||
ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
|
ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
|
||||||
// FIXME: Should make sure no callers ever do this.
|
// FIXME: Should make sure no callers ever do this.
|
||||||
if (!hasDefinition())
|
if (!hasDefinition())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (data().IvarList)
|
||||||
|
return data().IvarList;
|
||||||
|
|
||||||
ObjCIvarDecl *curIvar = 0;
|
ObjCIvarDecl *curIvar = 0;
|
||||||
if (!data().IvarList) {
|
if (!ivar_empty()) {
|
||||||
if (!ivar_empty()) {
|
ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
|
||||||
ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
|
data().IvarList = *I; ++I;
|
||||||
data().IvarList = *I; ++I;
|
for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
|
||||||
for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
|
curIvar->setNextIvar(*I);
|
||||||
curIvar->setNextIvar(*I);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ObjCInterfaceDecl::known_extensions_iterator
|
|
||||||
Ext = known_extensions_begin(),
|
|
||||||
ExtEnd = known_extensions_end();
|
|
||||||
Ext != ExtEnd; ++Ext) {
|
|
||||||
if (!Ext->ivar_empty()) {
|
|
||||||
ObjCCategoryDecl::ivar_iterator
|
|
||||||
I = Ext->ivar_begin(),
|
|
||||||
E = Ext->ivar_end();
|
|
||||||
if (!data().IvarList) {
|
|
||||||
data().IvarList = *I; ++I;
|
|
||||||
curIvar = data().IvarList;
|
|
||||||
}
|
|
||||||
for ( ;I != E; curIvar = *I, ++I)
|
|
||||||
curIvar->setNextIvar(*I);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data().IvarListMissingImplementation = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// cached and complete!
|
for (ObjCInterfaceDecl::known_extensions_iterator
|
||||||
if (!data().IvarListMissingImplementation)
|
Ext = known_extensions_begin(),
|
||||||
return data().IvarList;
|
ExtEnd = known_extensions_end();
|
||||||
|
Ext != ExtEnd; ++Ext) {
|
||||||
|
if (!Ext->ivar_empty()) {
|
||||||
|
ObjCCategoryDecl::ivar_iterator I = Ext->ivar_begin(),E = Ext->ivar_end();
|
||||||
|
if (!data().IvarList) {
|
||||||
|
data().IvarList = *I; ++I;
|
||||||
|
curIvar = data().IvarList;
|
||||||
|
}
|
||||||
|
for ( ;I != E; curIvar = *I, ++I)
|
||||||
|
curIvar->setNextIvar(*I);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
|
if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
|
||||||
data().IvarListMissingImplementation = false;
|
|
||||||
if (!ImplDecl->ivar_empty()) {
|
if (!ImplDecl->ivar_empty()) {
|
||||||
SmallVector<SynthesizeIvarChunk, 16> layout;
|
SmallVector<SynthesizeIvarChunk, 16> layout;
|
||||||
for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
|
for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
|
||||||
|
|
|
@ -1343,7 +1343,7 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {
|
||||||
LexicalBlockStack.push_back(FwdDeclNode);
|
LexicalBlockStack.push_back(FwdDeclNode);
|
||||||
RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
|
RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
|
||||||
|
|
||||||
// Add this to the completed-type cache while we're completing it recursively.
|
// Add this to the completed types cache since we're completing it.
|
||||||
CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
|
CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
|
||||||
|
|
||||||
// Convert all the elements.
|
// Convert all the elements.
|
||||||
|
@ -1436,8 +1436,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
|
||||||
|
|
||||||
// Otherwise, insert it into the CompletedTypeCache so that recursive uses
|
// Otherwise, insert it into the CompletedTypeCache so that recursive uses
|
||||||
// will find it and we're emitting the complete type.
|
// will find it and we're emitting the complete type.
|
||||||
QualType QualTy = QualType(Ty, 0);
|
CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RealDecl;
|
||||||
CompletedTypeCache[QualTy.getAsOpaquePtr()] = RealDecl;
|
|
||||||
// Push the struct on region stack.
|
// Push the struct on region stack.
|
||||||
llvm::TrackingVH<llvm::MDNode> FwdDeclNode(RealDecl);
|
llvm::TrackingVH<llvm::MDNode> FwdDeclNode(RealDecl);
|
||||||
|
|
||||||
|
@ -1562,12 +1561,6 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
|
||||||
|
|
||||||
llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
|
llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
|
||||||
FwdDeclNode->replaceOperandWith(10, Elements);
|
FwdDeclNode->replaceOperandWith(10, 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();
|
LexicalBlockStack.pop_back();
|
||||||
return llvm::DIType(FwdDeclNode);
|
return llvm::DIType(FwdDeclNode);
|
||||||
|
@ -1831,10 +1824,6 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
|
||||||
ReplaceMap.push_back(std::make_pair(Ty.getAsOpaquePtr(),
|
ReplaceMap.push_back(std::make_pair(Ty.getAsOpaquePtr(),
|
||||||
static_cast<llvm::Value*>(TC)));
|
static_cast<llvm::Value*>(TC)));
|
||||||
|
|
||||||
// Do not cache the type if it may be incomplete.
|
|
||||||
if (maybeIncompleteInterface(Ty))
|
|
||||||
return Res;
|
|
||||||
|
|
||||||
// And update the type cache.
|
// And update the type cache.
|
||||||
TypeCache[Ty.getAsOpaquePtr()] = Res;
|
TypeCache[Ty.getAsOpaquePtr()] = Res;
|
||||||
|
|
||||||
|
@ -1844,21 +1833,6 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
|
||||||
return Res;
|
return Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// clang::ParseAST handles each TopLevelDecl immediately after it was parsed.
|
|
||||||
/// A subsequent implementation may add more ivars to an interface, which is
|
|
||||||
/// why we cannot cache it yet.
|
|
||||||
bool CGDebugInfo::maybeIncompleteInterface(QualType Ty) {
|
|
||||||
switch (Ty->getTypeClass()) {
|
|
||||||
case Type::ObjCObjectPointer:
|
|
||||||
return maybeIncompleteInterface(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
|
|
||||||
case Type::ObjCInterface:
|
|
||||||
if (ObjCInterfaceDecl *Decl = cast<ObjCInterfaceType>(Ty)->getDecl())
|
|
||||||
return (Decl->getImplementation() == 0);
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// CreateTypeNode - Create a new debug type node.
|
/// CreateTypeNode - Create a new debug type node.
|
||||||
llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {
|
llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {
|
||||||
// Handle qualifiers, which recursively handles what they refer to.
|
// Handle qualifiers, which recursively handles what they refer to.
|
||||||
|
|
|
@ -299,10 +299,6 @@ private:
|
||||||
/// CreateTypeNode - Create type metadata for a source language type.
|
/// CreateTypeNode - Create type metadata for a source language type.
|
||||||
llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F);
|
llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F);
|
||||||
|
|
||||||
/// maybeIncompleteInterface - Determine if Ty may contain an
|
|
||||||
/// interface without an implementation
|
|
||||||
bool maybeIncompleteInterface(QualType Ty);
|
|
||||||
|
|
||||||
/// CreateLimitedTypeNode - Create type metadata for a source language
|
/// CreateLimitedTypeNode - Create type metadata for a source language
|
||||||
/// type, but only partial types for records.
|
/// type, but only partial types for records.
|
||||||
llvm::DIType CreateLimitedTypeNode(QualType Ty, llvm::DIFile F);
|
llvm::DIType CreateLimitedTypeNode(QualType Ty, llvm::DIFile F);
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -g %s -o - | FileCheck %s
|
|
||||||
|
|
||||||
// Debug symbols for private IVars
|
|
||||||
|
|
||||||
@interface I
|
|
||||||
{
|
|
||||||
@public int a;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
void foo(I* pi) {
|
|
||||||
// poking into pi for primary class ivars.
|
|
||||||
int _a = pi->a;
|
|
||||||
}
|
|
||||||
|
|
||||||
@interface I()
|
|
||||||
{
|
|
||||||
@public int b;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
void gorf (I* pg) {
|
|
||||||
// poking into pg for ivars for class extension
|
|
||||||
int _b = pg->b;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"a", metadata !{{[0-9]*}}, i32 7, i64 32, i64 32, i64 0, i32 0, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [a] [line 7, size 32, align 32, offset 0] [from int]
|
|
||||||
// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"b", metadata !{{[0-9]*}}, i32 18, i64 32, i64 32, i64 0, i32 0, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [b] [line 18, size 32, align 32, offset 0] [from int]
|
|
|
@ -1,31 +0,0 @@
|
||||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -g %s -o - | FileCheck %s
|
|
||||||
|
|
||||||
// Debug symbols for private IVars
|
|
||||||
|
|
||||||
@interface I
|
|
||||||
{
|
|
||||||
@public int a;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
void foo(I* pi) {
|
|
||||||
int _a = pi->a;
|
|
||||||
}
|
|
||||||
|
|
||||||
// another layer of indirection
|
|
||||||
struct S
|
|
||||||
{
|
|
||||||
I* i;
|
|
||||||
};
|
|
||||||
|
|
||||||
@interface I()
|
|
||||||
{
|
|
||||||
@public int b;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
void gorf (struct S* s) {
|
|
||||||
int _b = s->i->b;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"b", metadata !{{[0-9]*}}, i32 23, i64 32, i64 32, i64 0, i32 0, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [b] [line 23, size 32, align 32, offset 0] [from int]
|
|
|
@ -1,36 +0,0 @@
|
||||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -g %s -o - | FileCheck %s
|
|
||||||
|
|
||||||
// Debug symbols for private IVars. This test ensures that we are generating
|
|
||||||
// DI for ivars added ny the implementation.
|
|
||||||
__attribute((objc_root_class)) @interface NSObject {
|
|
||||||
id isa;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@protocol Protocol
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface Delegate : NSObject<Protocol> {
|
|
||||||
@protected int foo;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface Delegate(NSObject)
|
|
||||||
- (void)f;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation Delegate(NSObject)
|
|
||||||
- (void)f { return; }
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation Delegate {
|
|
||||||
int bar;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)g:(NSObject*) anObject {
|
|
||||||
bar = foo;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"foo", metadata !{{[0-9]*}}, i32 14, i64 32, i64 32, i64 0, i32 2, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [foo] [line 14, size 32, align 32, offset 0] [protected] [from int]
|
|
||||||
// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"bar", metadata !{{[0-9]*}}, i32 27, i64 32, i64 32, i64 0, i32 1, metadata !{{[0-9]*}}, null} ; [ DW_TAG_member ] [bar] [line 27, size 32, align 32, offset 0] [private] [from int]
|
|
Загрузка…
Ссылка в новой задаче