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
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();
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.
/// 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.
EnumDecl(DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, ScopedDecl *PrevDecl)
: TagDecl(Enum, DC, L, Id, PrevDecl), DeclContext(Enum) {
- ElementList = 0;
IntegerType = QualType();
}
public:
/// specified list of enums.
void defineElements(EnumConstantDecl *ListHead, QualType NewType) {
assert(!isDefinition() && "Cannot redefine enums!");
- ElementList = ListHead;
+ setDeclChain(ListHead);
setDefinition(true);
IntegerType = NewType;
/// 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; }
/// 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.
}
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,
}
}
+ 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.
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> {
}
void EnumDecl::Destroy(ASTContext& C) {
- if (ElementList) ElementList->Destroy(C);
+ if (getEnumConstantList()) getEnumConstantList()->Destroy(C);
Decl::Destroy(C);
}
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) {
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;
}
//===----------------------------------------------------------------------===//
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.
//===----------------------------------------------------------------------===//
ScopedDecl::EmitInRec(S);
S.EmitBool(isDefinition());
S.Emit(IntegerType);
- S.BatchEmitOwnedPtrs(ElementList,getNextDeclarator());
+ S.BatchEmitOwnedPtrs(getEnumConstantList(),getNextDeclarator());
}
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;
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
QualType(), SClass, IsInline, 0);
decl->ValueDecl::ReadInRec(D, C);
- D.ReadPtr(decl->DeclChain);
D.ReadPtr(decl->PreviousDeclaration);
Decl* next_declarator;
#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"
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);
-
- // 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);
+ // 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);
+
+ // Chain this decl to the containing DeclContext.
+ D->setNext(CurContext->getDeclChain());
+ CurContext->setDeclChain(D);
}
}