Support a couple more C++ Exprs for PCH.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106727 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Argyrios Kyrtzidis 2010-06-24 08:57:31 +00:00
Родитель 5e1b7c2f41
Коммит 8dfbd8b252
11 изменённых файлов: 216 добавлений и 11 удалений

Просмотреть файл

@ -414,6 +414,7 @@ struct ExplicitTemplateArgumentList {
void initializeFrom(const TemplateArgumentListInfo &List);
void copyInto(TemplateArgumentListInfo &List) const;
static std::size_t sizeFor(unsigned NumTemplateArgs);
static std::size_t sizeFor(const TemplateArgumentListInfo &List);
};

Просмотреть файл

@ -1800,6 +1800,9 @@ class CXXUnresolvedConstructExpr : public Expr {
unsigned NumArgs,
SourceLocation RParenLoc);
CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
: Expr(CXXUnresolvedConstructExprClass, Empty), NumArgs(NumArgs) { }
public:
static CXXUnresolvedConstructExpr *Create(ASTContext &C,
SourceLocation TyBegin,
@ -1809,6 +1812,9 @@ public:
unsigned NumArgs,
SourceLocation RParenLoc);
static CXXUnresolvedConstructExpr *CreateEmpty(ASTContext &C,
unsigned NumArgs);
/// \brief Retrieve the source location where the type begins.
SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
@ -1853,6 +1859,11 @@ public:
return *(arg_begin() + I);
}
void setArg(unsigned I, Expr *E) {
assert(I < NumArgs && "Argument index out-of-range");
*(arg_begin() + I) = E;
}
virtual SourceRange getSourceRange() const {
return SourceRange(TyBeginLoc, RParenLoc);
}
@ -1968,6 +1979,9 @@ public:
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs);
static CXXDependentScopeMemberExpr *
CreateEmpty(ASTContext &C, unsigned NumTemplateArgs);
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
@ -1982,6 +1996,7 @@ public:
void setBase(Expr *E) { Base = E; }
QualType getBaseType() const { return BaseType; }
void setBaseType(QualType T) { BaseType = T; }
/// \brief Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
@ -1995,10 +2010,12 @@ public:
/// \brief Retrieve the nested-name-specifier that qualifies the member
/// name.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
/// \brief Retrieve the source range covering the nested-name-specifier
/// that qualifies the member name.
SourceRange getQualifierRange() const { return QualifierRange; }
void setQualifierRange(SourceRange R) { QualifierRange = R; }
/// \brief Retrieve the first part of the nested-name-specifier that was
/// found in the scope of the member access expression when the member access
@ -2014,6 +2031,9 @@ public:
NamedDecl *getFirstQualifierFoundInScope() const {
return FirstQualifierFoundInScope;
}
void setFirstQualifierFoundInScope(NamedDecl *D) {
FirstQualifierFoundInScope = D;
}
/// \brief Retrieve the name of the member that this expression
/// refers to.
@ -2038,6 +2058,12 @@ public:
getExplicitTemplateArgumentList()->copyInto(List);
}
/// \brief Initializes the template arguments using the given structure.
void initializeTemplateArgumentsFrom(const TemplateArgumentListInfo &List) {
assert(HasExplicitTemplateArgs);
getExplicitTemplateArgumentList()->initializeFrom(List);
}
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
SourceLocation getLAngleLoc() const {

Просмотреть файл

@ -421,7 +421,9 @@ namespace clang {
/// \brief An TemplateTypeParmType record.
TYPE_TEMPLATE_TYPE_PARM = 29,
/// \brief An TemplateSpecializationType record.
TYPE_TEMPLATE_SPECIALIZATION = 30
TYPE_TEMPLATE_SPECIALIZATION = 30,
/// \brief An DependentNameType record.
TYPE_DEPENDENT_NAME = 31
};
/// \brief The type IDs for special types constructed by semantic
@ -765,7 +767,10 @@ namespace clang {
EXPR_CXX_NEW, // CXXNewExpr
EXPR_CXX_DELETE, // CXXDeleteExpr
EXPR_CXX_EXPR_WITH_TEMPORARIES // CXXExprWithTemporaries
EXPR_CXX_EXPR_WITH_TEMPORARIES, // CXXExprWithTemporaries
EXPR_CXX_DEPENDENT_SCOPE_MEMBER, // CXXDependentScopeMemberExpr
EXPR_CXX_UNRESOLVED_CONSTRUCT // CXXUnresolvedConstructExpr
};
/// \brief The kinds of designators that can occur in a

Просмотреть файл

@ -113,10 +113,14 @@ void ExplicitTemplateArgumentList::copyInto(
Info.addArgument(getTemplateArgs()[I]);
}
std::size_t ExplicitTemplateArgumentList::sizeFor(unsigned NumTemplateArgs) {
return sizeof(ExplicitTemplateArgumentList) +
sizeof(TemplateArgumentLoc) * NumTemplateArgs;
}
std::size_t ExplicitTemplateArgumentList::sizeFor(
const TemplateArgumentListInfo &Info) {
return sizeof(ExplicitTemplateArgumentList) +
sizeof(TemplateArgumentLoc) * Info.size();
return sizeFor(Info.size());
}
void DeclRefExpr::computeDependence() {

Просмотреть файл

@ -656,6 +656,14 @@ CXXUnresolvedConstructExpr::Create(ASTContext &C,
Args, NumArgs, RParenLoc);
}
CXXUnresolvedConstructExpr *
CXXUnresolvedConstructExpr::CreateEmpty(ASTContext &C, unsigned NumArgs) {
Stmt::EmptyShell Empty;
void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
sizeof(Expr *) * NumArgs);
return new (Mem) CXXUnresolvedConstructExpr(Empty, NumArgs);
}
Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
return child_iterator(reinterpret_cast<Stmt **>(this + 1));
}
@ -714,6 +722,29 @@ CXXDependentScopeMemberExpr::Create(ASTContext &C,
Member, MemberLoc, TemplateArgs);
}
CXXDependentScopeMemberExpr *
CXXDependentScopeMemberExpr::CreateEmpty(ASTContext &C,
unsigned NumTemplateArgs) {
if (NumTemplateArgs == 0)
return new (C) CXXDependentScopeMemberExpr(C, 0, QualType(),
0, SourceLocation(), 0,
SourceRange(), 0,
DeclarationName(),
SourceLocation());
std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
CXXDependentScopeMemberExpr *E
= new (Mem) CXXDependentScopeMemberExpr(C, 0, QualType(),
0, SourceLocation(), 0,
SourceRange(), 0,
DeclarationName(),
SourceLocation(), 0);
E->HasExplicitTemplateArgs = true;
return E;
}
Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
return child_iterator(&Base);
}

Просмотреть файл

@ -2216,6 +2216,14 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
IdentifierInfo *Name = GetIdentifierInfo(Record, Idx);
return Context->getTemplateTypeParmType(Depth, Index, Pack, Name);
}
case pch::TYPE_DEPENDENT_NAME: {
unsigned Idx = 0;
ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
return Context->getDependentNameType(Keyword, NNS, Name, QualType());
}
case pch::TYPE_TEMPLATE_SPECIALIZATION: {
unsigned Idx = 0;

Просмотреть файл

@ -137,6 +137,9 @@ namespace {
unsigned VisitCXXDeleteExpr(CXXDeleteExpr *E);
unsigned VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
unsigned VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
unsigned VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
};
}
@ -1114,6 +1117,50 @@ unsigned PCHStmtReader::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
return 1;
}
unsigned
PCHStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
VisitExpr(E);
unsigned NumTemplateArgs = Record[Idx++];
assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
"Read wrong record during creation ?");
if (E->hasExplicitTemplateArgs()) {
TemplateArgumentListInfo ArgInfo;
ArgInfo.setLAngleLoc(Reader.ReadSourceLocation(Record, Idx));
ArgInfo.setRAngleLoc(Reader.ReadSourceLocation(Record, Idx));
for (unsigned i = 0; i != NumTemplateArgs; ++i)
ArgInfo.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx));
E->initializeTemplateArgumentsFrom(ArgInfo);
}
E->setBase(cast_or_null<Expr>(StmtStack.back()));
E->setBaseType(Reader.GetType(Record[Idx++]));
E->setArrow(Record[Idx++]);
E->setOperatorLoc(Reader.ReadSourceLocation(Record, Idx));
E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
E->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
E->setFirstQualifierFoundInScope(
cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++])));
E->setMember(Reader.ReadDeclarationName(Record, Idx));
E->setMemberLoc(Reader.ReadSourceLocation(Record, Idx));
return 1;
}
unsigned
PCHStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
VisitExpr(E);
assert(Record[Idx] == E->arg_size() && "Read wrong record during creation ?");
++Idx; // NumArgs;
for (unsigned I = 0, N = E->arg_size(); I != N; ++I)
E->setArg(I, cast<Expr>(StmtStack[StmtStack.size() - N + I]));
E->setTypeBeginLoc(Reader.ReadSourceLocation(Record, Idx));
E->setTypeAsWritten(Reader.GetType(Record[Idx++]));
E->setLParenLoc(Reader.ReadSourceLocation(Record, Idx));
E->setRParenLoc(Reader.ReadSourceLocation(Record, Idx));
return E->arg_size();
}
// Within the bitstream, expressions are stored in Reverse Polish
// Notation, with each of the subexpressions preceding the
@ -1493,10 +1540,19 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
S = new (Context) CXXDeleteExpr(Empty);
break;
case pch::EXPR_CXX_EXPR_WITH_TEMPORARIES:
S = new (Context) CXXExprWithTemporaries(Empty);
break;
case pch::EXPR_CXX_DEPENDENT_SCOPE_MEMBER:
S = CXXDependentScopeMemberExpr::CreateEmpty(*Context,
Record[PCHStmtReader::NumExprFields]);
break;
case pch::EXPR_CXX_UNRESOLVED_CONSTRUCT:
S = CXXUnresolvedConstructExpr::CreateEmpty(*Context,
Record[PCHStmtReader::NumExprFields]);
break;
}
// We hit a STMT_STOP, so we're done with this expression.

Просмотреть файл

@ -252,8 +252,10 @@ PCHTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
void
PCHTypeWriter::VisitDependentNameType(const DependentNameType *T) {
// FIXME: Serialize this type (C++ only)
assert(false && "Cannot serialize dependent name types");
Record.push_back(T->getKeyword());
Writer.AddNestedNameSpecifier(T->getQualifier(), Record);
Writer.AddIdentifierRef(T->getIdentifier(), Record);
Code = pch::TYPE_DEPENDENT_NAME;
}
void

Просмотреть файл

@ -127,12 +127,14 @@ namespace {
void VisitCXXThrowExpr(CXXThrowExpr *E);
void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
void VisitCXXNewExpr(CXXNewExpr *E);
void VisitCXXDeleteExpr(CXXDeleteExpr *E);
void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
};
}
@ -1019,6 +1021,50 @@ void PCHStmtWriter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
Code = pch::EXPR_CXX_EXPR_WITH_TEMPORARIES;
}
void
PCHStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
VisitExpr(E);
if (E->hasExplicitTemplateArgs()) {
assert(E->getNumTemplateArgs() &&
"Num of template args was zero! PCH reading will mess up!");
Record.push_back(E->getNumTemplateArgs());
Writer.AddSourceLocation(E->getLAngleLoc(), Record);
Writer.AddSourceLocation(E->getRAngleLoc(), Record);
for (int i=0, e = E->getNumTemplateArgs(); i != e; ++i)
Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
} else {
Record.push_back(0);
}
if (!E->isImplicitAccess())
Writer.WriteSubStmt(E->getBase());
else
Writer.WriteSubStmt(0);
Writer.AddTypeRef(E->getBaseType(), Record);
Record.push_back(E->isArrow());
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
Writer.AddSourceRange(E->getQualifierRange(), Record);
Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record);
Writer.AddDeclarationName(E->getMember(), Record);
Writer.AddSourceLocation(E->getMemberLoc(), Record);
Code = pch::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
}
void
PCHStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
VisitExpr(E);
Record.push_back(E->arg_size());
for (CXXUnresolvedConstructExpr::arg_iterator
ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
Writer.WriteSubStmt(*ArgI);
Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
Writer.AddTypeRef(E->getTypeAsWritten(), Record);
Writer.AddSourceLocation(E->getLParenLoc(), Record);
Writer.AddSourceLocation(E->getRParenLoc(), Record);
Code = pch::EXPR_CXX_UNRESOLVED_CONSTRUCT;
}
//===----------------------------------------------------------------------===//
// PCHWriter Implementation

Просмотреть файл

@ -1,9 +1,16 @@
// Test this without pch.
// RUN: %clang_cc1 -include %S/cxx-templates.h -fsyntax-only -verify %s
// RUN: %clang_cc1 -include %S/cxx-templates.h -verify %s -ast-dump
// Test with pch.
// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-templates.h
// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s
// RUN: %clang_cc1 -include-pch %t -verify %s -ast-dump
struct A {
typedef int type;
static void my_f();
template <typename T>
static T my_templf(T x) { return x; }
};
void test() {
int x = templ_f(3);
@ -11,4 +18,8 @@ void test() {
S<char, float>::templ();
S<int, char>::partial();
S<int, float>::explicit_special();
Dep<A>::Ty ty;
Dep<A> a;
a.f();
}

Просмотреть файл

@ -19,3 +19,18 @@ template <typename T>
T templ_f(T x) {
return x;
}
template <typename T>
struct Dep {
typedef typename T::type Ty;
void f() {
Ty x = Ty();
T::my_f();
int y = T::template my_templf<int>(0);
}
};
template<typename T, typename A1>
inline T make_a(const A1& a1) {
return T(a1);
}