semantics_ir.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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) -> SemanticsIR;
  44. // Prints the full IR.
  45. auto Print(llvm::raw_ostream& out) const -> void;
  46. private:
  47. friend class SemanticsParseTreeHandler;
  48. // For the builtin IR only.
  49. SemanticsIR() : SemanticsIR(*this) {}
  50. // For most IRs.
  51. SemanticsIR(const SemanticsIR& builtins)
  52. : cross_reference_irs_({&builtins, this}),
  53. cross_references_(builtins.cross_references_) {}
  54. // Adds an identifier, returning an ID to reference it.
  55. // TODO: Deduplicate strings.
  56. // TODO: Probably make generic for all strings, including literals.
  57. auto AddIdentifier(llvm::StringRef identifier) -> SemanticsIdentifierId {
  58. SemanticsIdentifierId id(identifiers_.size());
  59. identifiers_.push_back(identifier);
  60. return id;
  61. }
  62. // Adds an integer literal, returning an ID to reference it.
  63. auto AddIntegerLiteral(llvm::APInt integer_literal)
  64. -> SemanticsIntegerLiteralId {
  65. SemanticsIntegerLiteralId id(integer_literals_.size());
  66. integer_literals_.push_back(integer_literal);
  67. return id;
  68. }
  69. // Adds an empty new node block, returning an ID to reference it and add
  70. // items.
  71. auto AddNodeBlock() -> SemanticsNodeBlockId {
  72. SemanticsNodeBlockId id(node_blocks_.size());
  73. node_blocks_.resize(node_blocks_.size() + 1);
  74. return id;
  75. }
  76. // Adds a node to a specified block, returning an ID to reference the node.
  77. auto AddNode(SemanticsNodeBlockId block_id, SemanticsNode node)
  78. -> SemanticsNodeId {
  79. auto& block = node_blocks_[block_id.id];
  80. SemanticsNodeId node_id(block.size());
  81. block.push_back(node);
  82. return node_id;
  83. }
  84. // Related IRs. There will always be at least 2 entries, the builtin IR (used
  85. // for references of builtins) followed by the current IR (used for references
  86. // crossing node blocks).
  87. llvm::SmallVector<const SemanticsIR*> cross_reference_irs_;
  88. // Cross-references within the current IR across node blocks, and to other
  89. // IRs. The first entries will always be builtins, at indices matching
  90. // SemanticsBuiltinKind ordering.
  91. // TODO: Deduplicate cross-references after they can be added outside
  92. // builtins.
  93. llvm::SmallVector<SemanticsCrossReference> cross_references_;
  94. // Storage for identifiers.
  95. llvm::SmallVector<llvm::StringRef> identifiers_;
  96. // Storage for integer literals.
  97. llvm::SmallVector<llvm::APInt> integer_literals_;
  98. // Storage for blocks within the IR.
  99. llvm::SmallVector<llvm::SmallVector<SemanticsNode>> node_blocks_;
  100. };
  101. } // namespace Carbon
  102. #endif // CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_IR_H_