brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 7ca1141 Raw
94 lines · cpp
1//===- Formula.cpp ----------------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "clang/Analysis/FlowSensitive/Formula.h"10#include "clang/Basic/LLVM.h"11#include "llvm/ADT/STLExtras.h"12#include "llvm/ADT/StringRef.h"13#include "llvm/Support/Allocator.h"14#include "llvm/Support/ErrorHandling.h"15#include <cassert>16 17namespace clang::dataflow {18 19const Formula &Formula::create(llvm::BumpPtrAllocator &Alloc, Kind K,20                               ArrayRef<const Formula *> Operands,21                               unsigned Value) {22  assert(Operands.size() == numOperands(K));23  if (Value != 0) // Currently, formulas have values or operands, not both.24    assert(numOperands(K) == 0);25  void *Mem = Alloc.Allocate(sizeof(Formula) +26                                 Operands.size() * sizeof(Operands.front()),27                             alignof(Formula));28  Formula *Result = new (Mem) Formula();29  Result->FormulaKind = K;30  Result->Value = Value;31  // Operands are stored as `const Formula *`s after the formula itself.32  // We don't need to construct an object as pointers are trivial types.33  // Formula is alignas(const Formula *), so alignment is satisfied.34  llvm::copy(Operands, reinterpret_cast<const Formula **>(Result + 1));35  return *Result;36}37 38static llvm::StringLiteral sigil(Formula::Kind K) {39  switch (K) {40  case Formula::AtomRef:41  case Formula::Literal:42    return "";43  case Formula::Not:44    return "!";45  case Formula::And:46    return " & ";47  case Formula::Or:48    return " | ";49  case Formula::Implies:50    return " => ";51  case Formula::Equal:52    return " = ";53  }54  llvm_unreachable("unhandled formula kind");55}56 57void Formula::print(llvm::raw_ostream &OS, const AtomNames *Names) const {58  if (Names && kind() == AtomRef)59    if (auto It = Names->find(getAtom()); It != Names->end()) {60      OS << It->second;61      return;62    }63 64  switch (numOperands(kind())) {65  case 0:66    switch (kind()) {67    case AtomRef:68      OS << getAtom();69      break;70    case Literal:71      OS << (literal() ? "true" : "false");72      break;73    default:74      llvm_unreachable("unhandled formula kind");75    }76    break;77  case 1:78    OS << sigil(kind());79    operands()[0]->print(OS, Names);80    break;81  case 2:82    OS << '(';83    operands()[0]->print(OS, Names);84    OS << sigil(kind());85    operands()[1]->print(OS, Names);86    OS << ')';87    break;88  default:89    llvm_unreachable("unhandled formula arity");90  }91}92 93} // namespace clang::dataflow94