aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-10-23 18:54:35 +0000
committerDouglas Gregor <dgregor@apple.com>2009-10-23 18:54:35 +0000
commita2813cec2605ce7878d1b13471d685f689b251af (patch)
tree3b3af61e9b460df1ce059046243a2ce3f297400d /lib
parent7a1f4cc8d5ce5813d8def23d6ec9783cb2f4450b (diff)
Eliminate QualifiedDeclRefExpr, which captured the notion of a
qualified reference to a declaration that is not a non-static data member or non-static member function, e.g., namespace N { int i; } int j = N::i; Instead, extend DeclRefExpr to optionally store the qualifier. Most clients won't see or care about the difference (since QualifierDeclRefExpr inherited DeclRefExpr). However, this reduces the number of top-level expression types that clients need to cope with, brings the implementation of DeclRefExpr into line with MemberExpr, and simplifies and unifies our handling of declaration references. Extended DeclRefExpr to (optionally) store explicitly-specified template arguments. This occurs when naming a declaration via a template-id (which will be stored in a TemplateIdRefExpr) that, following template argument deduction and (possibly) overload resolution, is replaced with a DeclRefExpr that refers to a template specialization but maintains the template arguments as written. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84962 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Expr.cpp92
-rw-r--r--lib/AST/StmtPrinter.cpp14
-rw-r--r--lib/AST/StmtProfile.cpp7
-rw-r--r--lib/Analysis/GRExprEngine.cpp2
-rw-r--r--lib/CodeGen/CGExpr.cpp10
-rw-r--r--lib/CodeGen/CGExprAgg.cpp2
-rw-r--r--lib/CodeGen/CGExprConstant.cpp5
-rw-r--r--lib/CodeGen/CodeGenFunction.h2
-rw-r--r--lib/Frontend/PCHReaderStmt.cpp2
-rw-r--r--lib/Frontend/PCHWriterStmt.cpp2
-rw-r--r--lib/Sema/SemaChecking.cpp3
-rw-r--r--lib/Sema/SemaCodeComplete.cpp3
-rw-r--r--lib/Sema/SemaExpr.cpp50
-rw-r--r--lib/Sema/SemaOverload.cpp49
-rw-r--r--lib/Sema/SemaTemplate.cpp9
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp15
-rw-r--r--lib/Sema/TreeTransform.h84
17 files changed, 206 insertions, 145 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index a4de3e5b0f..47df95dc71 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -30,6 +30,91 @@ using namespace clang;
// Primary Expressions.
//===----------------------------------------------------------------------===//
+DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ NamedDecl *D, SourceLocation NameLoc,
+ bool HasExplicitTemplateArgumentList,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ SourceLocation RAngleLoc,
+ QualType T, bool TD, bool VD)
+ : Expr(DeclRefExprClass, T, TD, VD),
+ DecoratedD(D,
+ (Qualifier? HasQualifierFlag : 0) |
+ (HasExplicitTemplateArgumentList?
+ HasExplicitTemplateArgumentListFlag : 0)),
+ Loc(NameLoc) {
+ if (Qualifier) {
+ NameQualifier *NQ = getNameQualifier();
+ NQ->NNS = Qualifier;
+ NQ->Range = QualifierRange;
+ }
+
+ if (HasExplicitTemplateArgumentList) {
+ ExplicitTemplateArgumentList *ETemplateArgs
+ = getExplicitTemplateArgumentList();
+ ETemplateArgs->LAngleLoc = LAngleLoc;
+ ETemplateArgs->RAngleLoc = RAngleLoc;
+ ETemplateArgs->NumTemplateArgs = NumExplicitTemplateArgs;
+
+ TemplateArgument *TemplateArgs = ETemplateArgs->getTemplateArgs();
+ for (unsigned I = 0; I < NumExplicitTemplateArgs; ++I)
+ new (TemplateArgs + I) TemplateArgument(ExplicitTemplateArgs[I]);
+ }
+}
+
+DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ NamedDecl *D,
+ SourceLocation NameLoc,
+ QualType T, bool TD, bool VD) {
+ return Create(Context, Qualifier, QualifierRange, D, NameLoc,
+ false, SourceLocation(), 0, 0, SourceLocation(),
+ T, TD, VD);
+}
+
+DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ NamedDecl *D,
+ SourceLocation NameLoc,
+ bool HasExplicitTemplateArgumentList,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ SourceLocation RAngleLoc,
+ QualType T, bool TD, bool VD) {
+ std::size_t Size = sizeof(DeclRefExpr);
+ if (Qualifier != 0)
+ Size += sizeof(NameQualifier);
+
+ if (HasExplicitTemplateArgumentList)
+ Size += sizeof(ExplicitTemplateArgumentList) +
+ sizeof(TemplateArgument) * NumExplicitTemplateArgs;
+
+ void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
+ return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc,
+ HasExplicitTemplateArgumentList,
+ LAngleLoc,
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
+ RAngleLoc,
+ T, TD, VD);
+}
+
+SourceRange DeclRefExpr::getSourceRange() const {
+ // FIXME: Does not handle multi-token names well, e.g., operator[].
+ SourceRange R(Loc);
+
+ if (hasQualifier())
+ R.setBegin(getQualifierRange().getBegin());
+ if (hasExplicitTemplateArgumentList())
+ R.setEnd(getRAngleLoc());
+ return R;
+}
+
// FIXME: Maybe this should use DeclPrinter with a special "print predefined
// expr" policy instead.
std::string PredefinedExpr::ComputeName(ASTContext &Context, IdentType IT,
@@ -855,8 +940,7 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
if (cast<ArraySubscriptExpr>(this)->getBase()->getType()->isVectorType())
return cast<ArraySubscriptExpr>(this)->getBase()->isLvalue(Ctx);
return LV_Valid;
- case DeclRefExprClass:
- case QualifiedDeclRefExprClass: { // C99 6.5.1p2
+ case DeclRefExprClass: { // C99 6.5.1p2
const NamedDecl *RefdDecl = cast<DeclRefExpr>(this)->getDecl();
if (DeclCanBeLvalue(RefdDecl, Ctx))
return LV_Valid;
@@ -1133,8 +1217,7 @@ bool Expr::isOBJCGCCandidate(ASTContext &Ctx) const {
return cast<ImplicitCastExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx);
case CStyleCastExprClass:
return cast<CStyleCastExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx);
- case DeclRefExprClass:
- case QualifiedDeclRefExprClass: {
+ case DeclRefExprClass: {
const Decl *D = cast<DeclRefExpr>(this)->getDecl();
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (VD->hasGlobalStorage())
@@ -1432,7 +1515,6 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
return ICEDiag(2, E->getLocStart());
}
case Expr::DeclRefExprClass:
- case Expr::QualifiedDeclRefExprClass:
if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
return NoDiag();
if (Ctx.getLangOptions().CPlusPlus &&
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 2af19765df..4bd7f964be 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -473,14 +473,14 @@ void StmtPrinter::VisitExpr(Expr *Node) {
}
void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
+ if (NestedNameSpecifier *Qualifier = Node->getQualifier())
+ Qualifier->print(OS, Policy);
OS << Node->getDecl()->getNameAsString();
-}
-
-void StmtPrinter::VisitQualifiedDeclRefExpr(QualifiedDeclRefExpr *Node) {
- NamedDecl *D = Node->getDecl();
-
- Node->getQualifier()->print(OS, Policy);
- OS << D->getNameAsString();
+ if (Node->hasExplicitTemplateArgumentList())
+ OS << TemplateSpecializationType::PrintTemplateArgumentList(
+ Node->getTemplateArgs(),
+ Node->getNumTemplateArgs(),
+ Policy);
}
void StmtPrinter::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *Node) {
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index c4d42f6be2..a6327c9ea7 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -206,7 +206,9 @@ void StmtProfiler::VisitExpr(Expr *S) {
void StmtProfiler::VisitDeclRefExpr(DeclRefExpr *S) {
VisitExpr(S);
+ VisitNestedNameSpecifier(S->getQualifier());
VisitDecl(S->getDecl());
+ VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
}
void StmtProfiler::VisitPredefinedExpr(PredefinedExpr *S) {
@@ -521,11 +523,6 @@ void StmtProfiler::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *S) {
VisitType(S->getQueriedType());
}
-void StmtProfiler::VisitQualifiedDeclRefExpr(QualifiedDeclRefExpr *S) {
- VisitDeclRefExpr(S);
- VisitNestedNameSpecifier(S->getQualifier());
-}
-
void StmtProfiler::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *S) {
VisitExpr(S);
VisitName(S->getDeclName());
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index ea0255ded8..08e02feb08 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -409,7 +409,6 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
}
case Stmt::DeclRefExprClass:
- case Stmt::QualifiedDeclRefExprClass:
VisitDeclRefExpr(cast<DeclRefExpr>(S), Pred, Dst, false);
break;
@@ -522,7 +521,6 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
return;
case Stmt::DeclRefExprClass:
- case Stmt::QualifiedDeclRefExprClass:
VisitDeclRefExpr(cast<DeclRefExpr>(Ex), Pred, Dst, true);
return;
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index bb487f6e3f..ca0d4b7c60 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -245,7 +245,6 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
case Expr::VAArgExprClass:
return EmitVAArgExprLValue(cast<VAArgExpr>(E));
case Expr::DeclRefExprClass:
- case Expr::QualifiedDeclRefExprClass:
return EmitDeclRefLValue(cast<DeclRefExpr>(E));
case Expr::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
case Expr::PredefinedExprClass:
@@ -866,9 +865,9 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
llvm::Value *V = LocalDeclMap[IPD];
assert(V && "BlockVarDecl not entered in LocalDeclMap?");
return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
- } else if (const QualifiedDeclRefExpr *QDRExpr =
- dyn_cast<QualifiedDeclRefExpr>(E)) {
- return EmitPointerToDataMemberLValue(QDRExpr);
+ } else if (E->getQualifier()) {
+ // FIXME: the qualifier check does not seem sufficient here
+ return EmitPointerToDataMemberLValue(E);
}
assert(0 && "Unimp declref");
//an invalid LValue, but the assert will
@@ -1519,8 +1518,7 @@ LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) {
}
-LValue CodeGenFunction::EmitPointerToDataMemberLValue(
- const QualifiedDeclRefExpr *E) {
+LValue CodeGenFunction::EmitPointerToDataMemberLValue(const DeclRefExpr *E) {
const FieldDecl *Field = cast<FieldDecl>(E->getDecl());
const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Field->getDeclContext());
QualType NNSpecTy =
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index f47b6ab3c8..5f12d427cf 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -297,7 +297,7 @@ void AggExprEmitter::VisitUnaryAddrOf(const UnaryOperator *E) {
assert(MPT->getPointeeType()->isFunctionProtoType() &&
"Unexpected member pointer type!");
- const QualifiedDeclRefExpr *DRE = cast<QualifiedDeclRefExpr>(E->getSubExpr());
+ const DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr());
const CXXMethodDecl *MD = cast<CXXMethodDecl>(DRE->getDecl());
const llvm::Type *PtrDiffTy =
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index fc3748c8e3..f8923efd24 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -434,7 +434,7 @@ public:
E->getType()->getAs<MemberPointerType>()) {
QualType T = MPT->getPointeeType();
if (T->isFunctionProtoType()) {
- QualifiedDeclRefExpr *DRE = cast<QualifiedDeclRefExpr>(E->getSubExpr());
+ DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr());
return EmitMemberFunctionPointer(cast<CXXMethodDecl>(DRE->getDecl()));
}
@@ -739,8 +739,7 @@ public:
E->getType().getAddressSpace());
return C;
}
- case Expr::DeclRefExprClass:
- case Expr::QualifiedDeclRefExprClass: {
+ case Expr::DeclRefExprClass: {
NamedDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
return CGM.GetAddrOfFunction(FD);
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 639e683f03..f290571b7d 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -819,7 +819,7 @@ public:
LValue EmitConditionalOperatorLValue(const ConditionalOperator *E);
LValue EmitCastLValue(const CastExpr *E);
LValue EmitNullInitializationLValue(const CXXZeroInitValueExpr *E);
- LValue EmitPointerToDataMemberLValue(const QualifiedDeclRefExpr *E);
+ LValue EmitPointerToDataMemberLValue(const DeclRefExpr *E);
llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
const ObjCIvarDecl *Ivar);
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index 4b9496e00f..60f6d19600 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -347,6 +347,8 @@ unsigned PCHStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
VisitExpr(E);
E->setDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ // FIXME: read qualifier
+ // FIXME: read explicit template arguments
return 0;
}
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
index 9497f973f6..afed7fae58 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -314,6 +314,8 @@ void PCHStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
VisitExpr(E);
Writer.AddDeclRef(E->getDecl(), Record);
Writer.AddSourceLocation(E->getLocation(), Record);
+ // FIXME: write qualifier
+ // FIXME: write explicit template arguments
Code = pch::EXPR_DECL_REF;
}
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 589b0c6bd0..b7ccedec70 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -1420,8 +1420,7 @@ static DeclRefExpr* EvalVal(Expr *E) {
// viewed AST node. We then recursively traverse the AST by calling
// EvalAddr and EvalVal appropriately.
switch (E->getStmtClass()) {
- case Stmt::DeclRefExprClass:
- case Stmt::QualifiedDeclRefExprClass: {
+ case Stmt::DeclRefExprClass: {
// DeclRefExpr: the base case. When we hit a DeclRefExpr we are looking
// at code that refers to a variable's name. We check if it has local
// storage within the function, and if so, return the expression.
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 381151325a..b877b1cadb 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1171,8 +1171,7 @@ void Sema::CodeCompleteCase(Scope *S) {
// At the XXX, our completions are TagDecl::TK_union,
// TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
// TK_struct, and TK_class.
- if (QualifiedDeclRefExpr *QDRE = dyn_cast<QualifiedDeclRefExpr>(DRE))
- Qualifier = QDRE->getQualifier();
+ Qualifier = DRE->getQualifier();
}
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index ae45429952..accdc7e5c8 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -446,9 +446,7 @@ Sema::OwningExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
isAddressOfOperand);
}
-/// BuildDeclRefExpr - Build either a DeclRefExpr or a
-/// QualifiedDeclRefExpr based on whether or not SS is a
-/// nested-name-specifier.
+/// BuildDeclRefExpr - Build a DeclRefExpr.
Sema::OwningExprResult
Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
bool TypeDependent, bool ValueDependent,
@@ -476,15 +474,11 @@ Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
MarkDeclarationReferenced(Loc, D);
- Expr *E;
- if (SS && !SS->isEmpty()) {
- E = new (Context) QualifiedDeclRefExpr(D, Ty, Loc, TypeDependent,
- ValueDependent, SS->getRange(),
- static_cast<NestedNameSpecifier *>(SS->getScopeRep()));
- } else
- E = new (Context) DeclRefExpr(D, Ty, Loc, TypeDependent, ValueDependent);
-
- return Owned(E);
+ return Owned(DeclRefExpr::Create(Context,
+ SS? (NestedNameSpecifier *)SS->getScopeRep() : 0,
+ SS? SS->getRange() : SourceRange(),
+ D, Loc,
+ Ty, TypeDependent, ValueDependent));
}
/// getObjectForAnonymousRecordDecl - Retrieve the (unnamed) field or
@@ -2738,16 +2732,12 @@ void Sema::DeconstructCallFunction(Expr *FnExpr,
cast<UnaryOperator>(FnExpr)->getOpcode()
== UnaryOperator::AddrOf) {
FnExpr = cast<UnaryOperator>(FnExpr)->getSubExpr();
- } else if (QualifiedDeclRefExpr *QDRExpr
- = dyn_cast<QualifiedDeclRefExpr>(FnExpr)) {
- // Qualified names disable ADL (C++0x [basic.lookup.argdep]p1).
- ArgumentDependentLookup = false;
- Qualifier = QDRExpr->getQualifier();
- QualifierRange = QDRExpr->getQualifierRange();
- Function = dyn_cast<NamedDecl>(QDRExpr->getDecl());
- break;
} else if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(FnExpr)) {
Function = dyn_cast<NamedDecl>(DRExpr->getDecl());
+ if ((Qualifier = DRExpr->getQualifier())) {
+ ArgumentDependentLookup = false;
+ QualifierRange = DRExpr->getQualifierRange();
+ }
break;
} else if (UnresolvedFunctionNameExpr *DepName
= dyn_cast<UnresolvedFunctionNameExpr>(FnExpr)) {
@@ -2933,16 +2923,10 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
return ExprError();
// Update Fn to refer to the actual function selected.
- Expr *NewFn = 0;
- if (Qualifier)
- NewFn = new (Context) QualifiedDeclRefExpr(FDecl, FDecl->getType(),
- Fn->getLocStart(),
- false, false,
- QualifierRange,
- Qualifier);
- else
- NewFn = new (Context) DeclRefExpr(FDecl, FDecl->getType(),
- Fn->getLocStart());
+ // FIXME: Use FixOverloadedFunctionReference?
+ Expr *NewFn = DeclRefExpr::Create(Context, Qualifier, QualifierRange, FDecl,
+ Fn->getLocStart(), FDecl->getType(), false,
+ false);
Fn->Destroy(Context);
Fn = NewFn;
}
@@ -5083,7 +5067,6 @@ QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc,
static NamedDecl *getPrimaryDecl(Expr *E) {
switch (E->getStmtClass()) {
case Stmt::DeclRefExprClass:
- case Stmt::QualifiedDeclRefExprClass:
return cast<DeclRefExpr>(E)->getDecl();
case Stmt::MemberExprClass:
// If this is an arrow operator, the address is an offset from
@@ -5199,7 +5182,7 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
// Okay: we can take the address of a field.
// Could be a pointer to member, though, if there is an explicit
// scope qualifier for the class.
- if (isa<QualifiedDeclRefExpr>(op)) {
+ if (isa<DeclRefExpr>(op) && cast<DeclRefExpr>(op)->getQualifier()) {
DeclContext *Ctx = dcl->getDeclContext();
if (Ctx && Ctx->isRecord()) {
if (FD->getType()->isReferenceType()) {
@@ -5216,7 +5199,8 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
} else if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(dcl)) {
// Okay: we can take the address of a function.
// As above.
- if (isa<QualifiedDeclRefExpr>(op) && MD->isInstance())
+ if (isa<DeclRefExpr>(op) && cast<DeclRefExpr>(op)->getQualifier() &&
+ MD->isInstance())
return Context.getMemberPointerType(op->getType(),
Context.getTypeDeclType(MD->getParent()).getTypePtr());
} else if (!isa<FunctionDecl>(dcl))
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index ebcf3ad8e2..9e79b999e7 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -5370,18 +5370,19 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
if (Method->isStatic()) {
// Do nothing: static member functions aren't any different
// from non-member functions.
- } else if (QualifiedDeclRefExpr *DRE
- = dyn_cast<QualifiedDeclRefExpr>(UnOp->getSubExpr())) {
- // We have taken the address of a pointer to member
- // function. Perform the computation here so that we get the
- // appropriate pointer to member type.
- DRE->setDecl(Fn);
- DRE->setType(Fn->getType());
- QualType ClassType
- = Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext()));
- E->setType(Context.getMemberPointerType(Fn->getType(),
- ClassType.getTypePtr()));
- return E;
+ } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr())) {
+ if (DRE->getQualifier()) {
+ // We have taken the address of a pointer to member
+ // function. Perform the computation here so that we get the
+ // appropriate pointer to member type.
+ DRE->setDecl(Fn);
+ DRE->setType(Fn->getType());
+ QualType ClassType
+ = Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext()));
+ E->setType(Context.getMemberPointerType(Fn->getType(),
+ ClassType.getTypePtr()));
+ return E;
+ }
}
// FIXME: TemplateIdRefExpr referring to a member function template
// specialization!
@@ -5401,18 +5402,20 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
MemExpr->setMemberDecl(Fn);
E->setType(Fn->getType());
} else if (TemplateIdRefExpr *TID = dyn_cast<TemplateIdRefExpr>(E)) {
- // FIXME: We should capture the template arguments here.
- if (NestedNameSpecifier *Qualifier = TID->getQualifier())
- E = new (Context) QualifiedDeclRefExpr(Fn, Fn->getType(),
- TID->getTemplateNameLoc(),
- /*FIXME?*/false, /*FIXME?*/false,
- TID->getQualifierRange(),
- Qualifier);
- else
- E = new (Context) DeclRefExpr(Fn, Fn->getType(),
- TID->getTemplateNameLoc());
+ E = DeclRefExpr::Create(Context,
+ TID->getQualifier(), TID->getQualifierRange(),
+ Fn, TID->getTemplateNameLoc(),
+ true,
+ TID->getLAngleLoc(),
+ TID->getTemplateArgs(),
+ TID->getNumTemplateArgs(),
+ TID->getRAngleLoc(),
+ Fn->getType(),
+ /*FIXME?*/false, /*FIXME?*/false);
- TID->Destroy(Context);
+ // FIXME: Don't destroy TID here, since we need its template arguments
+ // to survive.
+ // TID->Destroy(Context);
} else {
assert(false && "Invalid reference to overloaded function");
}
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 0f223208a9..2bb790dda4 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1845,7 +1845,7 @@ Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, NamedDecl *&Member) {
// template-parameter shall be one of: [...]
//
// -- a pointer to member expressed as described in 5.3.1.
- QualifiedDeclRefExpr *DRE = 0;
+ DeclRefExpr *DRE = 0;
// Ignore (and complain about) any excess parentheses.
while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
@@ -1860,8 +1860,11 @@ Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, NamedDecl *&Member) {
}
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg))
- if (UnOp->getOpcode() == UnaryOperator::AddrOf)
- DRE = dyn_cast<QualifiedDeclRefExpr>(UnOp->getSubExpr());
+ if (UnOp->getOpcode() == UnaryOperator::AddrOf) {
+ DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
+ if (DRE && !DRE->getQualifier())
+ DRE = 0;
+ }
if (!DRE)
return Diag(Arg->getSourceRange().getBegin(),
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 53d158088c..1790d27eeb 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -618,10 +618,21 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
// FIXME: Is this correct? Maybe FindInstantiatedDecl should do this?
InstD = InstD->getUnderlyingDecl();
- // FIXME: nested-name-specifier for QualifiedDeclRefExpr
+ CXXScopeSpec SS;
+ NestedNameSpecifier *Qualifier = 0;
+ if (E->getQualifier()) {
+ Qualifier = TransformNestedNameSpecifier(E->getQualifier(),
+ E->getQualifierRange());
+ if (!Qualifier)
+ return SemaRef.ExprError();
+
+ SS.setScopeRep(Qualifier);
+ SS.setRange(E->getQualifierRange());
+ }
+
return SemaRef.BuildDeclarationNameExpr(E->getLocation(), InstD,
/*FIXME:*/false,
- /*FIXME:*/0,
+ &SS,
/*FIXME:*/false);
}
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index dec94994a8..94a0e11ec8 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -781,10 +781,15 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildDeclRefExpr(NamedDecl *ND, SourceLocation Loc) {
+ OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ NamedDecl *ND, SourceLocation Loc) {
+ CXXScopeSpec SS;
+ SS.setScopeRep(Qualifier);
+ SS.setRange(QualifierRange);
return getSema().BuildDeclarationNameExpr(Loc, ND,
/*FIXME:*/false,
- /*SS=*/0,
+ &SS,
/*FIXME:*/false);
}
@@ -1392,26 +1397,6 @@ public:
T.getAsOpaquePtr(), RParenLoc);
}
- /// \brief Build a new qualified declaration reference expression.
- ///
- /// By default, performs semantic analysis to build the new expression.
- /// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildQualifiedDeclRefExpr(NestedNameSpecifier *NNS,
- SourceRange QualifierRange,
- NamedDecl *ND,
- SourceLocation Location,
- bool IsAddressOfOperand) {
- CXXScopeSpec SS;
- SS.setRange(QualifierRange);
- SS.setScopeRep(NNS);
- return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
- Location,
- ND->getDeclName(),
- /*Trailing lparen=*/false,
- &SS,
- IsAddressOfOperand);
- }
-
/// \brief Build a new (previously unresolved) declaration reference
/// expression.
///
@@ -3276,15 +3261,40 @@ TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
template<typename Derived>
Sema::OwningExprResult
TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
+ NestedNameSpecifier *Qualifier = 0;
+ if (E->getQualifier()) {
+ Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+ E->getQualifierRange());
+ if (!Qualifier)
+ return SemaRef.ExprError();
+ }
+
NamedDecl *ND
= dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
if (!ND)
return SemaRef.ExprError();
- if (!getDerived().AlwaysRebuild() && ND == E->getDecl())
+ if (!getDerived().AlwaysRebuild() &&
+ Qualifier == E->getQualifier() &&
+ ND == E->getDecl() &&
+ !E->hasExplicitTemplateArgumentList())
return SemaRef.Owned(E->Retain());
- return getDerived().RebuildDeclRefExpr(ND, E->getLocation());
+ // FIXME: We're losing the explicit template arguments in this transformation.
+
+ llvm::SmallVector<TemplateArgument, 4> TransArgs;
+ for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
+ TemplateArgument TransArg
+ = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
+ if (TransArg.isNull())
+ return SemaRef.ExprError();
+
+ TransArgs.push_back(TransArg);
+ }
+
+ // FIXME: Pass the qualifier/qualifier range along.
+ return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
+ ND, E->getLocation());
}
template<typename Derived>
@@ -4301,32 +4311,6 @@ TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
template<typename Derived>
Sema::OwningExprResult
-TreeTransform<Derived>::TransformQualifiedDeclRefExpr(QualifiedDeclRefExpr *E) {
- NestedNameSpecifier *NNS
- = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
- E->getQualifierRange());
- if (!NNS)
- return SemaRef.ExprError();
-
- NamedDecl *ND
- = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
- if (!ND)
- return SemaRef.ExprError();
-
- if (!getDerived().AlwaysRebuild() &&
- NNS == E->getQualifier() &&
- ND == E->getDecl())
- return SemaRef.Owned(E->Retain());
-
- return getDerived().RebuildQualifiedDeclRefExpr(NNS,
- E->getQualifierRange(),
- ND,
- E->getLocation(),
- /*FIXME:*/false);
-}
-
-template<typename Derived>
-Sema::OwningExprResult
TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
UnresolvedDeclRefExpr *E) {
NestedNameSpecifier *NNS