aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/DeclObjC.cpp
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2013-03-06 22:03:30 +0000
committerAdrian Prantl <aprantl@apple.com>2013-03-06 22:03:30 +0000
commit4919de6a53a007487c6d6b173921b5e7152a2004 (patch)
tree8b5292fac1a7ea0d07ecfa2f2b2c1fd8aea070e3 /lib/AST/DeclObjC.cpp
parent42773d64f98db0dd5cc80181c3b2d561851668f7 (diff)
Ensure that DIType is regenerated after we visit an implementation
that adds ivars to an interface. Fixes rdar://13175234 This is an update to r176116 that performs a smart caching of interfaces. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176584 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/DeclObjC.cpp')
-rw-r--r--lib/AST/DeclObjC.cpp53
1 files changed, 33 insertions, 20 deletions
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index d539e0098f..d1bf9a9e45 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -1093,38 +1093,51 @@ namespace {
/// all_declared_ivar_begin - return first ivar declared in this class,
/// its extensions and its implementation. Lazily build the list on first
/// 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() {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
return 0;
- if (data().IvarList)
- return data().IvarList;
-
ObjCIvarDecl *curIvar = 0;
- if (!ivar_empty()) {
- ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
- data().IvarList = *I; ++I;
- for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
- curIvar->setNextIvar(*I);
- }
+ if (!data().IvarList) {
+ if (!ivar_empty()) {
+ ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
+ data().IvarList = *I; ++I;
+ for (curIvar = data().IvarList; I != E; curIvar = *I, ++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 (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);
}
- for ( ;I != E; curIvar = *I, ++I)
- curIvar->setNextIvar(*I);
}
+ data().IvarListMissingImplementation = true;
}
+
+ // cached and complete!
+ if (!data().IvarListMissingImplementation)
+ return data().IvarList;
if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
+ data().IvarListMissingImplementation = false;
if (!ImplDecl->ivar_empty()) {
SmallVector<SynthesizeIvarChunk, 16> layout;
for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),