[cfe-commits] r144930 - in /cfe/trunk: include/clang/Basic/LangOptions.h include/clang/Frontend/ASTUnit.h include/clang/Frontend/CompilerInstance.h include/clang/Frontend/CompilerInvocation.h lib/ARCMigrate/ARCMT.cpp lib/Frontend/ASTUnit.cpp lib/Frontend/CompilerInstance.cpp lib/Frontend/CompilerInvocation.cpp tools/arcmt-test/arcmt-test.cpp tools/libclang/Indexing.cpp

Ted Kremenek kremenek at apple.com
Thu Nov 17 15:01:24 PST 2011


Author: kremenek
Date: Thu Nov 17 17:01:24 2011
New Revision: 144930

URL: http://llvm.org/viewvc/llvm-project?rev=144930&view=rev
Log:
Make 'LangOptions' in CompilerInvocation a heap-allocated, reference counted object.  I discovered that llvm::RefCountedBase<T> has
a bug where the reference count is copied in the copy constructor, which means that there were cases when the CompilerInvocation
objects created by ASTUnit were actually leaked.  When I fixed that bug locally, it showed that a whole bunch of code assumed
that the LangOptions object that was part of CompilerInvocation was still alive.  By making it heap-allocated and reference counted,
we can keep it around after the CompilerInvocation object goes away.

As part of this change, change CompilerInvocation:getLangOptions() to return a pointer, acting as another clue that this
object may outlive the CompilerInvocation object.

This commit doesn't fix the CompilerInvocation leak itself.  That will come when I commit the fix to llvm::RefCountedBase<T> to
mainline LLVM.

Modified:
    cfe/trunk/include/clang/Basic/LangOptions.h
    cfe/trunk/include/clang/Frontend/ASTUnit.h
    cfe/trunk/include/clang/Frontend/CompilerInstance.h
    cfe/trunk/include/clang/Frontend/CompilerInvocation.h
    cfe/trunk/lib/ARCMigrate/ARCMT.cpp
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Frontend/CompilerInstance.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/tools/arcmt-test/arcmt-test.cpp
    cfe/trunk/tools/libclang/Indexing.cpp

