forked from OSchip/llvm-project
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
This commit is contained in:
parent
930e3ad51e
commit
250ffb1fcb
|
@ -173,9 +173,6 @@ void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
|
|||
Decl::~Decl() { }
|
||||
|
||||
void Decl::setDeclContext(DeclContext *DC) {
|
||||
if (isOutOfSemaDC())
|
||||
delete getMultipleDC();
|
||||
|
||||
DeclCtx = DC;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -193,3 +193,15 @@ namespace ZeroLengthExplicitTemplateArgs {
|
|||
template<typename T> void g2(T);
|
||||
};
|
||||
}
|
||||
|
||||
namespace NonTypeTemplateParmContext {
|
||||
template<typename T, int inlineCapacity = 0> class Vector { };
|
||||
|
||||
struct String {
|
||||
template<int inlineCapacity>
|
||||
static String adopt(Vector<char, inlineCapacity>&);
|
||||
};
|
||||
|
||||
template<int inlineCapacity>
|
||||
inline bool equalIgnoringNullity(const Vector<char, inlineCapacity>& a, const String& b) { return false; }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue