1 //===- ConstructionContext.cpp - CFG constructor information --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the ConstructionContext class and its sub-classes, 11 // which represent various different ways of constructing C++ objects 12 // with the additional information the users may want to know about 13 // the constructor. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #include "clang/Analysis/ConstructionContext.h" 18 19 using namespace clang; 20 21 const ConstructionContextLayer * 22 ConstructionContextLayer::create(BumpVectorContext &C, TriggerTy Trigger, 23 const ConstructionContextLayer *Parent) { 24 ConstructionContextLayer *CC = 25 C.getAllocator().Allocate<ConstructionContextLayer>(); 26 return new (CC) ConstructionContextLayer(Trigger, Parent); 27 } 28 29 bool ConstructionContextLayer::isStrictlyMoreSpecificThan( 30 const ConstructionContextLayer *Other) const { 31 const ConstructionContextLayer *Self = this; 32 while (true) { 33 if (!Other) 34 return Self; 35 if (!Self || !Self->isSameLayer(Other)) 36 return false; 37 Self = Self->getParent(); 38 Other = Other->getParent(); 39 } 40 llvm_unreachable("The above loop can only be terminated via return!"); 41 } 42 43 const ConstructionContext *ConstructionContext::createFromLayers( 44 BumpVectorContext &C, const ConstructionContextLayer *TopLayer) { 45 // Before this point all we've had was a stockpile of arbitrary layers. 46 // Now validate that it is shaped as one of the finite amount of expected 47 // patterns. 48 if (const Stmt *S = TopLayer->getTriggerStmt()) { 49 if (const auto *DS = dyn_cast<DeclStmt>(S)) { 50 assert(TopLayer->isLast()); 51 auto *CC = 52 C.getAllocator().Allocate<SimpleVariableConstructionContext>(); 53 return new (CC) SimpleVariableConstructionContext(DS); 54 } else if (const auto *NE = dyn_cast<CXXNewExpr>(S)) { 55 assert(TopLayer->isLast()); 56 auto *CC = 57 C.getAllocator().Allocate<NewAllocatedObjectConstructionContext>(); 58 return new (CC) NewAllocatedObjectConstructionContext(NE); 59 } else if (const auto *BTE = dyn_cast<CXXBindTemporaryExpr>(S)) { 60 const MaterializeTemporaryExpr *MTE = nullptr; 61 assert(BTE->getType().getCanonicalType() 62 ->getAsCXXRecordDecl()->hasNonTrivialDestructor()); 63 // For temporaries with destructors, there may or may not be 64 // lifetime extension on the parent layer. 65 if (const ConstructionContextLayer *ParentLayer = TopLayer->getParent()) { 66 assert(ParentLayer->isLast()); 67 MTE = cast<MaterializeTemporaryExpr>(ParentLayer->getTriggerStmt()); 68 } 69 auto *CC = 70 C.getAllocator().Allocate<TemporaryObjectConstructionContext>(); 71 return new (CC) TemporaryObjectConstructionContext(BTE, MTE); 72 } else if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(S)) { 73 // If the object requires destruction and is not lifetime-extended, 74 // then it must have a BTE within its MTE. 75 assert(MTE->getType().getCanonicalType() 76 ->getAsCXXRecordDecl()->hasTrivialDestructor() || 77 MTE->getStorageDuration() != SD_FullExpression); 78 assert(TopLayer->isLast()); 79 auto *CC = 80 C.getAllocator().Allocate<TemporaryObjectConstructionContext>(); 81 return new (CC) TemporaryObjectConstructionContext(nullptr, MTE); 82 } else if (const auto *RS = dyn_cast<ReturnStmt>(S)) { 83 assert(TopLayer->isLast()); 84 auto *CC = 85 C.getAllocator().Allocate<ReturnedValueConstructionContext>(); 86 return new (CC) ReturnedValueConstructionContext(RS); 87 } 88 } else if (const CXXCtorInitializer *I = TopLayer->getTriggerInit()) { 89 assert(TopLayer->isLast()); 90 auto *CC = 91 C.getAllocator().Allocate<ConstructorInitializerConstructionContext>(); 92 return new (CC) ConstructorInitializerConstructionContext(I); 93 } 94 llvm_unreachable("Unexpected construction context!"); 95 } 96