diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td
--- a/llvm/include/llvm/Frontend/OpenACC/ACC.td
+++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td
@@ -23,7 +23,6 @@
   let clausePrefix = "ACCC_";
   let makeEnumAvailableInNamespace = true;
   let enableBitmaskEnumInNamespace = true;
-  let includeHeader = "llvm/Frontend/OpenACC/ACC.h.inc";
   let clauseEnumSetClass = "AccClauseSet";
   let flangClauseBaseClass = "AccClause";
 }
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -23,7 +23,6 @@
   let clausePrefix = "OMPC_";
   let makeEnumAvailableInNamespace = true;
   let enableBitmaskEnumInNamespace = true;
-  let includeHeader = "llvm/Frontend/OpenMP/OMP.h.inc";
   let clauseEnumSetClass = "OmpClauseSet";
   let flangClauseBaseClass = "OmpClause";
 }
diff --git a/llvm/include/llvm/TableGen/DirectiveEmitter.h b/llvm/include/llvm/TableGen/DirectiveEmitter.h
--- a/llvm/include/llvm/TableGen/DirectiveEmitter.h
+++ b/llvm/include/llvm/TableGen/DirectiveEmitter.h
@@ -30,10 +30,6 @@
     return Def->getValueAsString("clausePrefix");
   }
 
-  StringRef getIncludeHeader() const {
-    return Def->getValueAsString("includeHeader");
-  }
-
   StringRef getClauseEnumSetClass() const {
     return Def->getValueAsString("clauseEnumSetClass");
   }
diff --git a/llvm/lib/Frontend/OpenACC/ACC.cpp b/llvm/lib/Frontend/OpenACC/ACC.cpp
new file mode 100644
--- /dev/null
+++ b/llvm/lib/Frontend/OpenACC/ACC.cpp
@@ -0,0 +1,19 @@
+//===- ACC.cpp ------ Collection of helpers for OpenACC -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Frontend/OpenACC/ACC.h.inc"
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+using namespace acc;
+
+#define GEN_DIRECTIVES_IMPL
+#include "llvm/Frontend/OpenACC/ACC.inc"
diff --git a/llvm/lib/Frontend/OpenACC/CMakeLists.txt b/llvm/lib/Frontend/OpenACC/CMakeLists.txt
--- a/llvm/lib/Frontend/OpenACC/CMakeLists.txt
+++ b/llvm/lib/Frontend/OpenACC/CMakeLists.txt
@@ -1,9 +1,5 @@
-set(LLVM_TARGET_DEFINITIONS ${LLVM_MAIN_INCLUDE_DIR}/llvm/Frontend/OpenACC/ACC.td)
-tablegen(LLVM ACC.cpp --gen-directive-impl)
-add_public_tablegen_target(acc_cpp)
-
 add_llvm_component_library(LLVMFrontendOpenACC
-  ACC.cpp # Generated by tablegen above
+  ACC.cpp
 
   ADDITIONAL_HEADER_DIRS
   ${LLVM_MAIN_INCLUDE_DIR}/llvm/Frontend
@@ -11,7 +7,6 @@
 
   DEPENDS
   acc_gen
-  acc_cpp
 )
 
 target_link_libraries(LLVMFrontendOpenACC LLVMSupport)
