aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Driver/PrintParserCallbacks.cpp5
-rw-r--r--Driver/RewriteObjC.cpp41
-rw-r--r--include/clang/AST/ASTContext.h8
-rw-r--r--include/clang/AST/Decl.h195
-rw-r--r--include/clang/AST/DeclBase.h193
-rw-r--r--include/clang/AST/DeclCXX.h58
-rw-r--r--include/clang/AST/DeclObjC.h10
-rw-r--r--include/clang/AST/DeclarationName.h4
-rw-r--r--include/clang/Parse/Action.h4
-rw-r--r--include/clang/Parse/Scope.h14
-rw-r--r--lib/AST/ASTContext.cpp74
-rw-r--r--lib/AST/Decl.cpp59
-rw-r--r--lib/AST/DeclBase.cpp276
-rw-r--r--lib/AST/DeclCXX.cpp16
-rw-r--r--lib/AST/DeclObjC.cpp4
-rw-r--r--lib/AST/DeclSerialization.cpp63
-rw-r--r--lib/AST/DeclarationName.cpp6
-rw-r--r--lib/AST/Expr.cpp15
-rw-r--r--lib/AST/ExprConstant.cpp8
-rw-r--r--lib/Analysis/RegionStore.cpp9
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp9
-rw-r--r--lib/CodeGen/CGExprAgg.cpp16
-rw-r--r--lib/CodeGen/CGExprConstant.cpp19
-rw-r--r--lib/CodeGen/CGObjCMac.cpp15
-rw-r--r--lib/CodeGen/CodeGenModule.cpp36
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp39
-rw-r--r--lib/Parse/ParseDecl.cpp6
-rw-r--r--lib/Sema/CXXFieldCollector.h10
-rw-r--r--lib/Sema/IdentifierResolver.cpp7
-rw-r--r--lib/Sema/IdentifierResolver.h3
-rw-r--r--lib/Sema/Sema.cpp2
-rw-r--r--lib/Sema/Sema.h11
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp25
-rw-r--r--lib/Sema/SemaDecl.cpp297
-rw-r--r--lib/Sema/SemaDeclAttr.cpp6
-rw-r--r--lib/Sema/SemaDeclCXX.cpp73
-rw-r--r--lib/Sema/SemaDeclObjC.cpp2
-rw-r--r--lib/Sema/SemaExpr.cpp32
-rw-r--r--lib/Sema/SemaExprCXX.cpp7
-rw-r--r--lib/Sema/SemaInit.cpp28
-rw-r--r--lib/Sema/SemaOverload.cpp23
-rw-r--r--test/SemaCXX/namespace.cpp3
-rw-r--r--test/SemaCXX/qualified-id-lookup.cpp53
43 files changed, 1235 insertions, 549 deletions
diff --git a/Driver/PrintParserCallbacks.cpp b/Driver/PrintParserCallbacks.cpp
index f3ddb23a5f..8ec45f2703 100644
--- a/Driver/PrintParserCallbacks.cpp
+++ b/Driver/PrintParserCallbacks.cpp
@@ -185,13 +185,14 @@ namespace {
/// Act on @defs() element found when parsing a structure. ClassName is the
/// name of the referenced class.
- virtual void ActOnDefs(Scope *S, SourceLocation DeclStart,
+ virtual void ActOnDefs(Scope *S, DeclTy *TagD, SourceLocation DeclStart,
IdentifierInfo *ClassName,
llvm::SmallVectorImpl<DeclTy*> &Decls) {
llvm::cout << __FUNCTION__ << "\n";
}
- virtual DeclTy *ActOnField(Scope *S, SourceLocation DeclStart,
+ virtual DeclTy *ActOnField(Scope *S, DeclTy *TagD,
+ SourceLocation DeclStart,
Declarator &D, ExprTy *BitfieldWidth) {
llvm::cout << __FUNCTION__ << "\n";
return 0;
diff --git a/Driver/RewriteObjC.cpp b/Driver/RewriteObjC.cpp
index 1b7ce5bece..290a668563 100644
--- a/Driver/RewriteObjC.cpp
+++ b/Driver/RewriteObjC.cpp
@@ -2169,14 +2169,18 @@ QualType RewriteObjC::getSuperStructType() {
FieldTypes[0] = Context->getObjCIdType();
// struct objc_class *super;
FieldTypes[1] = Context->getObjCClassType();
+
// Create fields
- FieldDecl *FieldDecls[2];
-
- for (unsigned i = 0; i < 2; ++i)
- FieldDecls[i] = FieldDecl::Create(*Context, SourceLocation(), 0,
- FieldTypes[i]);
+ for (unsigned i = 0; i < 2; ++i) {
+ SuperStructDecl->addDecl(*Context,
+ FieldDecl::Create(*Context, SuperStructDecl,
+ SourceLocation(), 0,
+ FieldTypes[i], /*BitWidth=*/0,
+ /*Mutable=*/false, 0),
+ true);
+ }
- SuperStructDecl->defineBody(*Context, FieldDecls, 4);
+ SuperStructDecl->completeDefinition(*Context);
}
return Context->getTagDeclType(SuperStructDecl);
}
@@ -2196,14 +2200,20 @@ QualType RewriteObjC::getConstantStringStructType() {
FieldTypes[2] = Context->getPointerType(Context->CharTy);
// long length;
FieldTypes[3] = Context->LongTy;
+
// Create fields
- FieldDecl *FieldDecls[4];
-
- for (unsigned i = 0; i < 4; ++i)
- FieldDecls[i] = FieldDecl::Create(*Context, SourceLocation(), 0,
- FieldTypes[i]);
-
- ConstantStringDecl->defineBody(*Context, FieldDecls, 4);
+ for (unsigned i = 0; i < 4; ++i) {
+ ConstantStringDecl->addDecl(*Context,
+ FieldDecl::Create(*Context,
+ ConstantStringDecl,
+ SourceLocation(), 0,
+ FieldTypes[i],
+ /*BitWidth=*/0,
+ /*Mutable=*/true, 0),
+ true);
+ }
+
+ ConstantStringDecl->completeDefinition(*Context);
}
return Context->getTagDeclType(ConstantStringDecl);
}
@@ -3788,8 +3798,9 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp) {
ParenExpr *PE = new ParenExpr(SourceLocation(), SourceLocation(), BlkCast);
//PE->dump();
- FieldDecl *FD = FieldDecl::Create(*Context, SourceLocation(),
- &Context->Idents.get("FuncPtr"), Context->VoidPtrTy);
+ FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
+ &Context->Idents.get("FuncPtr"), Context->VoidPtrTy,
+ /*BitWidth=*/0, /*Mutable=*/true, 0);
MemberExpr *ME = new MemberExpr(PE, true, FD, SourceLocation(), FD->getType());
CastExpr *FunkCast = new CStyleCastExpr(PtrToFuncCastType, ME, PtrToFuncCastType, SourceLocation(), SourceLocation());
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 2a8b1c8a5b..45bb2c3637 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -513,10 +513,12 @@ private:
void InitBuiltinTypes();
void InitBuiltinType(QualType &R, BuiltinType::Kind K);
- /// setRecordDefinition - Used by RecordDecl::defineBody to inform ASTContext
- /// about which RecordDecl serves as the definition of a particular
- /// struct/union/class. This will eventually be used by enums as well.
+ /// setTagDefinition - Used by RecordDecl::completeDefinition and
+ /// EnumDecl::completeDefinition to inform
+ /// about which RecordDecl/EnumDecl serves as the definition of a particular
+ /// struct/union/class/enum.
void setTagDefinition(TagDecl* R);
+ friend class EnumDecl;
friend class RecordDecl;
// Return the ObjC type encoding for a given type.
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 8fbb3f00e9..3b0eb551bb 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -115,12 +115,6 @@ class ScopedDecl : public NamedDecl {
/// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
ScopedDecl *NextDeclarator;
- /// When this decl is in scope while parsing, the Next field contains a
- /// pointer to the shadowed decl of the same name. When the scope is popped,
- /// Decls are relinked onto a containing decl object.
- ///
- ScopedDecl *Next;
-
/// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
/// For declarations that don't contain C++ scope specifiers, it contains
/// the DeclContext where the ScopedDecl was declared.
@@ -150,7 +144,7 @@ class ScopedDecl : public NamedDecl {
protected:
ScopedDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName N, ScopedDecl *PrevDecl)
- : NamedDecl(DK, L, N), NextDeclarator(PrevDecl), Next(0),
+ : NamedDecl(DK, L, N), NextDeclarator(PrevDecl),
DeclCtx(reinterpret_cast<uintptr_t>(DC)) {}
virtual ~ScopedDecl();
@@ -188,9 +182,6 @@ public:
void setLexicalDeclContext(DeclContext *DC);
- ScopedDecl *getNext() const { return Next; }
- void setNext(ScopedDecl *N) { Next = N; }
-
/// getNextDeclarator - If this decl was part of a multi-declarator
/// declaration, such as "int X, Y, *Z;" this returns the decl for the next
/// declarator. Otherwise it returns null.
@@ -680,22 +671,31 @@ protected:
/// FieldDecl - An instance of this class is created by Sema::ActOnField to
/// represent a member of a struct/union/class.
-class FieldDecl : public NamedDecl {
+class FieldDecl : public ScopedDecl {
+ bool Mutable : 1;
QualType DeclType;
Expr *BitWidth;
protected:
- FieldDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
- Expr *BW = NULL)
- : NamedDecl(DK, L, Id), DeclType(T), BitWidth(BW) {}
- FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *BW)
- : NamedDecl(Field, L, Id), DeclType(T), BitWidth(BW) {}
+ FieldDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ IdentifierInfo *Id, QualType T, Expr *BW, bool Mutable,
+ ScopedDecl *PrevDecl)
+ : ScopedDecl(DK, DC, L, Id, PrevDecl), Mutable(Mutable), DeclType(T),
+ BitWidth(BW)
+ { }
+
public:
- static FieldDecl *Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id,
- QualType T, Expr *BW = NULL);
+ static FieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+ IdentifierInfo *Id, QualType T, Expr *BW,
+ bool Mutable, ScopedDecl *PrevDecl);
QualType getType() const { return DeclType; }
-
+
+ /// isMutable - Determines whether this field is mutable (C++ only).
+ bool isMutable() const { return Mutable; }
+
+ /// isBitfield - Determines whether this field is a bitfield.
bool isBitField() const { return BitWidth != NULL; }
+
Expr *getBitWidth() const { return BitWidth; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
@@ -888,9 +888,6 @@ protected:
/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
/// enums.
class EnumDecl : public TagDecl, public DeclContext {
- // 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.
@@ -908,30 +905,46 @@ public:
virtual void Destroy(ASTContext& C);
- /// defineElements - When created, EnumDecl correspond to a forward declared
- /// enum. This method is used to mark the decl as being defined, with the
- /// specified list of enums.
- void defineElements(EnumConstantDecl *ListHead, QualType NewType) {
- assert(!isDefinition() && "Cannot redefine enums!");
- setDeclChain(ListHead);
- setDefinition(true);
-
- IntegerType = NewType;
- }
+ /// completeDefinition - When created, the EnumDecl corresponds to a
+ /// forward-declared enum. This method is used to mark the
+ /// declaration as being defined; it's enumerators have already been
+ /// added (via DeclContext::addDecl). NewType is the new underlying
+ /// type of the enumeration type.
+ void completeDefinition(ASTContext &C, QualType NewType);
+ // enumerator_iterator - Iterates through the enumerators of this
+ // enumeration.
+ struct enumerator_iterator : public DeclContext::decl_iterator {
+ typedef EnumConstantDecl* value_type;
+ typedef EnumConstantDecl* reference;
+ typedef EnumConstantDecl* pointer;
+
+ enumerator_iterator() : DeclContext::decl_iterator() { }
+
+ explicit enumerator_iterator(DeclContext::decl_iterator Pos)
+ : DeclContext::decl_iterator(Pos) { }
+
+ reference operator*() const {
+ return cast<EnumConstantDecl>(DeclContext::decl_iterator::operator*());
+ }
+
+ pointer operator->() const {
+ return cast<EnumConstantDecl>(DeclContext::decl_iterator::operator*());
+ }
+ };
+
+ enumerator_iterator enumerator_begin() const {
+ return enumerator_iterator(this->decls_begin());
+ }
+
+ enumerator_iterator enumerator_end() const {
+ return enumerator_iterator(this->decls_end());
+ }
+
/// getIntegerType - Return the integer type this enum decl corresponds to.
/// This returns a null qualtype for an enum forward definition.
QualType getIntegerType() const { return IntegerType; }
-
- /// getEnumConstantList - Return the first EnumConstantDecl in the enum.
- ///
- 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; }
static DeclContext *castToDeclContext(const EnumDecl *D) {
@@ -957,16 +970,12 @@ protected:
/// union Y { int A, B; }; // Has body with members A and B (FieldDecls).
/// This decl will be marked invalid if *any* members are invalid.
///
-class RecordDecl : public TagDecl {
+class RecordDecl : public TagDecl, public DeclContext {
/// HasFlexibleArrayMember - This is true if this struct ends with a flexible
/// array member (e.g. int X[]) or if this union contains a struct that does.
/// If so, this cannot be contained in arrays or other structs as a member.
bool HasFlexibleArrayMember : 1;
- /// Members/NumMembers - This is a new[]'d array of pointers to Decls.
- FieldDecl **Members; // Null if not defined.
- int NumMembers; // -1 if not defined.
-
protected:
RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id);
@@ -993,42 +1002,74 @@ public:
return cast_or_null<RecordDecl>(TagDecl::getDefinition(C));
}
- /// getNumMembers - Return the number of members, or -1 if this is a forward
- /// definition.
- int getNumMembers() const { return NumMembers; }
- const FieldDecl *getMember(unsigned i) const { return Members[i]; }
- FieldDecl *getMember(unsigned i) { return Members[i]; }
-
// Iterator access to field members.
- typedef FieldDecl **field_iterator;
- typedef FieldDecl * const *field_const_iterator;
+ class field_iterator {
+ /// Current - Current position within the sequence of declarations
+ /// in this record.
+ DeclContext::decl_iterator Current;
+
+ /// End - Last position in the sequence of declarations in this
+ /// record.
+ DeclContext::decl_iterator End;
+
+ /// SkipToNextField - Advances the current position up to the next
+ /// FieldDecl.
+ void SkipToNextField() {
+ while (Current != End && !isa<FieldDecl>(*Current))
+ ++Current;
+ }
- field_iterator field_begin() {
- assert(isDefinition() && "Not a definition!");
- return Members;
- }
- field_iterator field_end() {
- assert(isDefinition() && "Not a definition!");
- return Members + getNumMembers();
- }
+ public:
+ typedef FieldDecl* value_type;
+ typedef FieldDecl* reference;
+ typedef FieldDecl* pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ field_iterator() : Current(), End() { }
+
+ field_iterator(DeclContext::decl_iterator C, DeclContext::decl_iterator E)
+ : Current(C), End(E) {
+ SkipToNextField();
+ }
+
+ reference operator*() const { return cast<FieldDecl>(*Current); }
- field_const_iterator field_begin() const {
- assert(isDefinition() && "Not a definition!");
- return Members;
+ pointer operator->() const { return cast<FieldDecl>(*Current); }
+
+ field_iterator& operator++() {
+ ++Current;
+ SkipToNextField();
+ return *this;
+ }
+
+ field_iterator operator++(int) {
+ field_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ friend bool operator==(const field_iterator& x, const field_iterator& y) {
+ return x.Current == y.Current;
+ }
+
+ friend bool operator!=(const field_iterator& x, const field_iterator& y) {
+ return x.Current != y.Current;
+ }
+ };
+
+ typedef field_iterator field_const_iterator;
+
+ field_iterator field_begin() const {
+ return field_iterator(decls_begin(), decls_end());
}
- field_const_iterator field_end() const {
- assert(isDefinition() && "Not a definition!");
- return Members + getNumMembers();
+ field_iterator field_end() const {
+ return field_iterator(decls_end(), decls_end());
}
- /// defineBody - When created, RecordDecl's correspond to a forward declared
- /// record. This method is used to mark the decl as being defined, with the
- /// specified contents.
- void defineBody(ASTContext& C, FieldDecl **Members, unsigned numMembers);
-
- /// getMember - If the member doesn't exist, or there are no members, this
- /// function will return 0;
- FieldDecl *getMember(IdentifierInfo *name);
+ /// completeDefinition - Notes that the definition of this type is
+ /// now complete.
+ void completeDefinition(ASTContext& C);
static bool classof(const Decl *D) {
return D->getKind() >= RecordFirst && D->getKind() <= RecordLast;
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 55919da54e..badf6345ec 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -17,11 +17,14 @@
#include "clang/AST/Attr.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include <vector>
namespace clang {
class DeclContext;
class TranslationUnitDecl;
class NamespaceDecl;
+class NamedDecl;
class ScopedDecl;
class FunctionDecl;
class CXXRecordDecl;
@@ -29,6 +32,7 @@ class EnumDecl;
class ObjCMethodDecl;
class ObjCInterfaceDecl;
class BlockDecl;
+class DeclarationName;
/// Decl - This represents one declaration (or definition), e.g. a variable,
/// typedef, function, struct, etc.
@@ -44,10 +48,6 @@ public:
// Decl
TranslationUnit, // [DeclContext]
// NamedDecl
- Field,
- CXXField,
- ObjCIvar,
- ObjCAtDefsField,
OverloadedFunction,
ObjCCategory,
ObjCCategoryImpl,
@@ -56,13 +56,16 @@ public:
ObjCProtocol,
ObjCProperty,
// ScopedDecl
+ Field,
+ ObjCIvar,
+ ObjCAtDefsField,
Namespace, // [DeclContext]
// TypeDecl
Typedef,
// TagDecl
Enum, // [DeclContext]
- Record,
- CXXRecord, // [DeclContext]
+ Record, // [DeclContext]
+ CXXRecord,
TemplateTypeParm,
// ValueDecl
EnumConstant,
@@ -87,9 +90,9 @@ public:
// For each non-leaf class, we now define a mapping to the first/last member
// of the class, to allow efficient classof.
- NamedFirst = Field , NamedLast = NonTypeTemplateParm,
+ NamedFirst = OverloadedFunction , NamedLast = NonTypeTemplateParm,
FieldFirst = Field , FieldLast = ObjCAtDefsField,
- ScopedFirst = Namespace , ScopedLast = NonTypeTemplateParm,
+ ScopedFirst = Field , ScopedLast = NonTypeTemplateParm,
TypeFirst = Typedef , TypeLast = TemplateTypeParm,
TagFirst = Enum , TagLast = CXXRecord,
RecordFirst = Record , RecordLast = CXXRecord,
@@ -183,10 +186,10 @@ public:
case ParmVar:
case EnumConstant:
case NonTypeTemplateParm:
+ case Field:
case ObjCInterface:
case ObjCCompatibleAlias:
case OverloadedFunction:
- case CXXField:
case CXXMethod:
case CXXConversion:
case CXXClassVar:
@@ -247,7 +250,7 @@ protected:
/// TranslationUnitDecl
/// NamespaceDecl
/// FunctionDecl
-/// CXXRecordDecl
+/// RecordDecl/CXXRecordDecl
/// EnumDecl
/// ObjCMethodDecl
/// ObjCInterfaceDecl
@@ -257,9 +260,26 @@ 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;
+ /// LookupPtrKind - Describes what kind of pointer LookupPtr
+ /// actually is.
+ enum LookupPtrKind {
+ /// LookupIsMap - Indicates that LookupPtr is actually a
+ /// DenseMap<DeclarationName, TwoNamedDecls> pointer.
+ LookupIsMap = 7
+ };
+
+ /// LookupPtr - Pointer to a data structure used to lookup
+ /// declarations within this context. If the context contains fewer
+ /// than seven declarations, the number of declarations is provided
+ /// in the 3 lowest-order bits and the upper bits are treated as a
+ /// pointer to an array of NamedDecl pointers. If the context
+ /// contains seven or more declarations, the upper bits are treated
+ /// as a pointer to a DenseMap<DeclarationName, TwoNamedDecls>.
+ llvm::PointerIntPair<void*, 3> LookupPtr;
+
+ /// Decls - Contains all of the declarations that are defined inside
+ /// this declaration context.
+ std::vector<ScopedDecl*> Decls;
// Used in the CastTo template to get the DeclKind
// from a Decl or a DeclContext. DeclContext doesn't have a getKind() method
@@ -281,6 +301,8 @@ class DeclContext {
return static_cast<NamespaceDecl*>(const_cast<From*>(D));
case Decl::Enum:
return static_cast<EnumDecl*>(const_cast<From*>(D));
+ case Decl::Record:
+ return static_cast<RecordDecl*>(const_cast<From*>(D));
case Decl::CXXRecord:
return static_cast<CXXRecordDecl*>(const_cast<From*>(D));
case Decl::ObjCMethod:
@@ -296,10 +318,19 @@ class DeclContext {
}
}
+ /// isLookupMap - Determine if the lookup structure is a
+ /// DenseMap. Othewise, it is an array.
+ bool isLookupMap() const { return LookupPtr.getInt() == LookupIsMap; }
+
protected:
- DeclContext(Decl::Kind K) : DeclKind(K), DeclChain(0) {}
+ DeclContext(Decl::Kind K) : DeclKind(K), LookupPtr() {
+ }
+
+ void DestroyDecls(ASTContext &C);
public:
+ ~DeclContext();
+
/// getParent - Returns the containing DeclContext if this is a ScopedDecl,
/// else returns NULL.
const DeclContext *getParent() const;
@@ -309,12 +340,12 @@ public:
}
/// getLexicalParent - Returns the containing lexical DeclContext. May be
- /// different from getParent, e.g.:
- ///
- /// namespace A {
- /// struct S;
- /// }
- /// struct A::S {}; // getParent() == namespace 'A'
+ /// different from getParent, e.g.:
+ ///
+ /// namespace A {
+ /// struct S;
+ /// }
+ /// struct A::S {}; // getParent() == namespace 'A'
/// // getLexicalParent() == translation unit
///
const DeclContext *getLexicalParent() const;
@@ -326,11 +357,12 @@ public:
bool isFunctionOrMethod() const {
switch (DeclKind) {
case Decl::Block:
- case Decl::Function:
- case Decl::CXXMethod:
case Decl::ObjCMethod:
return true;
+
default:
+ if (DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast)
+ return true;
return false;
}
}
@@ -343,6 +375,10 @@ public:
return DeclKind == Decl::CXXRecord;
}
+ bool isNamespace() const {
+ return DeclKind == Decl::Namespace;
+ }
+
bool Encloses(DeclContext *DC) const {
for (; DC; DC = DC->getParent())
if (DC == this)
@@ -350,15 +386,105 @@ public:
return false;
}
- const ScopedDecl *getDeclChain() const { return DeclChain; }
- ScopedDecl *getDeclChain() { return DeclChain; }
- void setDeclChain(ScopedDecl *D) { DeclChain = D; }
+ /// getPrimaryContext - There may be many different
+ /// declarations of the same entity (including forward declarations
+ /// of classes, multiple definitions of namespaces, etc.), each with
+ /// a different set of declarations. This routine returns the
+ /// "primary" DeclContext structure, which will contain the
+ /// information needed to perform name lookup into this context.
+ DeclContext *getPrimaryContext(ASTContext &Context);
+
+ /// getNextContext - If this is a DeclContext that may have other
+ /// DeclContexts that are semantically connected but syntactically
+ /// different, such as C++ namespaces, this routine retrieves the
+ /// next DeclContext in the link. Iteration through the chain of
+ /// DeclContexts should begin at the primary DeclContext and
+ /// continue until this function returns NULL. For example, given:
+ /// @code
+ /// namespace N {
+ /// int x;
+ /// }
+ /// namespace N {
+ /// int y;
+ /// }
+ /// @endcode
+ /// The first occurrence of namespace N will be the primary
+ /// DeclContext. Its getNextContext will return the second
+ /// occurrence of namespace N.
+ DeclContext *getNextContext();
+
+ /// decl_iterator - Iterates through the declarations stored
+ /// within this context.
+ typedef std::vector<ScopedDecl*>::const_iterator decl_iterator;
+
+ /// reverse_decl_iterator - Iterates through the declarations stored
+ /// within this context in reverse order.
+ typedef std::vector<ScopedDecl*>::const_reverse_iterator
+ reverse_decl_iterator;
+
+ /// decls_begin/decls_end - Iterate over the declarations stored in
+ /// this context.
+ decl_iterator decls_begin() const { return Decls.begin(); }
+ decl_iterator decls_end() const { return Decls.end(); }
+
+ /// decls_rbegin/decls_rend - Iterate over the declarations stored
+ /// in this context in reverse order.
+ reverse_decl_iterator decls_rbegin() const { return Decls.rbegin(); }
+ reverse_decl_iterator decls_rend() const { return Decls.rend(); }
+
+ /// addDecl - Add the declaration D to this scope. Note that
+ /// declarations are added at the beginning of the declaration
+ /// chain, so reverseDeclChain() should be called after all
+ /// declarations have been added. If AllowLookup, also adds this
+ /// declaration into data structure for name lookup.
+ void addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup = true);
+
+ /// reverseDeclChain - Reverse the chain of declarations stored in
+ /// this scope. Typically called once after all declarations have
+ /// been added and the scope is closed.
+ void reverseDeclChain();
+
+ /// lookup_iterator - An iterator that provides access to the results
+ /// of looking up a name within this context.
+ typedef NamedDecl **lookup_iterator;
+
+ /// lookup_const_iterator - An iterator that provides non-mutable
+ /// access to the results of lookup up a name within this context.
+ typedef NamedDecl * const * lookup_const_iterator;
+
+ typedef std::pair<lookup_iterator, lookup_iterator> lookup_result;
+ typedef std::pair<lookup_const_iterator, lookup_const_iterator>
+ lookup_const_result;
+
+ /// lookup - Find the declarations (if any) with the given Name in
+ /// this context. Returns a range of iterators that contains all of
+ /// the declarations with this name (which may be 0, 1, or 2
+ /// declarations). If two declarations are returned, the declaration
+ /// in the "ordinary" identifier namespace will precede the
+ /// declaration in the "tag" identifier namespace (e.g., values
+ /// before types). Note that this routine will not look into parent
+ /// contexts.
+ lookup_result lookup(ASTContext &Context, DeclarationName Name);
+ lookup_const_result