semantics_ir.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_IR_H_
  5. #define CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_IR_H_
  6. #include "llvm/ADT/ArrayRef.h"
  7. #include "llvm/ADT/SmallVector.h"
  8. #include "toolchain/parser/parse_tree.h"
  9. #include "toolchain/semantics/semantics_node.h"
  10. namespace Carbon::Testing {
  11. class SemanticsIRForTest;
  12. } // namespace Carbon::Testing
  13. namespace Carbon {
  14. // The ID of a cross-referenced IR (within cross_reference_irs_).
  15. struct SemanticsCrossReferenceIRId {
  16. SemanticsCrossReferenceIRId() : id(-1) {}
  17. constexpr explicit SemanticsCrossReferenceIRId(int32_t id) : id(id) {}
  18. auto Print(llvm::raw_ostream& out) const -> void { out << "ir" << id; }
  19. int32_t id;
  20. };
  21. // A cross-reference between node blocks or IRs; essentially, anything that's
  22. // not in the same SemanticsNodeBlock as the referencing node.
  23. struct SemanticsCrossReference {
  24. SemanticsCrossReference() = default;
  25. SemanticsCrossReference(SemanticsCrossReferenceIRId ir,
  26. SemanticsNodeBlockId node_block, SemanticsNodeId node)
  27. : ir(ir), node_block(node_block), node(node) {}
  28. auto Print(llvm::raw_ostream& out) const -> void {
  29. out << "xref(" << ir << ", " << node_block << ", " << node << ")";
  30. }
  31. SemanticsCrossReferenceIRId ir;
  32. SemanticsNodeBlockId node_block;
  33. SemanticsNodeId node;
  34. };
  35. // Provides semantic analysis on a ParseTree.
  36. class SemanticsIR {
  37. public:
  38. // Produces the builtins.
  39. static auto MakeBuiltinIR() -> SemanticsIR;
  40. // Adds the IR for the provided ParseTree.
  41. static auto MakeFromParseTree(const SemanticsIR& builtin_ir,
  42. const TokenizedBuffer& tokens,
  43. const ParseTree& parse_tree,
  44. llvm::raw_ostream* vlog_stream) -> SemanticsIR;
  45. // Prints the full IR.
  46. auto Print(llvm::raw_ostream& out) const -> void;
  47. private:
  48. friend class SemanticsParseTreeHandler;
  49. // For the builtin IR only.
  50. SemanticsIR() : SemanticsIR(*this) {}
  51. // For most IRs.
  52. SemanticsIR(const SemanticsIR& builtins)
  53. : cross_reference_irs_({&builtins, this}),
  54. cross_references_(builtins.cross_references_) {}
  55. // Adds an identifier, returning an ID to reference it.
  56. // TODO: Deduplicate strings.
  57. // TODO: Probably make generic for all strings, including literals.
  58. auto AddIdentifier(llvm::StringRef identifier) -> SemanticsIdentifierId {
  59. SemanticsIdentifierId id(identifiers_.size());
  60. identifiers_.push_back(identifier);
  61. return id;
  62. }
  63. // Adds an integer literal, returning an ID to reference it.
  64. auto AddIntegerLiteral(llvm::APInt integer_literal)
  65. -> SemanticsIntegerLiteralId {
  66. SemanticsIntegerLiteralId id(integer_literals_.size());
  67. integer_literals_.push_back(integer_literal);
  68. return id;
  69. }
  70. // Adds an empty new node block, returning an ID to reference it and add
  71. // items.
  72. auto AddNodeBlock() -> SemanticsNodeBlockId {
  73. SemanticsNodeBlockId id(node_blocks_.size());
  74. node_blocks_.resize(node_blocks_.size() + 1);
  75. return id;
  76. }
  77. // Adds a node to a specified block, returning an ID to reference the node.
  78. auto AddNode(SemanticsNodeBlockId block_id, SemanticsNode node)
  79. -> SemanticsNodeId {
  80. auto& block = node_blocks_[block_id.id];
  81. SemanticsNodeId node_id(block.size());
  82. block.push_back(node);
  83. return node_id;
  84. }
  85. // Related IRs. There will always be at least 2 entries, the builtin IR (used
  86. // for references of builtins) followed by the current IR (used for references
  87. // crossing node blocks).
  88. llvm::SmallVector<const SemanticsIR*> cross_reference_irs_;
  89. // Cross-references within the current IR across node blocks, and to other
  90. // IRs. The first entries will always be builtins, at indices matching
  91. // SemanticsBuiltinKind ordering.
  92. // TODO: Deduplicate cross-references after they can be added outside
  93. // builtins.
  94. llvm::SmallVector<SemanticsCrossReference> cross_references_;
  95. // Storage for identifiers.
  96. llvm::SmallVector<llvm::StringRef> identifiers_;
  97. // Storage for integer literals.
  98. llvm::SmallVector<llvm::APInt> integer_literals_;
  99. // Storage for blocks within the IR.
  100. llvm::SmallVector<llvm::SmallVector<SemanticsNode>> node_blocks_;
  101. };
  102. } // namespace Carbon
  103. #endif // CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_IR_H_