blob: 70c8dc94e2df67b3c8db999b58de248ce7f72298 [file] [log] [blame]
Eugene Zelenko21fadad2017-11-21 23:26:08 +00001//===- StmtIterator.cpp - Iterators for Statements ------------------------===//
Ted Kremenek336886a2007-10-18 00:24:38 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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-exception
Ted Kremenek336886a2007-10-18 00:24:38 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file defines internal methods for StmtIterator.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/StmtIterator.h"
Ted Kremenek336886a2007-10-18 00:24:38 +000014#include "clang/AST/Decl.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000015#include "clang/AST/Type.h"
16#include "clang/Basic/LLVM.h"
17#include "llvm/Support/Casting.h"
18#include <cassert>
19#include <cstdint>
Ted Kremenek336886a2007-10-18 00:24:38 +000020
21using namespace clang;
22
Douglas Gregor4619e432008-12-05 23:32:09 +000023// FIXME: Add support for dependent-sized array types in C++?
24// Does it even make sense to build a CFG for an uninstantiated template?
John McCall424cec92011-01-19 06:33:43 +000025static inline const VariableArrayType *FindVA(const Type* t) {
26 while (const ArrayType *vt = dyn_cast<ArrayType>(t)) {
27 if (const VariableArrayType *vat = dyn_cast<VariableArrayType>(vt))
Ted Kremenek2f70e712007-10-29 20:50:16 +000028 if (vat->getSizeExpr())
29 return vat;
Mike Stump11289f42009-09-09 15:08:12 +000030
Ted Kremenek2f70e712007-10-29 20:50:16 +000031 t = vt->getElementType().getTypePtr();
Ted Kremenek2ba761c2007-10-18 18:19:31 +000032 }
Mike Stump11289f42009-09-09 15:08:12 +000033
Craig Topper36250ad2014-05-12 05:36:57 +000034 return nullptr;
Ted Kremenek2f70e712007-10-29 20:50:16 +000035}
36
37void StmtIteratorBase::NextVA() {
Eugene Zelenko21fadad2017-11-21 23:26:08 +000038 assert(getVAPtr());
Ted Kremenek2f70e712007-10-29 20:50:16 +000039
John McCall424cec92011-01-19 06:33:43 +000040 const VariableArrayType *p = getVAPtr();
Ted Kremenek2f70e712007-10-29 20:50:16 +000041 p = FindVA(p->getElementType().getTypePtr());
42 setVAPtr(p);
43
Ted Kremenek587a44f2008-10-07 23:35:42 +000044 if (p)
45 return;
Mike Stump11289f42009-09-09 15:08:12 +000046
Eli Friedman2850ba82013-06-27 20:39:04 +000047 if (inDeclGroup()) {
Mike Stump11289f42009-09-09 15:08:12 +000048 if (VarDecl* VD = dyn_cast<VarDecl>(*DGI))
Chandler Carruth813faed2015-12-30 02:51:00 +000049 if (VD->hasInit())
Ted Kremenek587a44f2008-10-07 23:35:42 +000050 return;
Mike Stump11289f42009-09-09 15:08:12 +000051
52 NextDecl();
Ted Kremenek587a44f2008-10-07 23:35:42 +000053 }
54 else {
Eli Friedman2850ba82013-06-27 20:39:04 +000055 assert(inSizeOfTypeVA());
Ted Kremenek85e45f22007-12-14 22:52:23 +000056 RawVAPtr = 0;
Eli Friedman0883bfb2008-05-21 05:06:46 +000057 }
Ted Kremenek2f70e712007-10-29 20:50:16 +000058}
59
60void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
Craig Topper36250ad2014-05-12 05:36:57 +000061 assert(getVAPtr() == nullptr);
Eli Friedman2850ba82013-06-27 20:39:04 +000062 assert(inDeclGroup());
Mike Stump11289f42009-09-09 15:08:12 +000063
Eli Friedman2850ba82013-06-27 20:39:04 +000064 if (ImmediateAdvance)
65 ++DGI;
Mike Stump11289f42009-09-09 15:08:12 +000066
Eli Friedman2850ba82013-06-27 20:39:04 +000067 for ( ; DGI != DGE; ++DGI)
68 if (HandleDecl(*DGI))
Chris Lattner5bbb3c82009-03-29 16:50:03 +000069 return;
Ted Kremenek2f70e712007-10-29 20:50:16 +000070
Ted Kremenekf9638ba2008-10-07 23:04:14 +000071 RawVAPtr = 0;
72}
73
74bool StmtIteratorBase::HandleDecl(Decl* D) {
Mike Stump11289f42009-09-09 15:08:12 +000075 if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
John McCall424cec92011-01-19 06:33:43 +000076 if (const VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
Ted Kremenekf9638ba2008-10-07 23:04:14 +000077 setVAPtr(VAPtr);
78 return true;
Ted Kremenek2f70e712007-10-29 20:50:16 +000079 }
Mike Stump11289f42009-09-09 15:08:12 +000080
Ted Kremenekf9638ba2008-10-07 23:04:14 +000081 if (VD->getInit())
82 return true;
Ted Kremenek2f70e712007-10-29 20:50:16 +000083 }
Richard Smithdda56e42011-04-15 14:24:37 +000084 else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) {
John McCall424cec92011-01-19 06:33:43 +000085 if (const VariableArrayType* VAPtr =
Ted Kremenekf9638ba2008-10-07 23:04:14 +000086 FindVA(TD->getUnderlyingType().getTypePtr())) {
87 setVAPtr(VAPtr);
88 return true;
89 }
Ted Kremenek899ef132007-10-29 21:23:58 +000090 }
Ted Kremenekf9638ba2008-10-07 23:04:14 +000091 else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) {
92 if (ECD->getInitExpr())
93 return true;
94 }
95
Mike Stump11289f42009-09-09 15:08:12 +000096 return false;
Ted Kremenek2f70e712007-10-29 20:50:16 +000097}
98
Ted Kremenekf9638ba2008-10-07 23:04:14 +000099StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000100 : DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
Ted Kremenekf9638ba2008-10-07 23:04:14 +0000101 NextDecl(false);
102}
103
John McCall424cec92011-01-19 06:33:43 +0000104StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t)
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000105 : DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) {
Ted Kremenek85e45f22007-12-14 22:52:23 +0000106 RawVAPtr |= reinterpret_cast<uintptr_t>(t);
107}
108
Ted Kremenek066f6032007-10-25 22:24:19 +0000109Stmt*& StmtIteratorBase::GetDeclExpr() const {
John McCall424cec92011-01-19 06:33:43 +0000110 if (const VariableArrayType* VAPtr = getVAPtr()) {
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000111 assert(VAPtr->SizeExpr);
John McCall424cec92011-01-19 06:33:43 +0000112 return const_cast<Stmt*&>(VAPtr->SizeExpr);
Ted Kremenek066f6032007-10-25 22:24:19 +0000113 }
Ted Kremenekbe485b62009-03-11 18:17:16 +0000114
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000115 assert(inDeclGroup());
Eli Friedman2850ba82013-06-27 20:39:04 +0000116 VarDecl* VD = cast<VarDecl>(*DGI);
117 return *VD->getInitAddress();
Ted Kremenek336886a2007-10-18 00:24:38 +0000118}