diff --git a/llvm/lib/Frontend/OpenMP/CMakeLists.txt b/llvm/lib/Frontend/OpenMP/CMakeLists.txt
--- a/llvm/lib/Frontend/OpenMP/CMakeLists.txt
+++ b/llvm/lib/Frontend/OpenMP/CMakeLists.txt
@@ -1,9 +1,5 @@
-set(LLVM_TARGET_DEFINITIONS ${LLVM_MAIN_INCLUDE_DIR}/llvm/Frontend/OpenMP/OMP.td)
-tablegen(LLVM OMP.cpp --gen-directive-impl)
-add_public_tablegen_target(omp_cpp)
-
 add_llvm_component_library(LLVMFrontendOpenMP
-  OMP.cpp # Generated by tablegen above
+  OMP.cpp
   OMPContext.cpp
   OMPIRBuilder.cpp
 
@@ -14,7 +10,6 @@
   DEPENDS
   intrinsics_gen
   omp_gen
-  omp_cpp
 
   LINK_COMPONENTS
   Core
diff --git a/llvm/lib/Frontend/OpenMP/OMP.cpp b/llvm/lib/Frontend/OpenMP/OMP.cpp
new file mode 100644
--- /dev/null
+++ b/llvm/lib/Frontend/OpenMP/OMP.cpp
@@ -0,0 +1,19 @@
+//===- OMP.cpp ------ Collection of helpers for OpenMP --------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Frontend/OpenMP/OMP.h.inc"
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+using namespace omp;
+
+#define GEN_DIRECTIVES_IMPL
+#include "llvm/Frontend/OpenMP/OMP.inc"
diff --git a/llvm/test/TableGen/directive1.td b/llvm/test/TableGen/directive1.td
--- a/llvm/test/TableGen/directive1.td
+++ b/llvm/test/TableGen/directive1.td
@@ -1,5 +1,4 @@
 // RUN: llvm-tblgen -gen-directive-decl -I %p/../../include %s | FileCheck -match-full-lines %s
-// RUN: llvm-tblgen -gen-directive-impl -I %p/../../include %s | FileCheck -match-full-lines %s -check-prefix=IMPL
 // RUN: llvm-tblgen -gen-directive-gen -I %p/../../include %s | FileCheck -match-full-lines %s -check-prefix=GEN
 
 include "llvm/Frontend/Directive/DirectiveBase.td"
@@ -101,73 +100,6 @@
 // CHECK-NEXT:  #endif // LLVM_Tdl_INC
 
 
-// IMPL:       #include "llvm/ADT/StringRef.h"
-// IMPL-NEXT:  #include "llvm/ADT/StringSwitch.h"
-// IMPL-NEXT:  #include "llvm/Support/ErrorHandling.h"
-// IMPL-EMPTY:
-// IMPL-NEXT:  using namespace llvm;
-// IMPL-NEXT:  using namespace tdl;
-// IMPL-EMPTY:
-// IMPL-NEXT:  Directive llvm::tdl::getTdlDirectiveKind(llvm::StringRef Str) {
-// IMPL-NEXT:    return llvm::StringSwitch<Directive>(Str)
-// IMPL-NEXT:      .Case("dira",TDLD_dira)
-// IMPL-NEXT:      .Default(TDLD_dira);
-// IMPL-NEXT:  }
-// IMPL-EMPTY:
-// IMPL-NEXT:  llvm::StringRef llvm::tdl::getTdlDirectiveName(Directive Kind) {
-// IMPL-NEXT:    switch (Kind) {
-// IMPL-NEXT:      case TDLD_dira:
-// IMPL-NEXT:        return "dira";
-// IMPL-NEXT:    }
-// IMPL-NEXT:    llvm_unreachable("Invalid Tdl Directive kind");
-// IMPL-NEXT:  }
-// IMPL-EMPTY:
-// IMPL-NEXT:  Clause llvm::tdl::getTdlClauseKind(llvm::StringRef Str) {
-// IMPL-NEXT:    return llvm::StringSwitch<Clause>(Str)
-// IMPL-NEXT:      .Case("clausea",TDLC_clausea)
-// IMPL-NEXT:      .Case("clauseb",TDLC_clauseb)
-// IMPL-NEXT:      .Default(TDLC_clauseb);
-// IMPL-NEXT:  }
-// IMPL-EMPTY:
-// IMPL-NEXT:  llvm::StringRef llvm::tdl::getTdlClauseName(Clause Kind) {
-// IMPL-NEXT:    switch (Kind) {
-// IMPL-NEXT:      case TDLC_clausea:
-// IMPL-NEXT:        return "clausea";
-// IMPL-NEXT:      case TDLC_clauseb:
-// IMPL-NEXT:        return "clauseb";
-// IMPL-NEXT:    }
-// IMPL-NEXT:    llvm_unreachable("Invalid Tdl Clause kind");
-// IMPL-NEXT:  }
-// IMPL-EMPTY:
-// IMPL-NEXT:  AKind llvm::tdl::getAKind(llvm::StringRef Str) {
-// IMPL-NEXT:    return llvm::StringSwitch<AKind>(Str)
-// IMPL-NEXT:      .Case("vala",TDLCV_vala)
-// IMPL-NEXT:      .Case("valb",TDLCV_valb)
-// IMPL-NEXT:      .Case("valc",TDLCV_valc)
-// IMPL-NEXT:      .Default(TDLCV_valc);
-// IMPL-NEXT:  }
-// IMPL-EMPTY:
-// IMPL-NEXT:  bool llvm::tdl::isAllowedClauseForDirective(Directive D, Clause C, unsigned Version) {
-// IMPL-NEXT:    assert(unsigned(D) <= llvm::tdl::Directive_enumSize);
-// IMPL-NEXT:    assert(unsigned(C) <= llvm::tdl::Clause_enumSize);
-// IMPL-NEXT:    switch (D) {
-// IMPL-NEXT:      case TDLD_dira:
-// IMPL-NEXT:        switch (C) {
-// IMPL-NEXT:          case TDLC_clausea:
-// IMPL-NEXT:            return 1 <= Version && 2147483647 >= Version;
-// IMPL-NEXT:          case TDLC_clauseb:
-// IMPL-NEXT:            return 1 <= Version && 2147483647 >= Version;
-// IMPL-NEXT:          default:
-// IMPL-NEXT:            return false;
-// IMPL-NEXT:        }
-// IMPL-NEXT:        break;
-// IMPL-NEXT:    }
-// IMPL-NEXT:    llvm_unreachable("Invalid Tdl Directive kind");
-// IMPL-NEXT:  }
-// IMPL-EMPTY:
-
-
-
 // GEN:       #ifdef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
 // GEN-NEXT:  #undef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
 // GEN-EMPTY:
@@ -241,3 +173,65 @@
 // GEN-NEXT:  }
 // GEN-EMPTY:
 // GEN-NEXT:  #endif // GEN_FLANG_CLAUSE_UNPARSE
+
+// GEN:       #ifdef GEN_DIRECTIVES_IMPL
+// GEN-NEXT:  #undef GEN_DIRECTIVES_IMPL
+// GEN-EMPTY:
+// GEN-NEXT:  Directive llvm::tdl::getTdlDirectiveKind(llvm::StringRef Str) {
+// GEN-NEXT:    return llvm::StringSwitch<Directive>(Str)
+// GEN-NEXT:      .Case("dira",TDLD_dira)
+// GEN-NEXT:      .Default(TDLD_dira);
+// GEN-NEXT:  }
+// GEN-EMPTY:
+// GEN-NEXT:  llvm::StringRef llvm::tdl::getTdlDirectiveName(Directive Kind) {
+// GEN-NEXT:    switch (Kind) {
+// GEN-NEXT:      case TDLD_dira:
+// GEN-NEXT:        return "dira";
+// GEN-NEXT:    }
+// GEN-NEXT:    llvm_unreachable("Invalid Tdl Directive kind");
+// GEN-NEXT:  }
+// GEN-EMPTY:
+// GEN-NEXT:  Clause llvm::tdl::getTdlClauseKind(llvm::StringRef Str) {
+// GEN-NEXT:    return llvm::StringSwitch<Clause>(Str)
+// GEN-NEXT:      .Case("clausea",TDLC_clausea)
+// GEN-NEXT:      .Case("clauseb",TDLC_clauseb)
+// GEN-NEXT:      .Default(TDLC_clauseb);
+// GEN-NEXT:  }
+// GEN-EMPTY:
+// GEN-NEXT:  llvm::StringRef llvm::tdl::getTdlClauseName(Clause Kind) {
+// GEN-NEXT:    switch (Kind) {
+// GEN-NEXT:      case TDLC_clausea:
+// GEN-NEXT:        return "clausea";
+// GEN-NEXT:      case TDLC_clauseb:
+// GEN-NEXT:        return "clauseb";
+// GEN-NEXT:    }
+// GEN-NEXT:    llvm_unreachable("Invalid Tdl Clause kind");
+// GEN-NEXT:  }
+// GEN-EMPTY:
+// GEN-NEXT:  AKind llvm::tdl::getAKind(llvm::StringRef Str) {
+// GEN-NEXT:    return llvm::StringSwitch<AKind>(Str)
+// GEN-NEXT:      .Case("vala",TDLCV_vala)
+// GEN-NEXT:      .Case("valb",TDLCV_valb)
+// GEN-NEXT:      .Case("valc",TDLCV_valc)
+// GEN-NEXT:      .Default(TDLCV_valc);
+// GEN-NEXT:  }
+// GEN-EMPTY:
+// GEN-NEXT:  bool llvm::tdl::isAllowedClauseForDirective(Directive D, Clause C, unsigned Version) {
+// GEN-NEXT:    assert(unsigned(D) <= llvm::tdl::Directive_enumSize);
+// GEN-NEXT:    assert(unsigned(C) <= llvm::tdl::Clause_enumSize);
+// GEN-NEXT:    switch (D) {
+// GEN-NEXT:      case TDLD_dira:
+// GEN-NEXT:        switch (C) {
+// GEN-NEXT:          case TDLC_clausea:
+// GEN-NEXT:            return 1 <= Version && 2147483647 >= Version;
+// GEN-NEXT:          case TDLC_clauseb:
+// GEN-NEXT:            return 1 <= Version && 2147483647 >= Version;
+// GEN-NEXT:          default:
+// GEN-NEXT:            return false;
+// GEN-NEXT:        }
+// GEN-NEXT:        break;
+// GEN-NEXT:    }
+// GEN-NEXT:    llvm_unreachable("Invalid Tdl Directive kind");
+// GEN-NEXT:  }
+// GEN-EMPTY:
+// GEN-NEXT:  #endif // GEN_DIRECTIVES_IMPL
\ No newline at end of file
diff --git a/llvm/test/TableGen/directive2.td b/llvm/test/TableGen/directive2.td
--- a/llvm/test/TableGen/directive2.td
+++ b/llvm/test/TableGen/directive2.td
@@ -1,5 +1,4 @@
 // RUN: llvm-tblgen -gen-directive-decl -I %p/../../include %s | FileCheck -match-full-lines %s
-// RUN: llvm-tblgen -gen-directive-impl -I %p/../../include %s | FileCheck -match-full-lines %s -check-prefix=IMPL
 // RUN: llvm-tblgen -gen-directive-gen -I %p/../../include %s | FileCheck -match-full-lines %s -check-prefix=GEN
 
 include "llvm/Frontend/Directive/DirectiveBase.td"
@@ -79,71 +78,6 @@
 // CHECK-NEXT:  } // namespace llvm
 // CHECK-NEXT:  #endif // LLVM_Tdl_INC
 
-// IMPL:       #include "tdl.h.inc"
-// IMPL-EMPTY:
-// IMPL-NEXT:  #include "llvm/ADT/StringRef.h"
-// IMPL-NEXT:  #include "llvm/ADT/StringSwitch.h"
-// IMPL-NEXT:  #include "llvm/Support/ErrorHandling.h"
-// IMPL-EMPTY:
-// IMPL-NEXT:  using namespace llvm;
-// IMPL-NEXT:  using namespace tdl;
-// IMPL-EMPTY:
-// IMPL-NEXT:  Directive llvm::tdl::getTdlDirectiveKind(llvm::StringRef Str) {
-// IMPL-NEXT:    return llvm::StringSwitch<Directive>(Str)
-// IMPL-NEXT:      .Case("dira",TDLD_dira)
-// IMPL-NEXT:      .Default(TDLD_dira);
-// IMPL-NEXT:  }
-// IMPL-EMPTY:
-// IMPL-NEXT:  llvm::StringRef llvm::tdl::getTdlDirectiveName(Directive Kind) {
-// IMPL-NEXT:    switch (Kind) {
-// IMPL-NEXT:      case TDLD_dira:
-// IMPL-NEXT:        return "dira";
-// IMPL-NEXT:    }
-// IMPL-NEXT:    llvm_unreachable("Invalid Tdl Directive kind");
-// IMPL-NEXT:  }
-// IMPL-EMPTY:
-// IMPL-NEXT:  Clause llvm::tdl::getTdlClauseKind(llvm::StringRef Str) {
-// IMPL-NEXT:    return llvm::StringSwitch<Clause>(Str)
-// IMPL-NEXT:      .Case("clausea",TDLC_clauseb)
-// IMPL-NEXT:      .Case("clauseb",TDLC_clauseb)
-// IMPL-NEXT:      .Case("clausec",TDLC_clausec)
-// IMPL-NEXT:      .Case("claused",TDLC_clauseb)
-// IMPL-NEXT:      .Default(TDLC_clauseb);
-// IMPL-NEXT:  }
-// IMPL-EMPTY:
-// IMPL-NEXT:  llvm::StringRef llvm::tdl::getTdlClauseName(Clause Kind) {
-// IMPL-NEXT:    switch (Kind) {
-// IMPL-NEXT:      case TDLC_clausea:
-// IMPL-NEXT:        return "clausea";
-// IMPL-NEXT:      case TDLC_clauseb:
-// IMPL-NEXT:        return "clauseb";
-// IMPL-NEXT:      case TDLC_clausec:
-// IMPL-NEXT:        return "clausec";
-// IMPL-NEXT:      case TDLC_claused:
-// IMPL-NEXT:        return "claused";
-// IMPL-NEXT:    }
-// IMPL-NEXT:    llvm_unreachable("Invalid Tdl Clause kind");
-// IMPL-NEXT:  }
-// IMPL-EMPTY:
-// IMPL-NEXT:  bool llvm::tdl::isAllowedClauseForDirective(Directive D, Clause C, unsigned Version) {
-// IMPL-NEXT:    assert(unsigned(D) <= llvm::tdl::Directive_enumSize);
-// IMPL-NEXT:    assert(unsigned(C) <= llvm::tdl::Clause_enumSize);
-// IMPL-NEXT:    switch (D) {
-// IMPL-NEXT:      case TDLD_dira:
-// IMPL-NEXT:        switch (C) {
-// IMPL-NEXT:          case TDLC_clausea:
-// IMPL-NEXT:            return 2 <= Version && 4 >= Version;
-// IMPL-NEXT:          case TDLC_clauseb:
-// IMPL-NEXT:            return 2 <= Version && 2147483647 >= Version;
-// IMPL-NEXT:          default:
-// IMPL-NEXT:            return false;
-// IMPL-NEXT:        }
-// IMPL-NEXT:        break;
-// IMPL-NEXT:    }
-// IMPL-NEXT:    llvm_unreachable("Invalid Tdl Directive kind");
-// IMPL-NEXT:  }
-
-
 // GEN:      #ifdef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
 // GEN-NEXT: #undef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
 // GEN-EMPTY:
@@ -279,3 +213,63 @@
 // GEN-EMPTY:
 // GEN-NEXT:  #endif // GEN_CLANG_CLAUSE_CLASS
 
+
+// GEN:       #ifdef GEN_DIRECTIVES_IMPL
+// GEN-NEXT:  #undef GEN_DIRECTIVES_IMPL
+// GEN-EMPTY:
+// GEN-NEXT:  Directive llvm::tdl::getTdlDirectiveKind(llvm::StringRef Str) {
+// GEN-NEXT:    return llvm::StringSwitch<Directive>(Str)
+// GEN-NEXT:      .Case("dira",TDLD_dira)
+// GEN-NEXT:      .Default(TDLD_dira);
+// GEN-NEXT:  }
+// GEN-EMPTY:
+// GEN-NEXT:  llvm::StringRef llvm::tdl::getTdlDirectiveName(Directive Kind) {
+// GEN-NEXT:    switch (Kind) {
+// GEN-NEXT:      case TDLD_dira:
+// GEN-NEXT:        return "dira";
+// GEN-NEXT:    }
+// GEN-NEXT:    llvm_unreachable("Invalid Tdl Directive kind");
+// GEN-NEXT:  }
+// GEN-EMPTY:
+// GEN-NEXT:  Clause llvm::tdl::getTdlClauseKind(llvm::StringRef Str) {
+// GEN-NEXT:    return llvm::StringSwitch<Clause>(Str)
+// GEN-NEXT:      .Case("clausea",TDLC_clauseb)
+// GEN-NEXT:      .Case("clauseb",TDLC_clauseb)
+// GEN-NEXT:      .Case("clausec",TDLC_clausec)
+// GEN-NEXT:      .Case("claused",TDLC_clauseb)
+// GEN-NEXT:      .Default(TDLC_clauseb);
+// GEN-NEXT:  }
+// GEN-EMPTY:
+// GEN-NEXT:  llvm::StringRef llvm::tdl::getTdlClauseName(Clause Kind) {
+// GEN-NEXT:    switch (Kind) {
+// GEN-NEXT:      case TDLC_clausea:
+// GEN-NEXT:        return "clausea";
+// GEN-NEXT:      case TDLC_clauseb:
+// GEN-NEXT:        return "clauseb";
+// GEN-NEXT:      case TDLC_clausec:
+// GEN-NEXT:        return "clausec";
+// GEN-NEXT:      case TDLC_claused:
+// GEN-NEXT:        return "claused";
+// GEN-NEXT:    }
+// GEN-NEXT:    llvm_unreachable("Invalid Tdl Clause kind");
+// GEN-NEXT:  }
+// GEN-EMPTY:
+// GEN-NEXT:  bool llvm::tdl::isAllowedClauseForDirective(Directive D, Clause C, unsigned Version) {
+// GEN-NEXT:    assert(unsigned(D) <= llvm::tdl::Directive_enumSize);
+// GEN-NEXT:    assert(unsigned(C) <= llvm::tdl::Clause_enumSize);
+// GEN-NEXT:    switch (D) {
+// GEN-NEXT:      case TDLD_dira:
+// GEN-NEXT:        switch (C) {
+// GEN-NEXT:          case TDLC_clausea:
+// GEN-NEXT:            return 2 <= Version && 4 >= Version;
+// GEN-NEXT:          case TDLC_clauseb:
+// GEN-NEXT:            return 2 <= Version && 2147483647 >= Version;
+// GEN-NEXT:          default:
+// GEN-NEXT:            return false;
+// GEN-NEXT:        }
+// GEN-NEXT:        break;
+// GEN-NEXT:    }
+// GEN-NEXT:    llvm_unreachable("Invalid Tdl Directive kind");
+// GEN-NEXT:  }
+// GEN-EMPTY:
+// GEN-NEXT:  #endif // GEN_DIRECTIVES_IMPL
diff --git a/llvm/test/TableGen/directive3.td b/llvm/test/TableGen/directive3.td
--- a/llvm/test/TableGen/directive3.td
+++ b/llvm/test/TableGen/directive3.td
@@ -1,5 +1,4 @@
 // RUN: not llvm-tblgen -gen-directive-decl -I %p/../../include %s 2>&1 | FileCheck -match-full-lines %s
-// RUN: not llvm-tblgen -gen-directive-impl -I %p/../../include %s 2>&1 | FileCheck -match-full-lines %s
 // RUN: not llvm-tblgen -gen-directive-gen -I %p/../../include %s 2>&1 | FileCheck -match-full-lines %s
 
 include "llvm/Frontend/Directive/DirectiveBase.td"
diff --git a/llvm/utils/TableGen/DirectiveEmitter.cpp b/llvm/utils/TableGen/DirectiveEmitter.cpp
--- a/llvm/utils/TableGen/DirectiveEmitter.cpp
+++ b/llvm/utils/TableGen/DirectiveEmitter.cpp
@@ -711,37 +711,12 @@
   OS << "#undef CLAUSE\n";
 }
 