Modified: cfe/trunk/include/clang/Basic/LangOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.h?rev=144930&r1=144929&r2=144930&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/LangOptions.h (original)
+++ cfe/trunk/include/clang/Basic/LangOptions.h Thu Nov 17 17:01:24 2011
@@ -16,12 +16,13 @@
 
 #include <string>
 #include "clang/Basic/Visibility.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
 
 namespace clang {
 
 /// LangOptions - This class keeps track of the various options that can be
 /// enabled, which controls the dialect of C that is accepted.
-class LangOptions {
+class LangOptions : public llvm::RefCountedBase<LangOptions> {
 public:
   typedef clang::Visibility Visibility;
   

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=144930&r1=144929&r2=144930&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Thu Nov 17 17:01:24 2011
@@ -20,6 +20,7 @@
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "clang/Lex/ModuleLoader.h"
 #include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
@@ -69,6 +70,7 @@
 ///
 class ASTUnit : public ModuleLoader {
 private:
+  llvm::IntrusiveRefCntPtr<LangOptions>       LangOpts;
   llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
   llvm::IntrusiveRefCntPtr<FileManager>       FileMgr;
   llvm::IntrusiveRefCntPtr<SourceManager>     SourceMgr;

Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=144930&r1=144929&r2=144930&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original)
+++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Thu Nov 17 17:01:24 2011
@@ -218,10 +218,10 @@
   }
 
   LangOptions &getLangOpts() {
-    return Invocation->getLangOpts();
+    return *Invocation->getLangOpts();
   }
   const LangOptions &getLangOpts() const {
-    return Invocation->getLangOpts();
+    return *Invocation->getLangOpts();
   }
 
   PreprocessorOptions &getPreprocessorOpts() {

Modified: cfe/trunk/include/clang/Frontend/CompilerInvocation.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInvocation.h?rev=144930&r1=144929&r2=144930&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/CompilerInvocation.h (original)
+++ cfe/trunk/include/clang/Frontend/CompilerInvocation.h Thu Nov 17 17:01:24 2011
@@ -61,7 +61,7 @@
   HeaderSearchOptions HeaderSearchOpts;
 
   /// Options controlling the language variant.
-  LangOptions LangOpts;
+  llvm::IntrusiveRefCntPtr<LangOptions> LangOpts;
 
   /// Options controlling the preprocessor (aside from #include handling).
   PreprocessorOptions PreprocessorOpts;
@@ -73,7 +73,7 @@
   TargetOptions TargetOpts;
 
 public:
-  CompilerInvocation() {}
+  CompilerInvocation();
 
   /// @name Utility Methods
   /// @{
@@ -111,7 +111,7 @@
   /// \param LangStd - The input language standard.
   void setLangDefaults(InputKind IK,
                   LangStandard::Kind LangStd = LangStandard::lang_unspecified) {
-    setLangDefaults(LangOpts, IK, LangStd);
+    setLangDefaults(*LangOpts, IK, LangStd);
   }
 
   /// setLangDefaults - Set language defaults for the given input language and
@@ -166,8 +166,10 @@
     return FrontendOpts;
   }
 
-  LangOptions &getLangOpts() { return LangOpts; }
-  const LangOptions &getLangOpts() const { return LangOpts; }
+  LangOptions *getLangOpts() { return LangOpts.getPtr(); }
+  const LangOptions *getLangOpts() const { return LangOpts.getPtr(); }
+
+  void setLangOpts(LangOptions *LangOpts);
 
   PreprocessorOptions &getPreprocessorOpts() { return PreprocessorOpts; }
   const PreprocessorOptions &getPreprocessorOpts() const {

Modified: cfe/trunk/lib/ARCMigrate/ARCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ARCMT.cpp?rev=144930&r1=144929&r2=144930&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ARCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ARCMT.cpp Thu Nov 17 17:01:24 2011
@@ -190,13 +190,14 @@
   CInvok->getPreprocessorOpts().ImplicitPTHInclude = std::string();
   std::string define = getARCMTMacroName();
   define += '=';
+  CInvok->setLangOpts(new LangOptions(*CInvok->getLangOpts()));
   CInvok->getPreprocessorOpts().addMacroDef(define);
-  CInvok->getLangOpts().ObjCAutoRefCount = true;
-  CInvok->getLangOpts().setGC(LangOptions::NonGC);
+  CInvok->getLangOpts()->ObjCAutoRefCount = true;
+  CInvok->getLangOpts()->setGC(LangOptions::NonGC);
   CInvok->getDiagnosticOpts().ErrorLimit = 0;
   CInvok->getDiagnosticOpts().Warnings.push_back(
                                             "error=arc-unsafe-retained-assign");
-  CInvok->getLangOpts().ObjCRuntimeHasWeak = HasARCRuntime(origCI);
+  CInvok->getLangOpts()->ObjCRuntimeHasWeak = HasARCRuntime(origCI);
 
   return CInvok.take();
 }
@@ -224,10 +225,10 @@
                                  DiagnosticConsumer *DiagClient,
                                  bool emitPremigrationARCErrors,
                                  StringRef plistOut) {
-  if (!origCI.getLangOpts().ObjC1)
+  if (!origCI.getLangOpts()->ObjC1)
     return false;
 
-  LangOptions::GCMode OrigGCMode = origCI.getLangOpts().getGC();
+  LangOptions::GCMode OrigGCMode = origCI.getLangOpts()->getGC();
 
   std::vector<TransformFn> transforms = arcmt::getAllTransformations(OrigGCMode);
   assert(!transforms.empty());
@@ -301,7 +302,7 @@
 
   // If we are migrating code that gets the '-fobjc-arc' flag, make sure
   // to remove it so that we don't get errors from normal compilation.
-  origCI.getLangOpts().ObjCAutoRefCount = false;
+  origCI.getLangOpts()->ObjCAutoRefCount = false;
 
   return capturedDiags.hasErrors() || testAct.hasReportedErrors();
 }
@@ -316,10 +317,10 @@
                             StringRef outputDir,
                             bool emitPremigrationARCErrors,
                             StringRef plistOut) {
-  if (!origCI.getLangOpts().ObjC1)
+  if (!origCI.getLangOpts()->ObjC1)
     return false;
 
-  LangOptions::GCMode OrigGCMode = origCI.getLangOpts().getGC();
+  LangOptions::GCMode OrigGCMode = origCI.getLangOpts()->getGC();
 
   // Make sure checking is successful first.
   CompilerInvocation CInvokForCheck(origCI);
@@ -346,12 +347,12 @@
       new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false));
 
   if (outputDir.empty()) {
-    origCI.getLangOpts().ObjCAutoRefCount = true;
+    origCI.getLangOpts()->ObjCAutoRefCount = true;
     return migration.getRemapper().overwriteOriginal(*Diags);
   } else {
     // If we are migrating code that gets the '-fobjc-arc' flag, make sure
     // to remove it so that we don't get errors from normal compilation.
-    origCI.getLangOpts().ObjCAutoRefCount = false;
+    origCI.getLangOpts()->ObjCAutoRefCount = false;
     return migration.getRemapper().flushToDisk(outputDir, *Diags);
   }
 }
@@ -542,7 +543,7 @@
 
   Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOptions());
   TransformActions TA(*Diags, capturedDiags, Ctx, Unit->getPreprocessor());
-  MigrationPass pass(Ctx, OrigCI.getLangOpts().getGC(),
+  MigrationPass pass(Ctx, OrigCI.getLangOpts()->getGC(),
                      Unit->getSema(), TA, ARCMTMacroLocs);
 
   trans(pass);

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=144930&r1=144929&r2=144930&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Thu Nov 17 17:01:24 2011
@@ -1041,6 +1041,7 @@
 
   // Configure the various subsystems.
   // FIXME: Should we retain the previous file manager?
+  LangOpts = &Clang->getLangOpts();
   FileSystemOpts = Clang->getFileSystemOpts();
   FileMgr = new FileManager(FileSystemOpts);
   SourceMgr = new SourceManager(getDiagnostics(), *FileMgr);
@@ -1247,7 +1248,7 @@
   }
   
   return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer,
-                                                       Invocation.getLangOpts(),
+                                                       *Invocation.getLangOpts(),
                                                        MaxLines));
 }
 
@@ -2230,7 +2231,7 @@
   FrontendOpts.CodeCompletionAt.Column = Column;
 
   // Set the language options appropriately.
-  LangOpts = CCInvocation->getLangOpts();
+  LangOpts = *CCInvocation->getLangOpts();
 
   llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance());
 

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=144930&r1=144929&r2=144930&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Thu Nov 17 17:01:24 2011
@@ -987,11 +987,11 @@
 
   // For any options that aren't intended to affect how a module is built,
   // reset them to their default values.
-  Invocation->getLangOpts().resetNonModularOptions();
+  Invocation->getLangOpts()->resetNonModularOptions();
   Invocation->getPreprocessorOpts().resetNonModularOptions();
 
   // Note the name of the module we're building.
-  Invocation->getLangOpts().CurrentModule = ModuleName;
+  Invocation->getLangOpts()->CurrentModule = ModuleName;
 
   // Note that this module is part of the module build path, so that we
   // can detect cycles in the module graph.
