#define LLVM_CLANG_TRANSLATION_UNIT_H
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
#include "llvm/Bitcode/SerializationFwd.h"
#include "llvm/System/Path.h"
-#include <vector>
#include <string>
namespace clang {
class TranslationUnit {
ASTContext* Context;
- std::vector<Decl*> TopLevelDecls;
bool OwnsMetaData;
bool OwnsDecls;
ASTContext& getContext() { return *Context; }
const ASTContext& getContext() const { return *Context; }
-
- /// AddTopLevelDecl - Add a top-level declaration to the translation unit.
- /// Ownership of the Decl is transfered to the TranslationUnit object.
- void AddTopLevelDecl(Decl* d) {
- TopLevelDecls.push_back(d);
+
+ typedef DeclContext::decl_iterator iterator;
+ iterator begin() const {
+ return Context->getTranslationUnitDecl()->decls_begin();
}
-
- typedef std::vector<Decl*>::iterator iterator;
- iterator begin() { return TopLevelDecls.begin(); }
- iterator end() { return TopLevelDecls.end(); }
-
- typedef std::vector<Decl*>::const_iterator const_iterator;
- const_iterator begin() const { return TopLevelDecls.begin(); }
- const_iterator end() const { return TopLevelDecls.end(); }
+ iterator end() const { return Context->getTranslationUnitDecl()->decls_end(); }
};
/// EmitASTBitcodeFile - Emit a translation unit to a bitcode file.
void Decl::Destroy(ASTContext& C) {
#if 0
- // FIXME: This causes double-destroys in some cases, so it is
- // disabled at the moment.
+ // FIXME: Once ownership is fully understood, we can enable this code
+ if (DeclContext *DC = dyn_cast<DeclContext>(this))
+ DC->decls_begin()->Destroy(C);
- // Observe the unrolled recursion. By setting N->NextDeclarator = 0x0
+ // Observe the unrolled recursion. By setting N->NextDeclInScope = 0x0
// within the loop, only the Destroy method for the first Decl
// will deallocate all of the Decls in a chain.
- Decl* N = SD->getNextDeclarator();
+ Decl* N = NextDeclInScope;
while (N) {
- Decl* Tmp = N->getNextDeclarator();
- N->NextDeclarator = 0x0;
+ Decl* Tmp = N->NextDeclInScope;
+ N->NextDeclInScope = 0;
N->Destroy(C);
N = Tmp;
}
-#endif
this->~Decl();
C.getAllocator().Deallocate((void *)this);
+#endif
}
Decl *Decl::castFromDeclContext (const DeclContext *D) {
}
void DeclContext::DestroyDecls(ASTContext &C) {
- for (decl_iterator D = decls_begin(); D != decls_end(); ) {
- // FIXME: assert that this condition holds.
- if ((*D)->getLexicalDeclContext() == this)
- // Advance the cursor (via NextDeclInScope) *before* doing the Destroy.
- (*D++)->Destroy(C);
- else
- ++D;
- }
+ for (decl_iterator D = decls_begin(); D != decls_end(); )
+ (*D++)->Destroy(C);
}
bool DeclContext::isTransparentContext() const {
DeclsBlock = 3 };
TranslationUnit::~TranslationUnit() {
- if (OwnsDecls) {
- llvm::DenseSet<Decl*> Killed;
- for (std::vector<Decl*>::reverse_iterator I=TopLevelDecls.rbegin(),
- E=TopLevelDecls.rend();
- I!=E; ++I) {
- if (Killed.count(*I)) continue;
-
- Killed.insert(*I);
-
- // FIXME: This is a horrible hack. Because there is no clear ownership
- // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
- // reference, we need to destroy ObjCPropertyDecls here. This will
- // eventually be fixed when the ownership of ObjCPropertyDecls gets
- // cleaned up.
- if (ObjCInterfaceDecl* IDecl = dyn_cast<ObjCInterfaceDecl>(*I))
- for (ObjCInterfaceDecl::prop_iterator ID=IDecl->prop_begin(),
- ED=IDecl->prop_end(); ID!=ED; ++ID) {
- if (!*ID || Killed.count(*ID)) continue;
- Killed.insert(*ID);
- (*ID)->Destroy(*Context);
- }
-
- // FIXME: This is a horrible hack. Because there is no clear ownership
- // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
- // reference, we need to destroy ObjCPropertyDecls here. This will
- // eventually be fixed when the ownership of ObjCPropertyDecls gets
- // cleaned up.
- if (ObjCProtocolDecl* PDecl = dyn_cast<ObjCProtocolDecl>(*I))
- for (ObjCProtocolDecl::prop_iterator ID=PDecl->prop_begin(),
- ED=PDecl->prop_end(); ID!=ED; ++ID) {
- if (!*ID || Killed.count(*ID)) continue;
- Killed.insert(*ID);
- (*ID)->Destroy(*Context);
- }
-
- // FIXME: There is no clear ownership policy now for ObjCInterfaceDecls
- // referenced by ObjCClassDecls. Some of them can be forward decls that
- // are never later defined (and forward decls can be referenced by
- // multiple ObjCClassDecls) or the ObjCInterfaceDecl later
- // becomes a real definition.
- // Ideally we should have separate objects for forward declarations and
- // definitions, obviating this problem. Because of this situation,
- // referenced ObjCInterfaceDecls are destroyed here.
- if (ObjCClassDecl* CDecl = dyn_cast<ObjCClassDecl>(*I))
- for (ObjCClassDecl::iterator ID=CDecl->begin(),
- ED=CDecl->end(); ID!=ED; ++ID) {
- if (!*ID || Killed.count(*ID)) continue;
- Killed.insert(*ID);
- (*ID)->Destroy(*Context);
- }
-
- // FIXME: There is no clear ownership policy now for ObjCProtocolDecls
- // referenced by ObjCForwardProtocolDecl. Some of them can be forward
- // decls that are never later defined (and forward decls can be
- // referenced by multiple ObjCClassDecls) or the ObjCProtocolDecl
- // later becomes a real definition.
- // Ideally we should have separate objects for forward declarations and
- // definitions, obviating this problem. Because of this situation,
- // referenced ObjCProtocolDecls are destroyed here.
- if (ObjCForwardProtocolDecl* FDec = dyn_cast<ObjCForwardProtocolDecl>(*I))
- for (ObjCForwardProtocolDecl::iterator ID=FDec->begin(),
- ED=FDec->end(); ID!=ED; ++ID) {
- if (!*ID || Killed.count(*ID)) continue;
- Killed.insert(*ID);
- (*ID)->Destroy(*Context);
- }
-
-
- (*I)->Destroy(*Context);
- }
- }
-
if (OwnsMetaData && Context) {
// The ASTContext object has the sole references to the IdentifierTable
// Selectors, and the Target information. Go and delete them, since
}
void TranslationUnit::Emit(llvm::Serializer& Sezr) const {
-
- // ===---------------------------------------------------===/
- // Serialize the top-level decls.
- // ===---------------------------------------------------===/
-
- Sezr.EnterBlock(DeclsBlock);
-
- // Only serialize the head of a decl chain. The ASTConsumer interfaces
- // provides us with each top-level decl, including those nested in
- // a decl chain, so we may be passed decls that are already serialized.
- for (const_iterator I=begin(), E=end(); I!=E; ++I)
- if (!Sezr.isRegistered(*I))
- Sezr.EmitOwnedPtr(*I);
-
- Sezr.ExitBlock();
-
// ===---------------------------------------------------===/
// Serialize the "Translation Unit" metadata.
// ===---------------------------------------------------===/
Dezr.JumpTo(ASTContextBlockLoc);
TU->Context = Dezr.ReadOwnedPtr<ASTContext>();
- // "Rewind" the stream. Find the block with the serialized top-level decls.
- Dezr.Rewind();
- FoundBlock = Dezr.SkipToBlock(DeclsBlock);
- assert (FoundBlock);
- llvm::Deserializer::Location DeclBlockLoc = Dezr.getCurrentBlockLocation();
-
- while (!Dezr.FinishedBlock(DeclBlockLoc))
- TU->AddTopLevelDecl(Dezr.ReadOwnedPtr<Decl>(*TU->Context));
-
return TU;
}