aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Expr.h58
-rw-r--r--include/clang/AST/Stmt.h1
-rw-r--r--lib/AST/ASTImporter.cpp8
-rw-r--r--lib/AST/Expr.cpp39
-rw-r--r--lib/AST/StmtDumper.cpp5
-rw-r--r--lib/Sema/SemaOverload.cpp2
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp17
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp4
8 files changed, 111 insertions, 23 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 980ad376fb..363dca75b4 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -675,6 +675,10 @@ struct ExplicitTemplateArgumentList {
/// DeclRefExprBits.HasQualifier:
/// Specifies when this declaration reference expression has a C++
/// nested-name-specifier.
+/// DeclRefExprBits.HasFoundDecl:
+/// Specifies when this declaration reference expression has a record of
+/// a NamedDecl (different from the referenced ValueDecl) which was found
+/// during name lookup and/or overload resolution.
/// DeclRefExprBits.HasExplicitTemplateArgs:
/// Specifies when this declaration reference expression has an explicit
/// C++ template argument list.
@@ -700,13 +704,34 @@ class DeclRefExpr : public Expr {
return const_cast<DeclRefExpr *>(this)->getInternalQualifierLoc();
}
+ /// \brief Test whether there is a distinct FoundDecl attached to the end of
+ /// this DRE.
+ bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; }
+
+ /// \brief Helper to retrieve the optional NamedDecl through which this
+ /// reference occured.
+ NamedDecl *&getInternalFoundDecl() {
+ assert(hasFoundDecl());
+ if (hasQualifier())
+ return *reinterpret_cast<NamedDecl **>(&getInternalQualifierLoc() + 1);
+ return *reinterpret_cast<NamedDecl **>(this + 1);
+ }
+
+ /// \brief Helper to retrieve the optional NamedDecl through which this
+ /// reference occured.
+ NamedDecl *getInternalFoundDecl() const {
+ return const_cast<DeclRefExpr *>(this)->getInternalFoundDecl();
+ }
+
DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
ValueDecl *D, SourceLocation NameLoc,
+ NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK);
DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
ValueDecl *D, const DeclarationNameInfo &NameInfo,
+ NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK);
@@ -724,6 +749,7 @@ public:
D(D), Loc(L) {
DeclRefExprBits.HasQualifier = 0;
DeclRefExprBits.HasExplicitTemplateArgs = 0;
+ DeclRefExprBits.HasFoundDecl = 0;
computeDependence();
}
@@ -732,6 +758,7 @@ public:
ValueDecl *D,
SourceLocation NameLoc,
QualType T, ExprValueKind VK,
+ NamedDecl *FoundD = 0,
const TemplateArgumentListInfo *TemplateArgs = 0);
static DeclRefExpr *Create(ASTContext &Context,
@@ -739,11 +766,13 @@ public:
ValueDecl *D,
const DeclarationNameInfo &NameInfo,
QualType T, ExprValueKind VK,
+ NamedDecl *FoundD = 0,
const TemplateArgumentListInfo *TemplateArgs = 0);
/// \brief Construct an empty declaration reference expression.
static DeclRefExpr *CreateEmpty(ASTContext &Context,
- bool HasQualifier,
+ bool HasQualifier,
+ bool HasFoundDecl,
bool HasExplicitTemplateArgs,
unsigned NumTemplateArgs);
@@ -781,6 +810,21 @@ public:
return getInternalQualifierLoc();
}
+ /// \brief Get the NamedDecl through which this reference occured.
+ ///
+ /// This Decl may be different from the ValueDecl actually referred to in the
+ /// presence of using declarations, etc. It always returns non-NULL, and may
+ /// simple return the ValueDecl when appropriate.
+ NamedDecl *getFoundDecl() {
+ return hasFoundDecl() ? getInternalFoundDecl() : D;
+ }
+
+ /// \brief Get the NamedDecl through which this reference occurred.
+ /// See non-const variant.
+ const NamedDecl *getFoundDecl() const {
+ return hasFoundDecl() ? getInternalFoundDecl() : D;
+ }
+
/// \brief Determines whether this declaration reference was followed by an
/// explict template argument list.
bool hasExplicitTemplateArgs() const {
@@ -791,11 +835,15 @@ public:
/// member template name.
ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
assert(hasExplicitTemplateArgs());
- if (!hasQualifier())
- return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+ if (hasFoundDecl())
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(
+ &getInternalFoundDecl() + 1);
- return *reinterpret_cast<ExplicitTemplateArgumentList *>(
- &getInternalQualifierLoc() + 1);
+ if (hasQualifier())
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(
+ &getInternalQualifierLoc() + 1);
+
+ return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
}
/// \brief Retrieve the explicit template argument list that followed the
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 903096e137..695fb0403e 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -165,6 +165,7 @@ protected:
unsigned HasQualifier : 1;
unsigned HasExplicitTemplateArgs : 1;
+ unsigned HasFoundDecl : 1;
};
class CastExprBitfields {
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 3907b1a319..b14560e298 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -3765,6 +3765,13 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
if (!ToD)
return 0;
+
+ NamedDecl *FoundD = 0;
+ if (E->getDecl() != E->getFoundDecl()) {
+ FoundD = cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl()));
+ if (!FoundD)
+ return 0;
+ }
QualType T = Importer.Import(E->getType());
if (T.isNull())
@@ -3775,6 +3782,7 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
ToD,
Importer.Import(E->getLocation()),
T, E->getValueKind(),
+ FoundD,
/*FIXME:TemplateArgs=*/0);
}
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 92e66722ef..bba35ef532 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -274,8 +274,9 @@ void DeclRefExpr::computeDependence() {
ExprBits.ContainsUnexpandedParameterPack = true;
}
-DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
+DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
ValueDecl *D, SourceLocation NameLoc,
+ NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK)
: Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false),
@@ -283,17 +284,19 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
if (QualifierLoc)
getInternalQualifierLoc() = QualifierLoc;
-
+ DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0;
+ if (FoundD)
+ getInternalFoundDecl() = FoundD;
DeclRefExprBits.HasExplicitTemplateArgs = TemplateArgs ? 1 : 0;
- if (TemplateArgs) {
+ if (TemplateArgs)
getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
- }
computeDependence();
}
DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
ValueDecl *D, const DeclarationNameInfo &NameInfo,
+ NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK)
: Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false),
@@ -301,7 +304,9 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
if (QualifierLoc)
getInternalQualifierLoc() = QualifierLoc;
-
+ DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0;
+ if (FoundD)
+ getInternalFoundDecl() = FoundD;
DeclRefExprBits.HasExplicitTemplateArgs = TemplateArgs ? 1 : 0;
if (TemplateArgs)
getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
@@ -315,10 +320,11 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
SourceLocation NameLoc,
QualType T,
ExprValueKind VK,
+ NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs) {
return Create(Context, QualifierLoc, D,
DeclarationNameInfo(D->getDeclName(), NameLoc),
- T, VK, TemplateArgs);
+ T, VK, FoundD, TemplateArgs);
}
DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
@@ -327,29 +333,38 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
const DeclarationNameInfo &NameInfo,
QualType T,
ExprValueKind VK,
+ NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs) {
+ // Filter out cases where the found Decl is the same as the value refenenced.
+ if (D == FoundD)
+ FoundD = 0;
+
std::size_t Size = sizeof(DeclRefExpr);
if (QualifierLoc != 0)
Size += sizeof(NestedNameSpecifierLoc);
-
+ if (FoundD)
+ Size += sizeof(NamedDecl *);
if (TemplateArgs)
Size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
-
+
void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
- return new (Mem) DeclRefExpr(QualifierLoc, D, NameInfo, TemplateArgs, T, VK);
+ return new (Mem) DeclRefExpr(QualifierLoc, D, NameInfo, FoundD, TemplateArgs,
+ T, VK);
}
-DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context,
+DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context,
bool HasQualifier,
+ bool HasFoundDecl,
bool HasExplicitTemplateArgs,
unsigned NumTemplateArgs) {
std::size_t Size = sizeof(DeclRefExpr);
if (HasQualifier)
Size += sizeof(NestedNameSpecifierLoc);
-
+ if (HasFoundDecl)
+ Size += sizeof(NamedDecl *);
if (HasExplicitTemplateArgs)
Size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
-
+
void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
return new (Mem) DeclRefExpr(EmptyShell());
}
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index f74556931d..fb024f33ab 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -369,6 +369,11 @@ void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
OS << " ";
DumpDeclRef(Node->getDecl());
+ if (Node->getDecl() != Node->getFoundDecl()) {
+ OS << " (";
+ DumpDeclRef(Node->getFoundDecl());
+ OS << ")";
+ }
}
void StmtDumper::DumpDeclRef(Decl *d) {
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 6c529208e4..3f3ed0e1f9 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -9244,6 +9244,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
ULE->getNameLoc(),
Fn->getType(),
VK_LValue,
+ Found.getDecl(),
TemplateArgs);
}
@@ -9267,6 +9268,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
MemExpr->getMemberLoc(),
Fn->getType(),
VK_LValue,
+ Found.getDecl(),
TemplateArgs);
} else {
SourceLocation Loc = MemExpr->getMemberLoc();
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 6b49b7ba6c..918db7e367 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -426,6 +426,7 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
VisitExpr(E);
E->DeclRefExprBits.HasQualifier = Record[Idx++];
+ E->DeclRefExprBits.HasFoundDecl = Record[Idx++];
E->DeclRefExprBits.HasExplicitTemplateArgs = Record[Idx++];
unsigned NumTemplateArgs = 0;
if (E->hasExplicitTemplateArgs())
@@ -435,6 +436,9 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
E->getInternalQualifierLoc()
= Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
+ if (E->hasFoundDecl())
+ E->getInternalFoundDecl() = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+
if (E->hasExplicitTemplateArgs())
ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
NumTemplateArgs);
@@ -1566,12 +1570,13 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case EXPR_DECL_REF:
- S = DeclRefExpr::CreateEmpty(*Context,
- /*HasQualifier=*/Record[ASTStmtReader::NumExprFields],
- /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1],
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1]
- ? Record[ASTStmtReader::NumExprFields + 2]
- : 0);
+ S = DeclRefExpr::CreateEmpty(
+ *Context,
+ /*HasQualifier=*/Record[ASTStmtReader::NumExprFields],
+ /*HasFoundDecl=*/Record[ASTStmtReader::NumExprFields + 1],
+ /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 2],
+ /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 2] ?
+ Record[ASTStmtReader::NumExprFields + 3] : 0);
break;
case EXPR_INTEGER_LITERAL:
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 4fe3bae91a..bd5889ad92 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -384,6 +384,7 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
VisitExpr(E);
Record.push_back(E->hasQualifier());
+ Record.push_back(E->getDecl() != E->getFoundDecl());
Record.push_back(E->hasExplicitTemplateArgs());
if (E->hasExplicitTemplateArgs()) {
@@ -394,6 +395,9 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
if (E->hasQualifier())
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
+ if (E->getDecl() != E->getFoundDecl())
+ Writer.AddDeclRef(E->getFoundDecl(), Record);
+
if (E->hasExplicitTemplateArgs())
AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs());