[cfe-commits] r124227 - in /cfe/trunk: include/clang/AST/ASTMutationListener.h include/clang/CodeGen/CodeGenAction.h include/clang/Driver/CC1Options.td include/clang/Frontend/FrontendAction.h include/clang/Frontend/FrontendOptions.h include/clang/Frontend/MultiplexConsumer.h lib/CodeGen/CodeGenAction.cpp lib/Frontend/CompilerInvocation.cpp lib/Frontend/FrontendAction.cpp lib/Frontend/MultiplexConsumer.cpp

Nico Weber nicolasweber at gmx.de
Tue Jan 25 12:34:14 PST 2011


Author: nico
Date: Tue Jan 25 14:34:14 2011
New Revision: 124227

URL: http://llvm.org/viewvc/llvm-project?rev=124227&view=rev
Log:
Add -add-plugin flag, which runs plugins in addition to codegen.

Added:
    cfe/trunk/include/clang/Frontend/MultiplexConsumer.h
    cfe/trunk/lib/Frontend/MultiplexConsumer.cpp
Modified:
    cfe/trunk/include/clang/AST/ASTMutationListener.h
    cfe/trunk/include/clang/CodeGen/CodeGenAction.h
    cfe/trunk/include/clang/Driver/CC1Options.td
    cfe/trunk/include/clang/Frontend/FrontendAction.h
    cfe/trunk/include/clang/Frontend/FrontendOptions.h
    cfe/trunk/lib/CodeGen/CodeGenAction.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Frontend/FrontendAction.cpp

Modified: cfe/trunk/include/clang/AST/ASTMutationListener.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTMutationListener.h?rev=124227&r1=124226&r2=124227&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTMutationListener.h (original)
+++ cfe/trunk/include/clang/AST/ASTMutationListener.h Tue Jan 25 14:34:14 2011
@@ -15,6 +15,7 @@
 
 namespace clang {
   class Decl;
+  class DeclContext;
   class TagDecl;
   class CXXRecordDecl;
   class ClassTemplateDecl;

Modified: cfe/trunk/include/clang/CodeGen/CodeGenAction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/CodeGenAction.h?rev=124227&r1=124226&r2=124227&view=diff
==============================================================================
--- cfe/trunk/include/clang/CodeGen/CodeGenAction.h (original)
+++ cfe/trunk/include/clang/CodeGen/CodeGenAction.h Tue Jan 25 14:34:14 2011
@@ -18,6 +18,7 @@
 }
 
 namespace clang {
+class BackendConsumer;
 
 class CodeGenAction : public ASTFrontendAction {
 private:
@@ -42,6 +43,8 @@
   /// takeModule - Take the generated LLVM module, for use after the action has
   /// been run. The result may be null on failure.
   llvm::Module *takeModule();
+
+  BackendConsumer *BEConsumer;
 };
 
 class EmitAssemblyAction : public CodeGenAction {

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=124227&r1=124226&r2=124227&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Tue Jan 25 14:34:14 2011
@@ -290,10 +290,12 @@
 def load : Separate<"-load">, MetaVarName<"<dsopath>">,
   HelpText<"Load the named plugin (dynamic shared object)">;
 def plugin : Separate<"-plugin">, MetaVarName<"<name>">,
-  HelpText<"Use the named plugin action (use \"help\" to list available options)">;
+  HelpText<"Use the named plugin action instead of the default action (use \"help\" to list available options)">;
 def plugin_arg : JoinedAndSeparate<"-plugin-arg-">,
     MetaVarName<"<name> <arg>">,
     HelpText<"Pass <arg> to plugin <name>">;
+def add_plugin : Separate<"-add-plugin">, MetaVarName<"<name>">,
+  HelpText<"Use the named plugin action in addition to the default action">;
 def resource_dir : Separate<"-resource-dir">,
   HelpText<"The directory which holds the compiler resource files">;
 def version : Flag<"-version">,

Modified: cfe/trunk/include/clang/Frontend/FrontendAction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendAction.h?rev=124227&r1=124226&r2=124227&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendAction.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendAction.h Tue Jan 25 14:34:14 2011
@@ -52,6 +52,10 @@
   CompilerInstance *Instance;
   friend class ASTMergeAction;
 
+private:
+  ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI,
+                                        llvm::StringRef InFile);
+
 protected:
   /// @name Implementation Action Interface
   /// @{

Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=124227&r1=124226&r2=124227&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Tue Jan 25 14:34:14 2011
@@ -103,6 +103,9 @@
   /// Arg to pass to the plugin
   std::vector<std::string> PluginArgs;
 
+  /// The list of plugin actions to run in addition to the normal action.
+  std::vector<std::string> AddPluginActions;
+
   /// The list of plugins to load.
   std::vector<std::string> Plugins;
 

Added: cfe/trunk/include/clang/Frontend/MultiplexConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/MultiplexConsumer.h?rev=124227&view=auto
==============================================================================
--- cfe/trunk/include/clang/Frontend/MultiplexConsumer.h (added)
+++ cfe/trunk/include/clang/Frontend/MultiplexConsumer.h Tue Jan 25 14:34:14 2011
@@ -0,0 +1,54 @@
+//===-- MultiplexConsumer.h - AST Consumer for PCH Generation ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file declares the MultiplexConsumer class, which can be used to
+//  multiplex ASTConsumer and SemaConsumer messages to many consumers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Sema/SemaConsumer.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <vector>
+
+namespace clang {
+
+class MultiplexASTMutationListener;
+class MultiplexASTDeserializationListener;
+
+// Has a list of ASTConsumers and calls each of them. Owns its children.
+class MultiplexConsumer : public SemaConsumer {
+public:
+  // Takes ownership of the pointers in C.
+  MultiplexConsumer(const std::vector<ASTConsumer*>& C);
+  ~MultiplexConsumer();
+
+  // ASTConsumer
+  virtual void Initialize(ASTContext &Context);
+  virtual void HandleTopLevelDecl(DeclGroupRef D);
+  virtual void HandleInterestingDecl(DeclGroupRef D);
+  virtual void HandleTranslationUnit(ASTContext &Ctx);
+  virtual void HandleTagDeclDefinition(TagDecl *D);
+  virtual void CompleteTentativeDefinition(VarDecl *D);
+  virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired);
+  virtual ASTMutationListener *GetASTMutationListener();
+  virtual ASTDeserializationListener *GetASTDeserializationListener();
+  virtual void PrintStats();
+
+  // SemaConsumer
+  virtual void InitializeSema(Sema &S);
+  virtual void ForgetSema();
+
+  static bool classof(const MultiplexConsumer *) { return true; }
+private:
+  std::vector<ASTConsumer*> Consumers;  // Owns these.
+  llvm::OwningPtr<MultiplexASTMutationListener> MutationListener;
+  llvm::OwningPtr<MultiplexASTDeserializationListener> DeserializationListener;
+};
+
+}  // end namespace clang

Modified: cfe/trunk/lib/CodeGen/CodeGenAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=124227&r1=124226&r2=124227&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenAction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenAction.cpp Tue Jan 25 14:34:14 2011
@@ -28,7 +28,7 @@
 using namespace clang;
 using namespace llvm;
 
-namespace {
+namespace clang {
   class BackendConsumer : public ASTConsumer {
     Diagnostic &Diags;
     BackendAction Action;
@@ -236,10 +236,7 @@
     return;
 
   // Steal the module from the consumer.
-  BackendConsumer *Consumer = static_cast<BackendConsumer*>(
-    &getCompilerInstance().getASTConsumer());
-
-  TheModule.reset(Consumer->takeModule());
+  TheModule.reset(BEConsumer->takeModule());
 }
 
 llvm::Module *CodeGenAction::takeModule() {
@@ -274,10 +271,12 @@
   if (BA != Backend_EmitNothing && !OS)
     return 0;
 
-  return new BackendConsumer(BA, CI.getDiagnostics(),
-                             CI.getCodeGenOpts(), CI.getTargetOpts(),
-                             CI.getFrontendOpts().ShowTimers, InFile, OS.take(),
-                             CI.getLLVMContext());
+  BEConsumer = 
+      new BackendConsumer(BA, CI.getDiagnostics(),
+                          CI.getCodeGenOpts(), CI.getTargetOpts(),
+                          CI.getFrontendOpts().ShowTimers, InFile, OS.take(),
+                          CI.getLLVMContext());
+  return BEConsumer;
 }
 
 void CodeGenAction::ExecuteAction() {

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=124227&r1=124226&r2=124227&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Tue Jan 25 14:34:14 2011
@@ -433,6 +433,10 @@
     Res.push_back("-load");
     Res.push_back(Opts.Plugins[i]);
   }
+  for (unsigned i = 0, e = Opts.AddPluginActions.size(); i != e; ++i) {
+    Res.push_back("-add-plugin");
+    Res.push_back(Opts.AddPluginActions[i]);
+  }
   for (unsigned i = 0, e = Opts.ASTMergeFiles.size(); i != e; ++i) {
     Res.push_back("-ast-merge");
     Res.push_back(Opts.ASTMergeFiles[i]);
@@ -1098,6 +1102,8 @@
     }
   }
 
+  Opts.AddPluginActions = Args.getAllArgValues(OPT_add_plugin);
+
   if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
     Opts.CodeCompletionAt =
       ParsedSourceLocation::FromString(A->getValue(Args));

Modified: cfe/trunk/lib/Frontend/FrontendAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=124227&r1=124226&r2=124227&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendAction.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendAction.cpp Tue Jan 25 14:34:14 2011
@@ -10,11 +10,14 @@
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclGroup.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/FrontendPluginRegistry.h"
+#include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Parse/ParseAST.h"
 #include "clang/Serialization/ASTDeserializationListener.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -85,6 +88,39 @@
   CurrentASTUnit.reset(AST);
 }
 
+ASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
+                                                      llvm::StringRef InFile) {
+  ASTConsumer* Consumer = CreateASTConsumer(CI, InFile);
+  if (!Consumer)
+    return 0;
+
+  if (CI.getFrontendOpts().AddPluginActions.size() == 0)
+    return Consumer;
+
+  // Make sure the non-plugin consumer is first, so that plugins can't
+  // modifiy the AST.
+  std::vector<ASTConsumer*> Consumers(1, Consumer);
+
+  for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size();
+       i != e; ++i) { 
+    // This is O(|plugins| * |add_plugins|), but since both numbers are
+    // way below 50 in practice, that's ok.
+    for (FrontendPluginRegistry::iterator
+        it = FrontendPluginRegistry::begin(),
+        ie = FrontendPluginRegistry::end();
+        it != ie; ++it) {
+      if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) {
+        llvm::OwningPtr<PluginASTAction> P(it->instantiate());
+        FrontendAction* c = P.get();
+        if (P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs))
+          Consumers.push_back(c->CreateASTConsumer(CI, InFile));
+      }
+    }
+  }
+
+  return new MultiplexConsumer(Consumers);
+}
+
 bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                      llvm::StringRef Filename,
                                      InputKind InputKind) {
@@ -122,7 +158,7 @@
       goto failure;
 
     /// Create the AST consumer.
-    CI.setASTConsumer(CreateASTConsumer(CI, Filename));
+    CI.setASTConsumer(CreateWrappedASTConsumer(CI, Filename));
     if (!CI.hasASTConsumer())
       goto failure;
 
@@ -166,7 +202,8 @@
   if (!usesPreprocessorOnly()) {
     CI.createASTContext();
 
-    llvm::OwningPtr<ASTConsumer> Consumer(CreateASTConsumer(CI, Filename));
+    llvm::OwningPtr<ASTConsumer> Consumer(
+        CreateWrappedASTConsumer(CI, Filename));
     if (!Consumer)
       goto failure;
 

Added: cfe/trunk/lib/Frontend/MultiplexConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/MultiplexConsumer.cpp?rev=124227&view=auto
==============================================================================
--- cfe/trunk/lib/Frontend/MultiplexConsumer.cpp (added)
+++ cfe/trunk/lib/Frontend/MultiplexConsumer.cpp Tue Jan 25 14:34:14 2011
@@ -0,0 +1,221 @@
+//===- MultiplexConsumer.cpp - AST Consumer for PCH Generation --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the MultiplexConsumer class. It also declares and defines
+//  MultiplexASTDeserializationListener and  MultiplexASTMutationListener, which
+//  are implementation details of MultiplexConsumer.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/MultiplexConsumer.h"
+
+#include "clang/AST/ASTMutationListener.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/Serialization/ASTDeserializationListener.h"
+
+using namespace clang;
+
+namespace clang {
+
+// This ASTDeserializationListener forwards its notifications to a set of
+// child listeners.
+class MultiplexASTDeserializationListener
+    : public ASTDeserializationListener {
+public:
+  // Does NOT take ownership of the elements in L.
+  MultiplexASTDeserializationListener(
+      const std::vector<ASTDeserializationListener*>& L);
+  virtual void ReaderInitialized(ASTReader *Reader);
+  virtual void IdentifierRead(serialization::IdentID ID,
+                              IdentifierInfo *II);
+  virtual void TypeRead(serialization::TypeIdx Idx, QualType T);
+  virtual void DeclRead(serialization::DeclID ID, const Decl *D);
+  virtual void SelectorRead(serialization::SelectorID iD, Selector Sel);
+  virtual void MacroDefinitionRead(serialization::MacroID, 
+                                   MacroDefinition *MD);
+private:
+  std::vector<ASTDeserializationListener*> Listeners;
+};
+
+MultiplexASTDeserializationListener::MultiplexASTDeserializationListener(
+      const std::vector<ASTDeserializationListener*>& L)
+    : Listeners(L) {
+}
+
+void MultiplexASTDeserializationListener::ReaderInitialized(
+    ASTReader *Reader) {
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+    Listeners[i]->ReaderInitialized(Reader);
+}
+
+void MultiplexASTDeserializationListener::IdentifierRead(
+    serialization::IdentID ID, IdentifierInfo *II) {
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+    Listeners[i]->IdentifierRead(ID, II);
+}
+
+void MultiplexASTDeserializationListener::TypeRead(
+    serialization::TypeIdx Idx, QualType T) {
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+    Listeners[i]->TypeRead(Idx, T);
+}
+
+void MultiplexASTDeserializationListener::DeclRead(
+    serialization::DeclID ID, const Decl *D) {
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+    Listeners[i]->DeclRead(ID, D);
+}
+
+void MultiplexASTDeserializationListener::SelectorRead(
+    serialization::SelectorID ID, Selector Sel) {
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+    Listeners[i]->SelectorRead(ID, Sel);
+}
+
+void MultiplexASTDeserializationListener::MacroDefinitionRead(
+    serialization::MacroID ID, MacroDefinition *MD) {
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+    Listeners[i]->MacroDefinitionRead(ID, MD);
+}
+
+// This ASTMutationListener forwards its notifications to a set of
+// child listeners.
+class MultiplexASTMutationListener : public ASTMutationListener {
+public:
+  // Does NOT take ownership of the elements in L.
+  MultiplexASTMutationListener(const std::vector<ASTMutationListener*>& L);
+  virtual void CompletedTagDefinition(const TagDecl *D);
+  virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D);
+  virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D);
+  virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
+                                    const ClassTemplateSpecializationDecl *D);
+private:
+  std::vector<ASTMutationListener*> Listeners;
+};
+
+MultiplexASTMutationListener::MultiplexASTMutationListener(
+    const std::vector<ASTMutationListener*>& L)
+    : Listeners(L) {
+}
+
+void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) {
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+    Listeners[i]->CompletedTagDefinition(D);
+}
+
+void MultiplexASTMutationListener::AddedVisibleDecl(
+    const DeclContext *DC, const Decl *D) {
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+    Listeners[i]->AddedVisibleDecl(DC, D);
+}
+
+void MultiplexASTMutationListener::AddedCXXImplicitMember(
+    const CXXRecordDecl *RD, const Decl *D) {
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+    Listeners[i]->AddedCXXImplicitMember(RD, D);
+}
+void MultiplexASTMutationListener::AddedCXXTemplateSpecialization(
+    const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) {
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+    Listeners[i]->AddedCXXTemplateSpecialization(TD, D);
+}
+
+}  // end namespace clang
+
+
+MultiplexConsumer::MultiplexConsumer(const std::vector<ASTConsumer*>& C)
+    : Consumers(C), MutationListener(0), DeserializationListener(0) {
+  // Collect the mutation listeners and deserialization listeners of all
+  // children, and create a multiplex listener each if so.
+  std::vector<ASTMutationListener*> mutationListeners;
+  std::vector<ASTDeserializationListener*> serializationListeners;
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i) {
+    ASTMutationListener* mutationListener =
+        Consumers[i]->GetASTMutationListener();
+    if (mutationListener)
+      mutationListeners.push_back(mutationListener);
+    ASTDeserializationListener* serializationListener =
+        Consumers[i]->GetASTDeserializationListener();
+    if (serializationListener)
+      serializationListeners.push_back(serializationListener);
+  }
+  if (mutationListeners.size()) {
+    MutationListener.reset(new MultiplexASTMutationListener(mutationListeners));
+  }
+  if (serializationListeners.size()) {
+    DeserializationListener.reset(
+        new MultiplexASTDeserializationListener(serializationListeners));
+  }
+}
+
+MultiplexConsumer::~MultiplexConsumer() {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    delete Consumers[i];
+}
+
+void MultiplexConsumer::Initialize(ASTContext &Context) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->Initialize(Context);
+}
+
+void MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleTopLevelDecl(D);
+}
+
+void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleInterestingDecl(D);
+}
+
+void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleTranslationUnit(Ctx);
+}
+
+void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleTagDeclDefinition(D);
+}
+
+void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->CompleteTentativeDefinition(D);
+}
+
+void MultiplexConsumer::HandleVTable(
+    CXXRecordDecl *RD, bool DefinitionRequired) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleVTable(RD, DefinitionRequired);
+}
+
+ASTMutationListener *MultiplexConsumer::GetASTMutationListener() {
+  return MutationListener.get();
+}
+
+ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() {
+  return DeserializationListener.get();
+}
+
+void MultiplexConsumer::PrintStats() {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->PrintStats();
+}
+
+void MultiplexConsumer::InitializeSema(Sema &S) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i]))
+      SC->InitializeSema(S);
+}
+
+void MultiplexConsumer::ForgetSema() {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i]))
+      SC->ForgetSema();
+}





More information about the cfe-commits mailing list