From a03a85a425842ff5528caec7e7d6ebfdf4528a62 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Wed, 6 Mar 2013 22:03:30 +0000 Subject: 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. llvm-svn: 176584 --- clang/lib/AST/DeclObjC.cpp | 53 +++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 20 deletions(-) (limited to 'clang/lib/AST/DeclObjC.cpp') diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index d539e0098ff..d1bf9a9e45a 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/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 layout; for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(), -- cgit v1.2.3