Skip to content

Conversation

@jurahul
Copy link
Contributor

@jurahul jurahul commented Oct 13, 2025

Add a RAII class IncludeGuardEmitter which is similar to IfDefEmitter but emits header include guards and adopt it in DirectiveEmitter.

…guards

Add a RAII  class `InclusionGuardEmitter` which is similar to
`IfDefEmitter` but emits header inclusion guards, and adopt it it
DirectiveEmitter.
@jurahul jurahul marked this pull request as ready for review October 14, 2025 01:25
@jurahul jurahul requested review from joker-eph and kparzysz October 14, 2025 01:25
@llvmbot
Copy link
Member

llvmbot commented Oct 14, 2025

@llvm/pr-subscribers-tablegen

Author: Rahul Joshi (jurahul)

Changes

Add a RAII class InclusionGuardEmitter which is similar to IfDefEmitter but emits header inclusion guards and adopt it in DirectiveEmitter.


Full diff: https://github.com/llvm/llvm-project/pull/163283.diff

4 Files Affected:

  • (modified) llvm/include/llvm/TableGen/CodeGenHelpers.h (+16)
  • (modified) llvm/test/TableGen/directive1.td (+1)
  • (modified) llvm/test/TableGen/directive2.td (+1)
  • (modified) llvm/utils/TableGen/Basic/DirectiveEmitter.cpp (+2-4)
diff --git a/llvm/include/llvm/TableGen/CodeGenHelpers.h b/llvm/include/llvm/TableGen/CodeGenHelpers.h
index 5b823db494e7a..4199fdfb2aff9 100644
--- a/llvm/include/llvm/TableGen/CodeGenHelpers.h
+++ b/llvm/include/llvm/TableGen/CodeGenHelpers.h
@@ -34,6 +34,22 @@ class IfDefEmitter {
   raw_ostream &OS;
 };
 
+// Simple RAII helper for emitting header inclusion guard (i.e,
+// ifndef-define-endif).
+class InclusionGuardEmitter {
+public:
+  InclusionGuardEmitter(raw_ostream &OS, StringRef Name)
+      : Name(Name.str()), OS(OS) {
+    OS << "#ifndef " << Name << "\n"
+       << "#define " << Name << "\n\n";
+  }
+  ~InclusionGuardEmitter() { OS << "\n#endif // " << Name << "\n\n"; }
+
+private:
+  std::string Name;
+  raw_ostream &OS;
+};
+
 // Simple RAII helper for emitting namespace scope. Name can be a single
 // namespace (empty for anonymous namespace) or nested namespace.
 class NamespaceEmitter {
diff --git a/llvm/test/TableGen/directive1.td b/llvm/test/TableGen/directive1.td
index 3eda077eeabf7..475faf9254157 100644
--- a/llvm/test/TableGen/directive1.td
+++ b/llvm/test/TableGen/directive1.td
@@ -177,6 +177,7 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // CHECK-NEXT:    static constexpr bool is_iterable = true;
 // CHECK-NEXT:  };
 // CHECK-NEXT:  } // namespace llvm
+// CHECK-EMPTY:
 // CHECK-NEXT:  #endif // LLVM_Tdl_INC
 
 
diff --git a/llvm/test/TableGen/directive2.td b/llvm/test/TableGen/directive2.td
index a25197c3efd93..ccc09446b4465 100644
--- a/llvm/test/TableGen/directive2.td
+++ b/llvm/test/TableGen/directive2.td
@@ -150,6 +150,7 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // CHECK-NEXT:    static constexpr bool is_iterable = true;
 // CHECK-NEXT:  };
 // CHECK-NEXT:  } // namespace llvm
+// CHECK-EMPTY:
 // CHECK-NEXT:  #endif // LLVM_Tdl_INC
 
 // IMPL:      #ifdef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
diff --git a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
index b4d816ea211f7..decef7e4eae62 100644
--- a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
@@ -266,10 +266,9 @@ static void emitDirectivesDecl(const RecordKeeper &Records, raw_ostream &OS) {
     return;
 
   StringRef Lang = DirLang.getName();
+  InclusionGuardEmitter IncGuard(OS, (Twine("LLVM_") + Lang + "_INC").str());
 
-  OS << "#ifndef LLVM_" << Lang << "_INC\n";
-  OS << "#define LLVM_" << Lang << "_INC\n";
-  OS << "\n#include \"llvm/ADT/ArrayRef.h\"\n";
+  OS << "#include \"llvm/ADT/ArrayRef.h\"\n";
 
   if (DirLang.hasEnableBitmaskEnumInNamespace())
     OS << "#include \"llvm/ADT/BitmaskEnum.h\"\n";
@@ -370,7 +369,6 @@ static void emitDirectivesDecl(const RecordKeeper &Records, raw_ostream &OS) {
     OS << "};\n";
   }
   LlvmNS.close();
-  OS << "#endif // LLVM_" << Lang << "_INC\n";
 }
 
 // Given a list of spellings (for a given clause/directive), order them

Copy link
Member

@lenary lenary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Collaborator

@joker-eph joker-eph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice helper :)

@jurahul jurahul changed the title [NFC][TableGen] Add InclusionGuardEmitter to emit header inclusion guards [NFC][TableGen] Add IncludeGuardEmitter to emit header include guards Oct 14, 2025
@jurahul
Copy link
Contributor Author

jurahul commented Oct 14, 2025

I also renamed it to a more canonical IncludeGuardEmitter instead of Inclusion.

@jurahul jurahul merged commit 43f9017 into llvm:main Oct 14, 2025
10 checks passed
@jurahul jurahul deleted the inclusion_guard_emitter branch October 14, 2025 19:51
akadutta pushed a commit to akadutta/llvm-project that referenced this pull request Oct 14, 2025
…ds (llvm#163283)

Add a RAII class `IncludeGuardEmitter` which is similar to
`IfDefEmitter` but emits header include guards and adopt it in
DirectiveEmitter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants