Path: blob/main/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Formula.cpp
35266 views
//===- Formula.cpp ----------------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "clang/Analysis/FlowSensitive/Formula.h"9#include "clang/Basic/LLVM.h"10#include "llvm/ADT/STLExtras.h"11#include "llvm/ADT/StringRef.h"12#include "llvm/Support/Allocator.h"13#include "llvm/Support/ErrorHandling.h"14#include <cassert>15#include <type_traits>1617namespace clang::dataflow {1819const Formula &Formula::create(llvm::BumpPtrAllocator &Alloc, Kind K,20ArrayRef<const Formula *> Operands,21unsigned Value) {22assert(Operands.size() == numOperands(K));23if (Value != 0) // Currently, formulas have values or operands, not both.24assert(numOperands(K) == 0);25void *Mem = Alloc.Allocate(sizeof(Formula) +26Operands.size() * sizeof(Operands.front()),27alignof(Formula));28Formula *Result = new (Mem) Formula();29Result->FormulaKind = K;30Result->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.34llvm::copy(Operands, reinterpret_cast<const Formula **>(Result + 1));35return *Result;36}3738static llvm::StringLiteral sigil(Formula::Kind K) {39switch (K) {40case Formula::AtomRef:41case Formula::Literal:42return "";43case Formula::Not:44return "!";45case Formula::And:46return " & ";47case Formula::Or:48return " | ";49case Formula::Implies:50return " => ";51case Formula::Equal:52return " = ";53}54llvm_unreachable("unhandled formula kind");55}5657void Formula::print(llvm::raw_ostream &OS, const AtomNames *Names) const {58if (Names && kind() == AtomRef)59if (auto It = Names->find(getAtom()); It != Names->end()) {60OS << It->second;61return;62}6364switch (numOperands(kind())) {65case 0:66switch (kind()) {67case AtomRef:68OS << getAtom();69break;70case Literal:71OS << (literal() ? "true" : "false");72break;73default:74llvm_unreachable("unhandled formula kind");75}76break;77case 1:78OS << sigil(kind());79operands()[0]->print(OS, Names);80break;81case 2:82OS << '(';83operands()[0]->print(OS, Names);84OS << sigil(kind());85operands()[1]->print(OS, Names);86OS << ')';87break;88default:89llvm_unreachable("unhandled formula arity");90}91}9293} // namespace clang::dataflow9495