1212795Sdim//===- CXXFieldCollector.h - Utility class for C++ class semantic analysis ===//
2212795Sdim//
3212795Sdim//                     The LLVM Compiler Infrastructure
4212795Sdim//
5212795Sdim// This file is distributed under the University of Illinois Open Source
6212795Sdim// License. See LICENSE.TXT for details.
7212795Sdim//
8212795Sdim//===----------------------------------------------------------------------===//
9212795Sdim//
10212795Sdim//  This file provides CXXFieldCollector that is used during parsing & semantic
11212795Sdim//  analysis of C++ classes.
12212795Sdim//
13212795Sdim//===----------------------------------------------------------------------===//
14212795Sdim
15212795Sdim#ifndef LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
16212795Sdim#define LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
17212795Sdim
18249423Sdim#include "clang/Basic/LLVM.h"
19212795Sdim#include "llvm/ADT/SmallVector.h"
20212795Sdim
21212795Sdimnamespace clang {
22212795Sdim  class FieldDecl;
23212795Sdim
24212795Sdim/// CXXFieldCollector - Used to keep track of CXXFieldDecls during parsing of
25212795Sdim/// C++ classes.
26212795Sdimclass CXXFieldCollector {
27212795Sdim  /// Fields - Contains all FieldDecls collected during parsing of a C++
28212795Sdim  /// class. When a nested class is entered, its fields are appended to the
29212795Sdim  /// fields of its parent class, when it is exited its fields are removed.
30226633Sdim  SmallVector<FieldDecl*, 32> Fields;
31212795Sdim
32212795Sdim  /// FieldCount - Each entry represents the number of fields collected during
33212795Sdim  /// the parsing of a C++ class. When a nested class is entered, a new field
34212795Sdim  /// count is pushed, when it is exited, the field count is popped.
35226633Sdim  SmallVector<size_t, 4> FieldCount;
36212795Sdim
37212795Sdim  // Example:
38212795Sdim  //
39212795Sdim  // class C {
40212795Sdim  //   int x,y;
41212795Sdim  //   class NC {
42212795Sdim  //     int q;
43212795Sdim  //     // At this point, Fields contains [x,y,q] decls and FieldCount contains
44212795Sdim  //     // [2,1].
45212795Sdim  //   };
46212795Sdim  //   int z;
47212795Sdim  //   // At this point, Fields contains [x,y,z] decls and FieldCount contains
48212795Sdim  //   // [3].
49212795Sdim  // };
50212795Sdim
51212795Sdimpublic:
52212795Sdim  /// StartClass - Called by Sema::ActOnStartCXXClassDef.
53212795Sdim  void StartClass() { FieldCount.push_back(0); }
54212795Sdim
55212795Sdim  /// Add - Called by Sema::ActOnCXXMemberDeclarator.
56212795Sdim  void Add(FieldDecl *D) {
57212795Sdim    Fields.push_back(D);
58212795Sdim    ++FieldCount.back();
59212795Sdim  }
60212795Sdim
61212795Sdim  /// getCurNumField - The number of fields added to the currently parsed class.
62212795Sdim  size_t getCurNumFields() const {
63212795Sdim    assert(!FieldCount.empty() && "no currently-parsed class");
64212795Sdim    return FieldCount.back();
65212795Sdim  }
66212795Sdim
67212795Sdim  /// getCurFields - Pointer to array of fields added to the currently parsed
68212795Sdim  /// class.
69212795Sdim  FieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); }
70212795Sdim
71212795Sdim  /// FinishClass - Called by Sema::ActOnFinishCXXClassDef.
72212795Sdim  void FinishClass() {
73212795Sdim    Fields.resize(Fields.size() - getCurNumFields());
74212795Sdim    FieldCount.pop_back();
75212795Sdim  }
76212795Sdim};
77212795Sdim
78212795Sdim} // end namespace clang
79212795Sdim
80212795Sdim#endif
81