diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-03-05 01:35:54 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-03-05 01:35:54 +0000 |
commit | 67da6f6f0c20dbfebb1c383a3efaf85d925ad33e (patch) | |
tree | 311c0f10a746fc0b89ba7cb7b63d54ad0d37b32a /lib/Serialization/ASTReaderDecl.cpp | |
parent | b1c86492f9a9bef01a4567408c22f961bbd604fe (diff) |
When we're deserializing a template parameter declaration, temporarily
use the translation unit as its declaration context, then deserialize
the actual lexical and semantic DeclContexts after the template
parameter is complete. This avoids problems when the DeclContext
itself (e.g., a class template) is dependent on the template parameter
(e.g., for the injected-class-name).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127056 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 1e4ff83d5f..a49f909c6f 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -38,6 +38,9 @@ namespace clang { const RecordData &Record; unsigned &Idx; TypeID TypeIDForTypeDecl; + + DeclID DeclContextIDForTemplateParmDecl; + DeclID LexicalDeclContextIDForTemplateParmDecl; uint64_t GetCurrentCursorOffset(); SourceLocation ReadSourceLocation(const RecordData &R, unsigned &I) { @@ -175,13 +178,32 @@ void ASTDeclReader::Visit(Decl *D) { // FunctionDecl's body was written last after all other Stmts/Exprs. if (Record[Idx++]) FD->setLazyBody(GetCurrentCursorOffset()); + } else if (D->isTemplateParameter()) { + // If we have a fully initialized template parameter, we can now + // set its DeclContext. + D->setDeclContext( + cast_or_null<DeclContext>( + Reader.GetDecl(DeclContextIDForTemplateParmDecl))); + D->setLexicalDeclContext( + cast_or_null<DeclContext>( + Reader.GetDecl(LexicalDeclContextIDForTemplateParmDecl))); } } void ASTDeclReader::VisitDecl(Decl *D) { - D->setDeclContext(cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++]))); - D->setLexicalDeclContext( + if (D->isTemplateParameter()) { + // We don't want to deserialize the DeclContext of a template + // parameter immediately, because the template parameter might be + // used in the formulation of its DeclContext. Use the translation + // unit DeclContext as a placeholder. + DeclContextIDForTemplateParmDecl = Record[Idx++]; + LexicalDeclContextIDForTemplateParmDecl = Record[Idx++]; + D->setDeclContext(Reader.getContext()->getTranslationUnitDecl()); + } else { + D->setDeclContext(cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++]))); + D->setLexicalDeclContext( cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++]))); + } D->setLocation(ReadSourceLocation(Record, Idx)); D->setInvalidDecl(Record[Idx++]); if (Record[Idx++]) { // hasAttrs |