зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
5e1b7c2f41
Коммит
8dfbd8b252
|
@ -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);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче