1*0b57cec5SDimitry Andric //===- CXXFieldCollector.h - Utility class for C++ class semantic analysis ===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file provides CXXFieldCollector that is used during parsing & semantic 10*0b57cec5SDimitry Andric // analysis of C++ classes. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #ifndef LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H 15*0b57cec5SDimitry Andric #define LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H 16*0b57cec5SDimitry Andric 17*0b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 19*0b57cec5SDimitry Andric 20*0b57cec5SDimitry Andric namespace clang { 21*0b57cec5SDimitry Andric class FieldDecl; 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric /// CXXFieldCollector - Used to keep track of CXXFieldDecls during parsing of 24*0b57cec5SDimitry Andric /// C++ classes. 25*0b57cec5SDimitry Andric class CXXFieldCollector { 26*0b57cec5SDimitry Andric /// Fields - Contains all FieldDecls collected during parsing of a C++ 27*0b57cec5SDimitry Andric /// class. When a nested class is entered, its fields are appended to the 28*0b57cec5SDimitry Andric /// fields of its parent class, when it is exited its fields are removed. 29*0b57cec5SDimitry Andric SmallVector<FieldDecl*, 32> Fields; 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric /// FieldCount - Each entry represents the number of fields collected during 32*0b57cec5SDimitry Andric /// the parsing of a C++ class. When a nested class is entered, a new field 33*0b57cec5SDimitry Andric /// count is pushed, when it is exited, the field count is popped. 34*0b57cec5SDimitry Andric SmallVector<size_t, 4> FieldCount; 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andric // Example: 37*0b57cec5SDimitry Andric // 38*0b57cec5SDimitry Andric // class C { 39*0b57cec5SDimitry Andric // int x,y; 40*0b57cec5SDimitry Andric // class NC { 41*0b57cec5SDimitry Andric // int q; 42*0b57cec5SDimitry Andric // // At this point, Fields contains [x,y,q] decls and FieldCount contains 43*0b57cec5SDimitry Andric // // [2,1]. 44*0b57cec5SDimitry Andric // }; 45*0b57cec5SDimitry Andric // int z; 46*0b57cec5SDimitry Andric // // At this point, Fields contains [x,y,z] decls and FieldCount contains 47*0b57cec5SDimitry Andric // // [3]. 48*0b57cec5SDimitry Andric // }; 49*0b57cec5SDimitry Andric 50*0b57cec5SDimitry Andric public: 51*0b57cec5SDimitry Andric /// StartClass - Called by Sema::ActOnStartCXXClassDef. StartClass()52*0b57cec5SDimitry Andric void StartClass() { FieldCount.push_back(0); } 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric /// Add - Called by Sema::ActOnCXXMemberDeclarator. Add(FieldDecl * D)55*0b57cec5SDimitry Andric void Add(FieldDecl *D) { 56*0b57cec5SDimitry Andric Fields.push_back(D); 57*0b57cec5SDimitry Andric ++FieldCount.back(); 58*0b57cec5SDimitry Andric } 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric /// getCurNumField - The number of fields added to the currently parsed class. getCurNumFields()61*0b57cec5SDimitry Andric size_t getCurNumFields() const { 62*0b57cec5SDimitry Andric assert(!FieldCount.empty() && "no currently-parsed class"); 63*0b57cec5SDimitry Andric return FieldCount.back(); 64*0b57cec5SDimitry Andric } 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric /// getCurFields - Pointer to array of fields added to the currently parsed 67*0b57cec5SDimitry Andric /// class. getCurFields()68*0b57cec5SDimitry Andric FieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); } 69*0b57cec5SDimitry Andric 70*0b57cec5SDimitry Andric /// FinishClass - Called by Sema::ActOnFinishCXXClassDef. FinishClass()71*0b57cec5SDimitry Andric void FinishClass() { 72*0b57cec5SDimitry Andric Fields.resize(Fields.size() - getCurNumFields()); 73*0b57cec5SDimitry Andric FieldCount.pop_back(); 74*0b57cec5SDimitry Andric } 75*0b57cec5SDimitry Andric }; 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric } // end namespace clang 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric #endif 80