From a5e23f6b789374b48b9831199e3562432afcf7f8 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 25 Sep 2008 17:13:40 +0000 Subject: [PATCH] Added prototype implementation of the DeclGroup, DeclGroupRef, and DeclGroupOwningRef classes. Documentation and testing are pending. llvm-svn: 56611 --- clang/include/clang/AST/DeclGroup.h | 96 +++++++++++++++++++++++++++++ clang/lib/AST/DeclGroup.cpp | 59 ++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 clang/include/clang/AST/DeclGroup.h create mode 100644 clang/lib/AST/DeclGroup.cpp diff --git a/clang/include/clang/AST/DeclGroup.h b/clang/include/clang/AST/DeclGroup.h new file mode 100644 index 000000000000..75095d6c0088 --- /dev/null +++ b/clang/include/clang/AST/DeclGroup.h @@ -0,0 +1,96 @@ +//===--- DeclGroup.h - Classes for representing groups of Decls -*- 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 DeclGroup, DeclGroupRef, and OwningDeclGroup classes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLGROUP_H +#define LLVM_CLANG_AST_DECLGROUP_H + +#include "llvm/Support/DataTypes.h" +#include + +namespace clang { + +class ASTContext; +class Decl; +class DeclGroup; +class DeclGroupIterator; + +class DeclGroup { + // FIXME: Include a TypeSpecifier object. + unsigned NumDecls; + +private: + DeclGroup(unsigned numdecls, Decl** decls); + +public: + static DeclGroup* Create(ASTContext& C, unsigned numdecls, Decl** decls); + void Destroy(ASTContext& C); + + unsigned size() const { return NumDecls; } + Decl*& operator[](unsigned i) { + assert (i < NumDecls && "Out-of-bounds access."); + return *((Decl**) (this+1)); + } +}; + +class DeclGroupRef { +protected: + enum Kind { DeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 }; + uintptr_t ThePtr; + + Kind getKind() const { return (Kind) (ThePtr & Mask); } + +public: + DeclGroupRef() : ThePtr(0) {} + + explicit DeclGroupRef(Decl* D) + : ThePtr(reinterpret_cast(D)) {} + + explicit DeclGroupRef(DeclGroup* D) + : ThePtr(reinterpret_cast(D) | DeclGroupKind) {} + + typedef Decl** iterator; + + iterator begin() { + if (getKind() == DeclKind) + return ThePtr ? (Decl**) &ThePtr : 0; + + DeclGroup* G = reinterpret_cast(ThePtr & ~Mask); + return &(*G)[0]; + } + + iterator end() { + if (getKind() == DeclKind) + return ThePtr ? ((Decl**) &ThePtr) + 1 : 0; + + DeclGroup* G = reinterpret_cast(ThePtr & ~Mask); + return &(*G)[0] + G->size(); + } +}; + +class DeclGroupOwningRef : public DeclGroupRef { +public: + ~DeclGroupOwningRef(); + void Destroy(ASTContext& C); + + explicit DeclGroupOwningRef(DeclGroupOwningRef& R) + : DeclGroupRef(R) { R.ThePtr = 0; } + + DeclGroupOwningRef& operator=(DeclGroupOwningRef& R) { + ThePtr = R.ThePtr; + R.ThePtr = 0; + return *this; + } +}; + +} // end clang namespace +#endif diff --git a/clang/lib/AST/DeclGroup.cpp b/clang/lib/AST/DeclGroup.cpp new file mode 100644 index 000000000000..5987d5a7012a --- /dev/null +++ b/clang/lib/AST/DeclGroup.cpp @@ -0,0 +1,59 @@ +//===--- DeclGroup.cpp - Classes for representing groups of Decls -*- 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 DeclGroup, DeclGroupRef, and OwningDeclGroup classes. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/DeclGroup.h" +#include "clang/AST/Decl.h" +#include "clang/AST/ASTContext.h" +#include "llvm/Support/Allocator.h" + +using namespace clang; + +DeclGroup* DeclGroup::Create(ASTContext& C, unsigned numdecls, Decl** decls) { + unsigned size = sizeof(DeclGroup) + sizeof(Decl*) * numdecls; + unsigned alignment = llvm::AlignOf::Alignment; + void* mem = C.getAllocator().Allocate(size, alignment); + new (mem) DeclGroup(numdecls, decls); + return static_cast(mem); +} + +DeclGroup::DeclGroup(unsigned numdecls, Decl** decls) { + assert (numdecls > 0); + assert (decls); + memcpy(this+1, decls, numdecls * sizeof(*decls)); +} + +void DeclGroup::Destroy(ASTContext& C) { + Decl** Decls = (Decl**) this + 1; + + for (unsigned i = 0; i < NumDecls; ++i) + Decls[i]->Destroy(C); + + this->~DeclGroup(); + C.getAllocator().Deallocate((void*) this); +} + +DeclGroupOwningRef::~DeclGroupOwningRef() { + assert (ThePtr == 0 && "Destroy method not called."); +} + +void DeclGroupOwningRef::Destroy(ASTContext& C) { + if (!ThePtr) + return; + + if (getKind() == DeclKind) + reinterpret_cast(ThePtr)->Destroy(C); + else + reinterpret_cast(ThePtr & ~Mask)->Destroy(C); + + ThePtr = 0; +}