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 | 250ffb1fcb79ee8783e3c42f3232e6700dee36b8 (patch) | |
| tree | d34d0d7da729cd345da1d6c1b1733364a616f13a /clang/lib/Serialization | |
| parent | 930e3ad51e23e6ef29657d607173faf3e0e2b7b8 (diff) | |
| download | bcm5719-llvm-250ffb1fcb79ee8783e3c42f3232e6700dee36b8.tar.gz bcm5719-llvm-250ffb1fcb79ee8783e3c42f3232e6700dee36b8.zip | |
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).
llvm-svn: 127056
Diffstat (limited to 'clang/lib/Serialization')
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 1e4ff83d5fc..a49f909c6f0 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/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 |

