diff options
-rw-r--r-- | include/clang/AST/Expr.h | 58 | ||||
-rw-r--r-- | include/clang/AST/Stmt.h | 1 | ||||
-rw-r--r-- | lib/AST/ASTImporter.cpp | 8 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 39 | ||||
-rw-r--r-- | lib/AST/StmtDumper.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 17 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 4 |
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()); |