@@ -1004,7 +1004,7 @@
   FrontendOpts.DisableFree = false;
   FrontendOpts.Inputs.clear();
   FrontendOpts.Inputs.push_back(
-    std::make_pair(getSourceInputKindFromOptions(Invocation->getLangOpts()),
+    std::make_pair(getSourceInputKindFromOptions(*Invocation->getLangOpts()),
                                                  UmbrellaHeader));
 
   Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=144930&r1=144929&r2=144930&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Thu Nov 17 17:01:24 2011
@@ -30,6 +30,21 @@
 #include "llvm/Support/Path.h"
 using namespace clang;
 
+//===----------------------------------------------------------------------===//
+// Initialization.
+//===----------------------------------------------------------------------===//
+
+CompilerInvocation::CompilerInvocation()
+  : LangOpts(new LangOptions()) {}
+
+void CompilerInvocation::setLangOpts(LangOptions *LOpts) {
+  LangOpts = LOpts;
+}
+
+//===----------------------------------------------------------------------===//
+// Utility functions.
+//===----------------------------------------------------------------------===//
+
 static const char *getAnalysisStoreName(AnalysisStores Kind) {
   switch (Kind) {
   default:
@@ -892,7 +907,7 @@
   FileSystemOptsToArgs(getFileSystemOpts(), Res);
   FrontendOptsToArgs(getFrontendOpts(), Res);
   HeaderSearchOptsToArgs(getHeaderSearchOpts(), Res);
-  LangOptsToArgs(getLangOpts(), Res);
+  LangOptsToArgs(*getLangOpts(), Res);
   PreprocessorOptsToArgs(getPreprocessorOpts(), Res);
   PreprocessorOutputOptsToArgs(getPreprocessorOutputOpts(), Res);
   TargetOptsToArgs(getTargetOpts(), Res);
@@ -1982,9 +1997,9 @@
   ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, DashX, Diags);
   ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args);
   if (DashX != IK_AST && DashX != IK_LLVM_IR) {
-    ParseLangArgs(Res.getLangOpts(), *Args, DashX, Diags);
+    ParseLangArgs(*Res.getLangOpts(), *Args, DashX, Diags);
     if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC)
-      Res.getLangOpts().ObjCExceptions = 1;
+      Res.getLangOpts()->ObjCExceptions = 1;
   }
   // FIXME: ParsePreprocessorArgs uses the FileManager to read the contents of
   // PCH file and find the original header name. Remove the need to do that in
@@ -2057,9 +2072,9 @@
   
   // Extend the signature with the language options
 #define LANGOPT(Name, Bits, Default, Description) \
-  Signature.add(LangOpts.Name, Bits);
+  Signature.add(LangOpts->Name, Bits);
 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
-  Signature.add(static_cast<unsigned>(LangOpts.get##Name()), Bits);
+  Signature.add(static_cast<unsigned>(LangOpts->get##Name()), Bits);
 #define BENIGN_LANGOPT(Name, Bits, Default, Description)
 #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
 #include "clang/Basic/LangOptions.def"

Modified: cfe/trunk/tools/arcmt-test/arcmt-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/arcmt-test/arcmt-test.cpp?rev=144930&r1=144929&r2=144930&view=diff
==============================================================================
--- cfe/trunk/tools/arcmt-test/arcmt-test.cpp (original)
+++ cfe/trunk/tools/arcmt-test/arcmt-test.cpp Thu Nov 17 17:01:24 2011
@@ -125,7 +125,7 @@
     return true;
   }
 
-  if (!CI.getLangOpts().ObjC1)
+  if (!CI.getLangOpts()->ObjC1)
     return false;
 
   arcmt::checkForManualIssues(CI,
@@ -167,13 +167,13 @@
     return true;
   }
 
-  if (!origCI.getLangOpts().ObjC1)
+  if (!origCI.getLangOpts()->ObjC1)
     return false;
 
   MigrationProcess migration(origCI, DiagClient);
 
   std::vector<TransformFn>
-    transforms = arcmt::getAllTransformations(origCI.getLangOpts().getGC());
+    transforms = arcmt::getAllTransformations(origCI.getLangOpts()->getGC());
   assert(!transforms.empty());
 
   llvm::OwningPtr<PrintTransforms> transformPrinter;

Modified: cfe/trunk/tools/libclang/Indexing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/Indexing.cpp?rev=144930&r1=144929&r2=144930&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/Indexing.cpp (original)
+++ cfe/trunk/tools/libclang/Indexing.cpp Thu Nov 17 17:01:24 2011
@@ -333,7 +333,7 @@
   // (often very broken) source code, where spell-checking can have a
   // significant negative impact on performance (particularly when 
   // precompiled headers are involved), we disable it.
-  CInvok->getLangOpts().SpellChecking = false;
+  CInvok->getLangOpts()->SpellChecking = false;
 
   if (!requestedToGetTU)
     CInvok->getPreprocessorOpts().DetailedRecord = false;





More information about the cfe-commits mailing list