brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.0 KiB · 0f2eaa9 Raw
92 lines · cpp
1//===- Origins.cpp - Origin Implementation -----------------------*- 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/Analyses/LifetimeSafety/Origins.h"10 11namespace clang::lifetimes::internal {12 13void OriginManager::dump(OriginID OID, llvm::raw_ostream &OS) const {14  OS << OID << " (";15  Origin O = getOrigin(OID);16  if (const ValueDecl *VD = O.getDecl())17    OS << "Decl: " << VD->getNameAsString();18  else if (const Expr *E = O.getExpr())19    OS << "Expr: " << E->getStmtClassName();20  else21    OS << "Unknown";22  OS << ")";23}24 25Origin &OriginManager::addOrigin(OriginID ID, const clang::ValueDecl &D) {26  AllOrigins.emplace_back(ID, &D);27  return AllOrigins.back();28}29 30Origin &OriginManager::addOrigin(OriginID ID, const clang::Expr &E) {31  AllOrigins.emplace_back(ID, &E);32  return AllOrigins.back();33}34 35// TODO: Mark this method as const once we remove the call to getOrCreate.36OriginID OriginManager::get(const Expr &E) {37  if (auto *ParenIgnored = E.IgnoreParens(); ParenIgnored != &E)38    return get(*ParenIgnored);39  auto It = ExprToOriginID.find(&E);40  if (It != ExprToOriginID.end())41    return It->second;42  // If the expression itself has no specific origin, and it's a reference43  // to a declaration, its origin is that of the declaration it refers to.44  // For pointer types, where we don't pre-emptively create an origin for the45  // DeclRefExpr itself.46  if (const auto *DRE = dyn_cast<DeclRefExpr>(&E))47    return get(*DRE->getDecl());48  // TODO: This should be an assert(It != ExprToOriginID.end()). The current49  // implementation falls back to getOrCreate to avoid crashing on50  // yet-unhandled pointer expressions, creating an empty origin for them.51  return getOrCreate(E);52}53 54OriginID OriginManager::get(const ValueDecl &D) {55  auto It = DeclToOriginID.find(&D);56  // TODO: This should be an assert(It != DeclToOriginID.end()). The current57  // implementation falls back to getOrCreate to avoid crashing on58  // yet-unhandled pointer expressions, creating an empty origin for them.59  if (It == DeclToOriginID.end())60    return getOrCreate(D);61 62  return It->second;63}64 65OriginID OriginManager::getOrCreate(const Expr &E) {66  auto It = ExprToOriginID.find(&E);67  if (It != ExprToOriginID.end())68    return It->second;69 70  OriginID NewID = getNextOriginID();71  addOrigin(NewID, E);72  ExprToOriginID[&E] = NewID;73  return NewID;74}75 76const Origin &OriginManager::getOrigin(OriginID ID) const {77  assert(ID.Value < AllOrigins.size());78  return AllOrigins[ID.Value];79}80 81OriginID OriginManager::getOrCreate(const ValueDecl &D) {82  auto It = DeclToOriginID.find(&D);83  if (It != DeclToOriginID.end())84    return It->second;85  OriginID NewID = getNextOriginID();86  addOrigin(NewID, D);87  DeclToOriginID[&D] = NewID;88  return NewID;89}90 91} // namespace clang::lifetimes::internal92