]> granicus.if.org Git - clang/commitdiff
Simplify lifetime management of MacroInfo objects in Preprocessor by having the Prepr...
authorTed Kremenek <kremenek@apple.com>
Tue, 19 Oct 2010 18:16:54 +0000 (18:16 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 19 Oct 2010 18:16:54 +0000 (18:16 +0000)
list of allocated MacroInfos.  This requires only 1 extra pointer per MacroInfo object, and allows us to blow them
away in one place.  This fixes an elusive memory leak with MacroInfos (whose exact location I couldn't still figure
out despite substantial digging).

Fixes <rdar://problem/8361834>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116842 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/Preprocessor.h
lib/Lex/PPDirectives.cpp
lib/Lex/Preprocessor.cpp

index 752cbed7b364752cf1532cd816c399e3a48cbb89..a1a68dce45172876c421f914e90c0a2b7d13173a 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
 #define LLVM_CLANG_LEX_PREPROCESSOR_H
 
+#include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Lex/PTHLexer.h"
 #include "clang/Lex/PPCallbacks.h"
@@ -251,6 +252,15 @@ private:  // Cached tokens state.
   /// invoked (at which point the last position is popped).
   std::vector<CachedTokensTy::size_type> BacktrackPositions;
 
+  struct MacroInfoChain {
+    MacroInfo MI;
+    MacroInfoChain *Next;
+  };
+
+  /// MacroInfos are managed as a chain for easy disposal.  This is the head
+  /// of that list.
+  MacroInfoChain *MIChainHead;
+
 public:
   Preprocessor(Diagnostic &diags, const LangOptions &opts,
                const TargetInfo &target,
index 5e3b16e60de9c3a05b641aafaa4de8a4172b7cac..ffdc6ae5894e67023193f3cdfa0556ce5a5a3325 100644 (file)
@@ -33,8 +33,12 @@ MacroInfo *Preprocessor::AllocateMacroInfo() {
   if (!MICache.empty()) {
     MI = MICache.back();
     MICache.pop_back();
-  } else
-    MI = (MacroInfo*) BP.Allocate<MacroInfo>();
+  } else {
+    MacroInfoChain *MIChain = BP.Allocate<MacroInfoChain>();
+    MIChain->Next = MIChainHead;
+    MIChainHead = MIChain;
+    MI = &(MIChainHead->MI);
+  }
   return MI;
 }
 
index 56ed7659249c0960dda89e5fd5efb82ad29d2611..9a695004c9298e85e9eb606c997ecf120a0387e3 100644 (file)
@@ -56,7 +56,7 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
     SourceMgr(SM), HeaderInfo(Headers), ExternalSource(0),
     Identifiers(opts, IILookup), BuiltinInfo(Target), CodeComplete(0),
     CodeCompletionFile(0), SkipMainFilePreamble(0, true), CurPPLexer(0), 
-    CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0) {
+    CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0), MIChainHead(0) {
   ScratchBuf = new ScratchBuffer(SourceMgr);
   CounterValue = 0; // __COUNTER__ starts at 0.
   OwnsHeaderSearch = OwnsHeaders;
@@ -106,29 +106,10 @@ Preprocessor::~Preprocessor() {
   }
 
   // Free any macro definitions.
-  for (llvm::DenseMap<IdentifierInfo*, MacroInfo*>::iterator I =
-       Macros.begin(), E = Macros.end(); I != E; ++I) {
-    // We don't need to free the MacroInfo objects directly.  These
-    // will be released when the BumpPtrAllocator 'BP' object gets
-    // destroyed.  We still need to run the dtor, however, to free
-    // memory alocated by MacroInfo.
-    I->second->Destroy();
-    I->first->setHasMacroDefinition(false);
-  }
-  for (std::vector<MacroInfo*>::iterator I = MICache.begin(),
-                                         E = MICache.end(); I != E; ++I) {
-    // We don't need to free the MacroInfo objects directly.  These
-    // will be released when the BumpPtrAllocator 'BP' object gets
-    // destroyed.  We still need to run the dtor, however, to free
-    // memory alocated by MacroInfo.
-    (*I)->Destroy();
-  }
-  for (llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> >::iterator I =
-         PragmaPushMacroInfo.begin(), E = PragmaPushMacroInfo.end(); I!=E; ++I){
-    for (std::vector<MacroInfo*>::iterator I2 = I->second.begin(), E2 = I->second.end();
-         I2 != E2; ++I2) {
-      (*I2)->Destroy();
-    }
+  for (MacroInfoChain *I = MIChainHead ; I ; ) {
+    MacroInfoChain *Next = I->Next;
+    I->MI.Destroy();
+    I = Next;
   }
 
   // Free any cached macro expanders.