//===-- DeclNodes.def - Metadata about Decl AST nodes -----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the declaration nodes within the AST. The
//  description of the declaration nodes uses six macros: 
//
//  DECL(Derived, Base) describes a normal declaration type Derived
//  and specifies its base class. Note that Derived should not have
//  the Decl suffix on it, while Base should.
//
//  LAST_DECL(Derived, Base) is like DECL, but is used for the last
//  declaration in the list.
//
//  ABSTRACT_DECL(Derived, Base) describes an abstract class that is
//  used to specify a classification of declarations. For example,
//  TagDecl is an abstract class used to describe the various kinds of
//  "tag" declarations (unions, structs, classes, enums).
//
//  DECL_CONTEXT(Decl) specifies that Decl is a kind of declaration
//  that is also a DeclContext.
//  
//  LAST_DECL_CONTEXT(Decl) is like DECL_CONTEXT, but is used for the
//  last declaration context.
//
//  DECL_RANGE(CommonBase, Start, End) specifies a range of
//  declaration values that have a common (potentially indirect) base
//  class.
//
//  LAST_DECL_RANGE(CommonBase, Start, End) is like DECL_RANGE, but is
//  used for the last declaration range.
//
//  Note that, due to the use of ranges, the order of the these
//  declarations is significant. A declaration should be listed under
//  its base class.
//  ===----------------------------------------------------------------------===//

#ifndef DECL
#  define DECL(Derived, Base)
#endif

#ifndef LAST_DECL
#  define LAST_DECL(Derived, Base) DECL(Derived, Base)
#endif

#ifndef ABSTRACT_DECL
#  define ABSTRACT_DECL(Derived, Base)
#endif

#ifndef DECL_CONTEXT
#  define DECL_CONTEXT(Decl)
#endif

#ifndef DECL_CONTEXT_BASE
#  define DECL_CONTEXT_BASE(Decl) DECL_CONTEXT(Decl)
#endif

#ifndef LAST_DECL_CONTEXT
#  define LAST_DECL_CONTEXT(Decl) DECL_CONTEXT(Decl)
#endif

#ifndef DECL_RANGE
#  define DECL_RANGE(CommonBase, Start, End)
#endif

#ifndef LAST_DECL_RANGE
#  define LAST_DECL_RANGE(CommonBase, Start, End) \
  DECL_RANGE(CommonBase, Start, End)
#endif

DECL(TranslationUnit, Decl)
ABSTRACT_DECL(Named,  Decl)
  DECL(Namespace, NamedDecl)
  DECL(UsingDirective, NamedDecl)
  DECL(NamespaceAlias, NamedDecl)
  ABSTRACT_DECL(Type, NamedDecl)
    DECL(Typedef, TypeDecl)
    DECL(UnresolvedUsingTypename, TypeDecl)
    ABSTRACT_DECL(Tag, TypeDecl)
      DECL(Enum, TagDecl)
      DECL(Record, TagDecl)
        DECL(CXXRecord, RecordDecl)
          DECL(ClassTemplateSpecialization, CXXRecordDecl)
            DECL(ClassTemplatePartialSpecialization, 
                 ClassTemplateSpecializationDecl)
    DECL(TemplateTypeParm, TypeDecl)
  ABSTRACT_DECL(Value, NamedDecl)
    DECL(EnumConstant, ValueDecl)
    DECL(UnresolvedUsingValue, ValueDecl)
    ABSTRACT_DECL(Declarator, ValueDecl)
      DECL(Function, DeclaratorDecl)
        DECL(CXXMethod, FunctionDecl)
          DECL(CXXConstructor, CXXMethodDecl)
          DECL(CXXDestructor, CXXMethodDecl)
          DECL(CXXConversion, CXXMethodDecl)
      DECL(Field, DeclaratorDecl)
        DECL(ObjCIvar, FieldDecl)
        DECL(ObjCAtDefsField, FieldDecl)
      DECL(Var, DeclaratorDecl)
        DECL(ImplicitParam, VarDecl)
        DECL(ParmVar, VarDecl)
        DECL(NonTypeTemplateParm, VarDecl)
  DECL(Template, NamedDecl)
    DECL(FunctionTemplate, TemplateDecl)
    DECL(ClassTemplate, TemplateDecl)
    DECL(TemplateTemplateParm, TemplateDecl)
  DECL(Using, NamedDecl)
  DECL(UsingShadow, NamedDecl)
  DECL(ObjCMethod, NamedDecl)
  DECL(ObjCContainer, NamedDecl)
    DECL(ObjCCategory, ObjCContainerDecl)
    DECL(ObjCProtocol, ObjCContainerDecl)
    DECL(ObjCInterface, ObjCContainerDecl)
    ABSTRACT_DECL(ObjCImpl, ObjCContainerDecl)
      DECL(ObjCCategoryImpl, ObjCImplDecl)
      DECL(ObjCImplementation, ObjCImplDecl)
  DECL(ObjCProperty, NamedDecl)
  DECL(ObjCCompatibleAlias, NamedDecl)
DECL(LinkageSpec, Decl)
DECL(ObjCPropertyImpl, Decl)
DECL(ObjCForwardProtocol, Decl)
DECL(ObjCClass, Decl)
DECL(FileScopeAsm, Decl)
DECL(Friend, Decl)
DECL(FriendTemplate, Decl)
DECL(StaticAssert, Decl)
LAST_DECL(Block, Decl)

// Declaration contexts. DECL_CONTEXT_BASE indicates that it has subclasses.
DECL_CONTEXT(TranslationUnit)
DECL_CONTEXT(Namespace)
DECL_CONTEXT(LinkageSpec)
DECL_CONTEXT(ObjCMethod)
DECL_CONTEXT_BASE(Tag)
DECL_CONTEXT_BASE(Function)
DECL_CONTEXT_BASE(ObjCContainer)
LAST_DECL_CONTEXT(Block)

// Declaration ranges
DECL_RANGE(Named, Namespace, ObjCCompatibleAlias)
DECL_RANGE(ObjCContainer, ObjCContainer, ObjCImplementation)
DECL_RANGE(Field, Field, ObjCAtDefsField)
DECL_RANGE(Type, Typedef, TemplateTypeParm)
DECL_RANGE(Tag, Enum, ClassTemplatePartialSpecialization)
DECL_RANGE(Record, Record, ClassTemplatePartialSpecialization)
DECL_RANGE(Value, EnumConstant, NonTypeTemplateParm)
DECL_RANGE(Declarator, Function, NonTypeTemplateParm)
DECL_RANGE(Function, Function, CXXConversion)
DECL_RANGE(Template, Template, TemplateTemplateParm)
DECL_RANGE(ObjCImpl, ObjCCategoryImpl, ObjCImplementation)
LAST_DECL_RANGE(Var, Var, NonTypeTemplateParm)

#undef LAST_DECL_RANGE
#undef DECL_RANGE
#undef LAST_DECL_CONTEXT
#undef DECL_CONTEXT_BASE
#undef DECL_CONTEXT
#undef ABSTRACT_DECL
#undef LAST_DECL
#undef DECL
