107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis//===- CXXFieldCollector.h - Utility class for C++ class semantic analysis ===//
207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis//
307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis//
507952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis// License. See LICENSE.TXT for details.
707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis//
807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis//
1007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis//  This file provides CXXFieldCollector that is used during parsing & semantic
1107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis//  analysis of C++ classes.
1207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis//
1307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
1407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
1507952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis#ifndef LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
1607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis#define LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
1707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
189946fc735d7285f2195f89635370f534afd9877eDmitri Gribenko#include "clang/Basic/LLVM.h"
1907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis#include "llvm/ADT/SmallVector.h"
2007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
2107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidisnamespace clang {
2244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  class FieldDecl;
2307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
2407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis/// CXXFieldCollector - Used to keep track of CXXFieldDecls during parsing of
2507952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis/// C++ classes.
2607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidisclass CXXFieldCollector {
2744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  /// Fields - Contains all FieldDecls collected during parsing of a C++
2807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  /// class. When a nested class is entered, its fields are appended to the
2907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  /// fields of its parent class, when it is exited its fields are removed.
30686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<FieldDecl*, 32> Fields;
3107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
3207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  /// FieldCount - Each entry represents the number of fields collected during
3307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  /// the parsing of a C++ class. When a nested class is entered, a new field
3407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  /// count is pushed, when it is exited, the field count is popped.
35686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<size_t, 4> FieldCount;
3607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
3707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  // Example:
3807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  //
3907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  // class C {
4007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  //   int x,y;
4107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  //   class NC {
4207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  //     int q;
4307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  //     // At this point, Fields contains [x,y,q] decls and FieldCount contains
4407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  //     // [2,1].
4507952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  //   };
4607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  //   int z;
4707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  //   // At this point, Fields contains [x,y,z] decls and FieldCount contains
4807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  //   // [3].
4907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  // };
5007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
5107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidispublic:
5207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  /// StartClass - Called by Sema::ActOnStartCXXClassDef.
5307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  void StartClass() { FieldCount.push_back(0); }
5407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
5507952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  /// Add - Called by Sema::ActOnCXXMemberDeclarator.
5644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  void Add(FieldDecl *D) {
5707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    Fields.push_back(D);
5807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    ++FieldCount.back();
5907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  }
6007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
617bfa29111950cc013df6726203732d5a2b3c1165Argyrios Kyrtzidis  /// getCurNumField - The number of fields added to the currently parsed class.
62a8cab015e5f2750cb6f15e71016569739c2ad1e3John McCall  size_t getCurNumFields() const {
63a8cab015e5f2750cb6f15e71016569739c2ad1e3John McCall    assert(!FieldCount.empty() && "no currently-parsed class");
64a8cab015e5f2750cb6f15e71016569739c2ad1e3John McCall    return FieldCount.back();
65a8cab015e5f2750cb6f15e71016569739c2ad1e3John McCall  }
6607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
677bfa29111950cc013df6726203732d5a2b3c1165Argyrios Kyrtzidis  /// getCurFields - Pointer to array of fields added to the currently parsed
6807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  /// class.
6944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  FieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); }
7007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
7107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  /// FinishClass - Called by Sema::ActOnFinishCXXClassDef.
7207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  void FinishClass() {
7307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    Fields.resize(Fields.size() - getCurNumFields());
7407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    FieldCount.pop_back();
7507952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis  }
7607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis};
7707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
7807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis} // end namespace clang
7907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
8007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis#endif
81