diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-11-09 23:41:00 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-11-09 23:41:00 +0000 |
commit | 5239304ff761b8b03eefb772bd5d830a9b9f1aea (patch) | |
tree | 53033fe5ea5d74e5ba0656a854938755a05018ef /lib | |
parent | 0f84a23cc542a76f97aee735cdf3ff948b149879 (diff) |
Introduce ScopedDecl::getLexicalDeclContext() which is different from ScopedDecl::getDeclContext() when there are nested-names.
e.g.:
namespace A {
void f(); // SemanticDC (getDeclContext) == LexicalDC (getLexicalDeclContext) == 'namespace A'
}
void A::f(); // SemanticDC == namespace 'A'
// LexicalDC == global namespace
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58948 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Decl.cpp | 23 | ||||
-rw-r--r-- | lib/AST/DeclSerialization.cpp | 24 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 34 |
4 files changed, 64 insertions, 21 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index b0fe4d1b14..fa5e9ce36e 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -140,6 +140,29 @@ const char *NamedDecl::getName() const { } //===----------------------------------------------------------------------===// +// ScopedDecl Implementation +//===----------------------------------------------------------------------===// + +void ScopedDecl::setLexicalDeclContext(DeclContext *DC) { + if (DC == getLexicalDeclContext()) + return; + + if (isInSemaDC()) { + MultipleDC *MDC = new MultipleDC(); + MDC->SemanticDC = getDeclContext(); + MDC->LexicalDC = DC; + DeclCtx = reinterpret_cast<uintptr_t>(MDC) | 0x1; + } else { + getMultipleDC()->LexicalDC = DC; + } +} + +ScopedDecl::~ScopedDecl() { + if (isOutOfSemaDC()) + delete getMultipleDC(); +} + +//===----------------------------------------------------------------------===// // FunctionDecl Implementation //===----------------------------------------------------------------------===// diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp index 34066a5039..04cb71983b 100644 --- a/lib/AST/DeclSerialization.cpp +++ b/lib/AST/DeclSerialization.cpp @@ -145,15 +145,31 @@ void ScopedDecl::EmitInRec(Serializer& S) const { NamedDecl::EmitInRec(S); S.EmitPtr(getNext()); // From ScopedDecl. S.EmitPtr(cast_or_null<Decl>(getDeclContext())); // From ScopedDecl. + S.EmitPtr(cast_or_null<Decl>(getLexicalDeclContext())); // From ScopedDecl. } void ScopedDecl::ReadInRec(Deserializer& D, ASTContext& C) { NamedDecl::ReadInRec(D, C); D.ReadPtr(Next); // From ScopedDecl. - - assert(DeclCtx == 0); // Allow back-patching. Observe that we register - D.ReadPtr(DeclCtx); // the variable of the *object* for back-patching. - // Its actual value will get filled in later. + + assert(DeclCtx == 0); + + const SerializedPtrID &SemaDCPtrID = D.ReadPtrID(); + const SerializedPtrID &LexicalDCPtrID = D.ReadPtrID(); + + if (SemaDCPtrID == LexicalDCPtrID) { + // Allow back-patching. Observe that we register the variable of the + // *object* for back-patching. Its actual value will get filled in later. + D.ReadUIntPtr(DeclCtx, SemaDCPtrID); + } + else { + MultipleDC *MDC = new MultipleDC(); + DeclCtx = reinterpret_cast<uintptr_t>(MDC) | 0x1; + // Allow back-patching. Observe that we register the variable of the + // *object* for back-patching. Its actual value will get filled in later. + D.ReadUIntPtr(reinterpret_cast<uintptr_t&>(MDC->SemanticDC), SemaDCPtrID); + D.ReadUIntPtr(reinterpret_cast<uintptr_t&>(MDC->LexicalDC), LexicalDCPtrID); + } } //===------------------------------------------------------------===// diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 178ab13f16..d7518e0aa7 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -109,10 +109,6 @@ public: /// CurContext - This is the current declaration context of parsing. DeclContext *CurContext; - /// LexicalFileContext - The current lexical file declaration context, - /// the translation unit or a namespace. - DeclContext *LexicalFileContext; - /// PreDeclaratorDC - Keeps the declaration context before switching to the /// context of a declarator's nested-name-specifier. DeclContext *PreDeclaratorDC; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index cae05a365c..6c71d50895 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -53,8 +53,8 @@ std::string Sema::getTypeAsString(TypeTy *Type) { DeclContext *Sema::getContainingDC(DeclContext *DC) { if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC)) { // A C++ out-of-line method will return to the file declaration context. - if (!MD->isInlineDefinition()) - return LexicalFileContext; + if (MD->isOutOfLineDefinition()) + return MD->getLexicalDeclContext(); // A C++ inline method is parsed *after* the topmost class it was declared in // is fully parsed (it's "complete"). @@ -70,25 +70,24 @@ DeclContext *Sema::getContainingDC(DeclContext *DC) { return DC; } - if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) - return LexicalFileContext; + if (isa<ObjCMethodDecl>(DC)) + return Context.getTranslationUnitDecl(); + + if (ScopedDecl *SD = dyn_cast<ScopedDecl>(DC)) + return SD->getLexicalDeclContext(); return DC->getParent(); } void Sema::PushDeclContext(DeclContext *DC) { assert(getContainingDC(DC) == CurContext && - "The next DeclContext should be directly contained in the current one."); + "The next DeclContext should be lexically contained in the current one."); CurContext = DC; - if (CurContext->isFileContext()) - LexicalFileContext = CurContext; } void Sema::PopDeclContext() { assert(CurContext && "DeclContext imbalance!"); CurContext = getContainingDC(CurContext); - if (CurContext->isFileContext()) - LexicalFileContext = CurContext; } /// Add this decl to the scope shadowed decl chains. @@ -1147,6 +1146,10 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { New = NewVD; } + // Set the lexical context. If the declarator has a C++ scope specifier, the + // lexical context will be different from the semantic context. + New->setLexicalDeclContext(CurContext); + // If this has an identifier, add it to the scope stack. if (II) PushOnScopeChains(New, S); @@ -2004,10 +2007,6 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) { Diag(Definition->getLocation(), diag::err_previous_definition); } - if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) - if (isa<CXXRecordDecl>(CurContext)) - MD->setInlineDefinition(true); - PushDeclContext(FD); // Check the validity of our function parameters @@ -2267,6 +2266,11 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK, if (Attr) ProcessDeclAttributeList(New, Attr); + + // Set the lexical context. If the tag has a C++ scope specifier, the + // lexical context will be different from the semantic context. + New->setLexicalDeclContext(CurContext); + return New; } @@ -2421,6 +2425,10 @@ Sema::DeclTy *Sema::ActOnTagStruct(Scope *S, TagDecl::TagKind Kind, TagKind TK, if (Attr) ProcessDeclAttributeList(New, Attr); + // Set the lexical context. If the tag has a C++ scope specifier, the + // lexical context will be different from the semantic context. + New->setLexicalDeclContext(CurContext); + return New; } |