-Add DeclChain member to DeclContext.
-ScopedDecls get chained to their DeclContext. -DeclContext's DeclChain replaces FunctionDecl's DeclChain and EnumDecl's ElementList. llvm-svn: 52164
This commit is contained in:
parent
1b095b443c
commit
406fb231f8
|
@ -379,10 +379,6 @@ private:
|
|||
|
||||
Stmt *Body; // Null if a prototype.
|
||||
|
||||
/// DeclChain - Linked list of declarations that are defined inside this
|
||||
/// function.
|
||||
ScopedDecl *DeclChain;
|
||||
|
||||
/// PreviousDeclaration - A link to the previous declaration of this
|
||||
/// same function, NULL if this is the first declaration. For
|
||||
/// example, in the following code, the PreviousDeclaration can be
|
||||
|
@ -405,7 +401,7 @@ protected:
|
|||
StorageClass S, bool isInline, ScopedDecl *PrevDecl)
|
||||
: ValueDecl(DK, DC, L, Id, T, PrevDecl),
|
||||
DeclContext(DK),
|
||||
ParamInfo(0), Body(0), DeclChain(0), PreviousDeclaration(0),
|
||||
ParamInfo(0), Body(0), PreviousDeclaration(0),
|
||||
SClass(S), IsInline(isInline), IsImplicit(0) {}
|
||||
|
||||
virtual ~FunctionDecl();
|
||||
|
@ -438,9 +434,6 @@ public:
|
|||
|
||||
bool isImplicit() { return IsImplicit; }
|
||||
void setImplicit() { IsImplicit = true; }
|
||||
|
||||
ScopedDecl *getDeclChain() const { return DeclChain; }
|
||||
void setDeclChain(ScopedDecl *D) { DeclChain = D; }
|
||||
|
||||
/// getPreviousDeclaration - Return the previous declaration of this
|
||||
/// function.
|
||||
|
@ -720,10 +713,9 @@ protected:
|
|||
/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
|
||||
/// enums.
|
||||
class EnumDecl : public TagDecl, public DeclContext {
|
||||
/// ElementList - this is a linked list of EnumConstantDecl's which are linked
|
||||
/// together through their getNextDeclarator pointers.
|
||||
EnumConstantDecl *ElementList;
|
||||
|
||||
// EnumDecl's DeclChain points to a linked list of EnumConstantDecl's which
|
||||
// are linked together through their getNextDeclarator pointers.
|
||||
|
||||
/// IntegerType - This represent the integer type that the enum corresponds
|
||||
/// to for code generation purposes. Note that the enumerator constants may
|
||||
/// have a different type than this does.
|
||||
|
@ -732,7 +724,6 @@ class EnumDecl : public TagDecl, public DeclContext {
|
|||
EnumDecl(DeclContext *DC, SourceLocation L,
|
||||
IdentifierInfo *Id, ScopedDecl *PrevDecl)
|
||||
: TagDecl(Enum, DC, L, Id, PrevDecl), DeclContext(Enum) {
|
||||
ElementList = 0;
|
||||
IntegerType = QualType();
|
||||
}
|
||||
public:
|
||||
|
@ -747,7 +738,7 @@ public:
|
|||
/// specified list of enums.
|
||||
void defineElements(EnumConstantDecl *ListHead, QualType NewType) {
|
||||
assert(!isDefinition() && "Cannot redefine enums!");
|
||||
ElementList = ListHead;
|
||||
setDeclChain(ListHead);
|
||||
setDefinition(true);
|
||||
|
||||
IntegerType = NewType;
|
||||
|
@ -759,8 +750,12 @@ public:
|
|||
|
||||
/// getEnumConstantList - Return the first EnumConstantDecl in the enum.
|
||||
///
|
||||
EnumConstantDecl *getEnumConstantList() { return ElementList; }
|
||||
const EnumConstantDecl *getEnumConstantList() const { return ElementList; }
|
||||
EnumConstantDecl *getEnumConstantList() {
|
||||
return cast_or_null<EnumConstantDecl>(getDeclChain());
|
||||
}
|
||||
const EnumConstantDecl *getEnumConstantList() const {
|
||||
return cast_or_null<const EnumConstantDecl>(getDeclChain());
|
||||
}
|
||||
|
||||
static bool classof(const Decl *D) { return D->getKind() == Enum; }
|
||||
static bool classof(const EnumDecl *D) { return true; }
|
||||
|
|
|
@ -237,6 +237,10 @@ class DeclContext {
|
|||
/// DeclKind - This indicates which class this is.
|
||||
Decl::Kind DeclKind : 8;
|
||||
|
||||
/// DeclChain - Linked list of declarations that are defined inside this
|
||||
/// declaration context.
|
||||
ScopedDecl *DeclChain;
|
||||
|
||||
// Used in the CastTo template to get the DeclKind
|
||||
// from a Decl or a DeclContext. DeclContext doesn't have a getKind() method
|
||||
// to avoid 'ambiguous access' compiler errors.
|
||||
|
@ -271,7 +275,7 @@ class DeclContext {
|
|||
}
|
||||
|
||||
protected:
|
||||
DeclContext(Decl::Kind K) : DeclKind(K) {}
|
||||
DeclContext(Decl::Kind K) : DeclKind(K), DeclChain(0) {}
|
||||
|
||||
public:
|
||||
/// getParent - Returns the containing DeclContext if this is a ScopedDecl,
|
||||
|
@ -289,6 +293,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
ScopedDecl *getDeclChain() const { return DeclChain; }
|
||||
void setDeclChain(ScopedDecl *D) { DeclChain = D; }
|
||||
|
||||
/// ToDecl and FromDecl make Decl <-> DeclContext castings.
|
||||
/// They are intended to be used by the simplify_type and cast_convert_val
|
||||
/// templates.
|
||||
|
@ -321,6 +328,12 @@ public:
|
|||
static bool classof(const EnumDecl *D) { return true; }
|
||||
static bool classof(const ObjCMethodDecl *D) { return true; }
|
||||
static bool classof(const ObjCInterfaceDecl *D) { return true; }
|
||||
|
||||
private:
|
||||
void EmitOutRec(llvm::Serializer& S) const;
|
||||
void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
|
||||
|
||||
friend class Decl;
|
||||
};
|
||||
|
||||
template<> struct DeclContext::KindTrait<DeclContext> {
|
||||
|
|
|
@ -116,7 +116,7 @@ RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
|
|||
}
|
||||
|
||||
void EnumDecl::Destroy(ASTContext& C) {
|
||||
if (ElementList) ElementList->Destroy(C);
|
||||
if (getEnumConstantList()) getEnumConstantList()->Destroy(C);
|
||||
Decl::Destroy(C);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,13 @@ using namespace clang;
|
|||
void Decl::Emit(Serializer& S) const {
|
||||
S.EmitInt(getKind());
|
||||
EmitImpl(S);
|
||||
if (const DeclContext *DC = dyn_cast<const DeclContext>(this))
|
||||
DC->EmitOutRec(S);
|
||||
}
|
||||
|
||||
Decl* Decl::Create(Deserializer& D, ASTContext& C) {
|
||||
|
||||
Decl *Dcl;
|
||||
Kind k = static_cast<Kind>(D.ReadInt());
|
||||
|
||||
switch (k) {
|
||||
|
@ -42,39 +45,56 @@ Decl* Decl::Create(Deserializer& D, ASTContext& C) {
|
|||
break;
|
||||
|
||||
case TranslationUnit:
|
||||
return TranslationUnitDecl::CreateImpl(D, C);
|
||||
Dcl = TranslationUnitDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case Namespace:
|
||||
return NamespaceDecl::CreateImpl(D, C);
|
||||
Dcl = NamespaceDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case Var:
|
||||
return VarDecl::CreateImpl(D, C);
|
||||
Dcl = VarDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case Enum:
|
||||
return EnumDecl::CreateImpl(D, C);
|
||||
Dcl = EnumDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case EnumConstant:
|
||||
return EnumConstantDecl::CreateImpl(D, C);
|
||||
Dcl = EnumConstantDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case Field:
|
||||
return FieldDecl::CreateImpl(D, C);
|
||||
Dcl = FieldDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case ParmVar:
|
||||
return ParmVarDecl::CreateImpl(D, C);
|
||||
Dcl = ParmVarDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case Function:
|
||||
return FunctionDecl::CreateImpl(D, C);
|
||||
|
||||
Dcl = FunctionDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case Class:
|
||||
case Union:
|
||||
case Struct:
|
||||
return RecordDecl::CreateImpl(k, D, C);
|
||||
Dcl = RecordDecl::CreateImpl(k, D, C);
|
||||
break;
|
||||
|
||||
case Typedef:
|
||||
return TypedefDecl::CreateImpl(D, C);
|
||||
Dcl = TypedefDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case FileScopeAsm:
|
||||
return FileScopeAsmDecl::CreateImpl(D, C);
|
||||
Dcl = FileScopeAsmDecl::CreateImpl(D, C);
|
||||
break;
|
||||
}
|
||||
|
||||
if (DeclContext *DC = dyn_cast<DeclContext>(Dcl))
|
||||
DC->ReadOutRec(D, C);
|
||||
|
||||
return Dcl;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -89,6 +109,18 @@ void Decl::ReadInRec(Deserializer& D, ASTContext& C) {
|
|||
Loc = SourceLocation::ReadVal(D); // From Decl.
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Common serialization logic for subclasses of DeclContext.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void DeclContext::EmitOutRec(Serializer& S) const {
|
||||
S.EmitPtr(DeclChain);
|
||||
}
|
||||
|
||||
void DeclContext::ReadOutRec(Deserializer& D, ASTContext& C) {
|
||||
D.ReadPtr(DeclChain);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Common serialization logic for subclasses of NamedDecl.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -283,7 +315,7 @@ void EnumDecl::EmitImpl(Serializer& S) const {
|
|||
ScopedDecl::EmitInRec(S);
|
||||
S.EmitBool(isDefinition());
|
||||
S.Emit(IntegerType);
|
||||
S.BatchEmitOwnedPtrs(ElementList,getNextDeclarator());
|
||||
S.BatchEmitOwnedPtrs(getEnumConstantList(),getNextDeclarator());
|
||||
}
|
||||
|
||||
EnumDecl* EnumDecl::CreateImpl(Deserializer& D, ASTContext& C) {
|
||||
|
@ -299,7 +331,7 @@ EnumDecl* EnumDecl::CreateImpl(Deserializer& D, ASTContext& C) {
|
|||
|
||||
D.BatchReadOwnedPtrs(Elist, next_declarator, C);
|
||||
|
||||
decl->ElementList = cast_or_null<EnumConstantDecl>(Elist);
|
||||
decl->setDeclChain(cast_or_null<EnumConstantDecl>(Elist));
|
||||
decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
|
||||
|
||||
return decl;
|
||||
|
@ -361,7 +393,6 @@ void FunctionDecl::EmitImpl(Serializer& S) const {
|
|||
S.EmitInt(SClass); // From FunctionDecl.
|
||||
S.EmitBool(IsInline); // From FunctionDecl.
|
||||
ValueDecl::EmitInRec(S);
|
||||
S.EmitPtr(DeclChain);
|
||||
S.EmitPtr(PreviousDeclaration);
|
||||
|
||||
// NOTE: We do not need to serialize out the number of parameters, because
|
||||
|
@ -388,7 +419,6 @@ FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) {
|
|||
QualType(), SClass, IsInline, 0);
|
||||
|
||||
decl->ValueDecl::ReadInRec(D, C);
|
||||
D.ReadPtr(decl->DeclChain);
|
||||
D.ReadPtr(decl->PreviousDeclaration);
|
||||
|
||||
Decl* next_declarator;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "clang/AST/Attr.h"
|
||||
#include "clang/AST/Builtins.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
|
@ -90,34 +91,27 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
|
|||
if (S->decl_empty()) return;
|
||||
assert((S->getFlags() & Scope::DeclScope) &&"Scope shouldn't contain decls!");
|
||||
|
||||
// We only want to remove the decls from the identifier decl chains for local
|
||||
// scopes, when inside a function/method.
|
||||
if (S->getFnParent() == 0)
|
||||
return;
|
||||
|
||||
for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
|
||||
I != E; ++I) {
|
||||
Decl *TmpD = static_cast<Decl*>(*I);
|
||||
assert(TmpD && "This decl didn't get pushed??");
|
||||
ScopedDecl *D = dyn_cast<ScopedDecl>(TmpD);
|
||||
assert(D && "This decl isn't a ScopedDecl?");
|
||||
|
||||
if (isa<CXXFieldDecl>(TmpD)) continue;
|
||||
|
||||
assert(isa<ScopedDecl>(TmpD) && "Decl isn't ScopedDecl?");
|
||||
ScopedDecl *D = cast<ScopedDecl>(TmpD);
|
||||
|
||||
IdentifierInfo *II = D->getIdentifier();
|
||||
if (!II) continue;
|
||||
|
||||
// Unlink this decl from the identifier.
|
||||
IdResolver.RemoveDecl(D);
|
||||
// We only want to remove the decls from the identifier decl chains for local
|
||||
// scopes, when inside a function/method.
|
||||
if (S->getFnParent() != 0)
|
||||
IdResolver.RemoveDecl(D);
|
||||
|
||||
// This will have to be revisited for C++: there we want to nest stuff in
|
||||
// namespace decls etc. Even for C, we might want a top-level translation
|
||||
// unit decl or something.
|
||||
if (!CurFunctionDecl)
|
||||
continue;
|
||||
|
||||
// Chain this decl to the containing function, it now owns the memory for
|
||||
// the decl.
|
||||
D->setNext(CurFunctionDecl->getDeclChain());
|
||||
CurFunctionDecl->setDeclChain(D);
|
||||
// Chain this decl to the containing DeclContext.
|
||||
D->setNext(CurContext->getDeclChain());
|
||||
CurContext->setDeclChain(D);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue