Added prototype implementation of the DeclGroup, DeclGroupRef, and DeclGroupOwningRef classes.

Documentation and testing are pending.

llvm-svn: 56611
This commit is contained in:
Ted Kremenek 2008-09-25 17:13:40 +00:00
parent 32a733e2c7
commit a5e23f6b78
2 changed files with 155 additions and 0 deletions

View File

@ -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 <cassert>
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<uintptr_t>(D)) {}
explicit DeclGroupRef(DeclGroup* D)
: ThePtr(reinterpret_cast<uintptr_t>(D) | DeclGroupKind) {}
typedef Decl** iterator;
iterator begin() {
if (getKind() == DeclKind)
return ThePtr ? (Decl**) &ThePtr : 0;
DeclGroup* G = reinterpret_cast<DeclGroup*>(ThePtr & ~Mask);
return &(*G)[0];
}
iterator end() {
if (getKind() == DeclKind)
return ThePtr ? ((Decl**) &ThePtr) + 1 : 0;
DeclGroup* G = reinterpret_cast<DeclGroup*>(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

View File

@ -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<DeclGroup>::Alignment;
void* mem = C.getAllocator().Allocate(size, alignment);
new (mem) DeclGroup(numdecls, decls);
return static_cast<DeclGroup*>(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<Decl*>(ThePtr)->Destroy(C);
else
reinterpret_cast<DeclGroup*>(ThePtr & ~Mask)->Destroy(C);
ThePtr = 0;
}