-// Generate the implemenation section for the enumeration in the directive
-// language.
-void EmitDirectivesGen(RecordKeeper &Records, raw_ostream &OS) {
-  const auto DirLang = DirectiveLanguage{Records};
-  if (DirLang.HasValidityErrors())
-    return;
-
-  EmitDirectivesFlangImpl(DirLang, OS);
-
-  GenerateClauseClassMacro(DirLang, OS);
-}
-
 // Generate the implemenation for the enumeration in the directive
 // language. This code can be included in library.
-void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) {
-  const auto DirLang = DirectiveLanguage{Records};
-  if (DirLang.HasValidityErrors())
-    return;
-
-  if (!DirLang.getIncludeHeader().empty())
-    OS << "#include \"" << DirLang.getIncludeHeader() << "\"\n\n";
+void EmitDirectivesImpl(const DirectiveLanguage &DirLang, raw_ostream &OS) {
+  IfDefScope Scope("GEN_DIRECTIVES_IMPL", OS);
 
-  OS << "#include \"llvm/ADT/StringRef.h\"\n";
-  OS << "#include \"llvm/ADT/StringSwitch.h\"\n";
-  OS << "#include \"llvm/Support/ErrorHandling.h\"\n";
   OS << "\n";
-  OS << "using namespace llvm;\n";
-  llvm::SmallVector<StringRef, 2> Namespaces;
-  llvm::SplitString(DirLang.getCppNamespace(), Namespaces, "::");
-  for (auto Ns : Namespaces)
-    OS << "using namespace " << Ns << ";\n";
 
   // getDirectiveKind(StringRef Str)
   GenerateGetKind(DirLang.getDirectives(), OS, "Directive", DirLang,
@@ -767,4 +742,18 @@
   GenerateIsAllowedClause(DirLang, OS);
 }
 
+// Generate the implemenation section for the enumeration in the directive
+// language.
+void EmitDirectivesGen(RecordKeeper &Records, raw_ostream &OS) {
+  const auto DirLang = DirectiveLanguage{Records};
+  if (DirLang.HasValidityErrors())
+    return;
+
+  EmitDirectivesFlangImpl(DirLang, OS);
+
+  GenerateClauseClassMacro(DirLang, OS);
+
+  EmitDirectivesImpl(DirLang, OS);
+}
+
 } // namespace llvm
diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp
--- a/llvm/utils/TableGen/TableGen.cpp
+++ b/llvm/utils/TableGen/TableGen.cpp
@@ -55,7 +55,6 @@
   GenExegesis,
   GenAutomata,
   GenDirectivesEnumDecl,
-  GenDirectivesEnumImpl,
   GenDirectivesEnumGen,
 };
 
@@ -135,8 +134,6 @@
         clEnumValN(GenAutomata, "gen-automata", "Generate generic automata"),
         clEnumValN(GenDirectivesEnumDecl, "gen-directive-decl",
                    "Generate directive related declaration code (header file)"),
-        clEnumValN(GenDirectivesEnumImpl, "gen-directive-impl",
-                   "Generate directive related implementation code"),
         clEnumValN(GenDirectivesEnumGen, "gen-directive-gen",
                    "Generate directive related implementation code part")));
 
@@ -266,9 +263,6 @@
   case GenDirectivesEnumDecl:
     EmitDirectivesDecl(Records, OS);
     break;
-  case GenDirectivesEnumImpl:
-    EmitDirectivesImpl(Records, OS);
-    break;
   case GenDirectivesEnumGen:
     EmitDirectivesGen(Records, OS);
     break;