r176153 - Update template diffing to handle template arguments that are declarations.
Richard Trieu
rtrieu at google.com
Tue Feb 26 17:41:53 PST 2013
Author: rtrieu
Date: Tue Feb 26 19:41:53 2013
New Revision: 176153
URL: http://llvm.org/viewvc/llvm-project?rev=176153&view=rev
Log:
Update template diffing to handle template arguments that are declarations.
Modified:
cfe/trunk/lib/AST/ASTDiagnostic.cpp
cfe/trunk/test/Misc/diag-template-diffing.cpp
Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=176153&r1=176152&r2=176153&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Tue Feb 26 19:41:53 2013
@@ -435,6 +435,9 @@ class TemplateDiff {
/// IsValidFromInt, IsValidToInt - Whether the APSInt's are valid.
bool IsValidFromInt, IsValidToInt;
+ /// FromValueDecl, ToValueDecl - Whether the argument is a decl.
+ ValueDecl *FromValueDecl, *ToValueDecl;
+
/// FromDefault, ToDefault - Whether the argument is a default argument.
bool FromDefault, ToDefault;
@@ -444,8 +447,8 @@ class TemplateDiff {
DiffNode(unsigned ParentNode = 0)
: NextNode(0), ChildNode(0), ParentNode(ParentNode),
FromType(), ToType(), FromExpr(0), ToExpr(0), FromTD(0), ToTD(0),
- IsValidFromInt(false), IsValidToInt(false),
- FromDefault(false), ToDefault(false), Same(false) { }
+ IsValidFromInt(false), IsValidToInt(false), FromValueDecl(0),
+ ToValueDecl(0), FromDefault(false), ToDefault(false), Same(false) { }
};
/// FlatTree - A flattened tree used to store the DiffNodes.
@@ -501,6 +504,12 @@ class TemplateDiff {
FlatTree[CurrentNode].ToQual = ToQual;
}
+ /// SetNode - Set FromValueDecl and ToValueDecl of the current node.
+ void SetNode(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl) {
+ FlatTree[CurrentNode].FromValueDecl = FromValueDecl;
+ FlatTree[CurrentNode].ToValueDecl = ToValueDecl;
+ }
+
/// SetSame - Sets the same flag of the current node.
void SetSame(bool Same) {
FlatTree[CurrentNode].Same = Same;
@@ -584,6 +593,11 @@ class TemplateDiff {
FlatTree[ReadNode].IsValidToInt;
}
+ /// NodeIsDecl - Returns true if the arguments are stored as Decl's.
+ bool NodeIsValueDecl() {
+ return FlatTree[ReadNode].FromValueDecl || FlatTree[ReadNode].ToValueDecl;
+ }
+
/// GetNode - Gets the FromType and ToType.
void GetNode(QualType &FromType, QualType &ToType) {
FromType = FlatTree[ReadNode].FromType;
@@ -617,6 +631,12 @@ class TemplateDiff {
ToQual = FlatTree[ReadNode].ToQual;
}
+ /// GetNode - Gets the FromValueDecl and ToValueDecl.
+ void GetNode(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl) {
+ FromValueDecl = FlatTree[ReadNode].FromValueDecl;
+ ToValueDecl = FlatTree[ReadNode].ToValueDecl;
+ }
+
/// NodeIsSame - Returns true the arguments are the same.
bool NodeIsSame() {
return FlatTree[ReadNode].Same;
@@ -845,6 +865,7 @@ class TemplateDiff {
dyn_cast<NonTypeTemplateParmDecl>(ParamND)) {
Expr *FromExpr, *ToExpr;
llvm::APSInt FromInt, ToInt;
+ ValueDecl *FromValueDecl = 0, *ToValueDecl = 0;
unsigned ParamWidth = 128; // Safe default
if (DefaultNTTPD->getType()->isIntegralOrEnumerationType())
ParamWidth = Context.getIntWidth(DefaultNTTPD->getType());
@@ -852,23 +873,37 @@ class TemplateDiff {
FromIter->getKind() == TemplateArgument::Integral;
bool HasToInt = !ToIter.isEnd() &&
ToIter->getKind() == TemplateArgument::Integral;
+ bool HasFromValueDecl =
+ !FromIter.isEnd() &&
+ FromIter->getKind() == TemplateArgument::Declaration;
+ bool HasToValueDecl =
+ !ToIter.isEnd() &&
+ ToIter->getKind() == TemplateArgument::Declaration;
+
+ assert(((!HasFromInt && !HasToInt) ||
+ (!HasFromValueDecl && !HasToValueDecl)) &&
+ "Template argument cannot be both integer and declaration");
if (HasFromInt)
FromInt = FromIter->getAsIntegral();
+ else if (HasFromValueDecl)
+ FromValueDecl = FromIter->getAsDecl();
else
GetExpr(FromIter, DefaultNTTPD, FromExpr);
if (HasToInt)
ToInt = ToIter->getAsIntegral();
+ else if (HasToValueDecl)
+ ToValueDecl = ToIter->getAsDecl();
else
GetExpr(ToIter, DefaultNTTPD, ToExpr);
- if (!HasFromInt && !HasToInt) {
+ if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) {
Tree.SetNode(FromExpr, ToExpr);
Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr));
Tree.SetDefault(FromIter.isEnd() && FromExpr,
ToIter.isEnd() && ToExpr);
- } else {
+ } else if (HasFromInt || HasToInt) {
if (!HasFromInt && FromExpr) {
FromInt = FromExpr->EvaluateKnownConstInt(Context);
HasFromInt = true;
@@ -881,6 +916,20 @@ class TemplateDiff {
Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
Tree.SetDefault(FromIter.isEnd() && HasFromInt,
ToIter.isEnd() && HasToInt);
+ } else {
+ if (!HasFromValueDecl && FromExpr) {
+ DeclRefExpr *DRE = cast<DeclRefExpr>(FromExpr);
+ FromValueDecl = cast<ValueDecl>(DRE->getDecl());
+ }
+ if (!HasToValueDecl && ToExpr) {
+ DeclRefExpr *DRE = cast<DeclRefExpr>(ToExpr);
+ ToValueDecl = cast<ValueDecl>(DRE->getDecl());
+ }
+ Tree.SetNode(FromValueDecl, ToValueDecl);
+ Tree.SetSame(FromValueDecl->getCanonicalDecl() ==
+ ToValueDecl->getCanonicalDecl());
+ Tree.SetDefault(FromIter.isEnd() && FromValueDecl,
+ ToIter.isEnd() && ToValueDecl);
}
}
@@ -1116,6 +1165,15 @@ class TemplateDiff {
Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
return;
}
+
+ if (Tree.NodeIsValueDecl()) {
+ ValueDecl *FromValueDecl, *ToValueDecl;
+ Tree.GetNode(FromValueDecl, ToValueDecl);
+ PrintValueDecl(FromValueDecl, ToValueDecl, Tree.FromDefault(),
+ Tree.ToDefault(), Tree.NodeIsSame());
+ return;
+ }
+
llvm_unreachable("Unable to deduce template difference.");
}
@@ -1331,6 +1389,35 @@ class TemplateDiff {
}
}
+
+ /// PrintDecl - Handles printing of Decl arguments, highlighting
+ /// argument differences.
+ void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
+ bool FromDefault, bool ToDefault, bool Same) {
+ assert((FromValueDecl || ToValueDecl) &&
+ "Only one Decl argument may be NULL");
+
+ if (Same) {
+ OS << FromValueDecl->getName();
+ } else if (!PrintTree) {
+ OS << (FromDefault ? "(default) " : "");
+ Bold();
+ OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");
+ Unbold();
+ } else {
+ OS << (FromDefault ? "[(default) " : "[");
+ Bold();
+ OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");
+ Unbold();
+ OS << " != " << (ToDefault ? "(default) " : "");
+ Bold();
+ OS << (ToValueDecl ? ToValueDecl->getName() : "(no argument)");
+ Unbold();
+ OS << ']';
+ }
+
+ }
+
// Prints the appropriate placeholder for elided template arguments.
void PrintElideArgs(unsigned NumElideArgs, unsigned Indent) {
if (PrintTree) {
Modified: cfe/trunk/test/Misc/diag-template-diffing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/diag-template-diffing.cpp?rev=176153&r1=176152&r2=176153&view=diff
==============================================================================
--- cfe/trunk/test/Misc/diag-template-diffing.cpp (original)
+++ cfe/trunk/test/Misc/diag-template-diffing.cpp Tue Feb 26 19:41:53 2013
@@ -869,6 +869,40 @@ namespace rdar12931988 {
}
}
+namespace ValueDecl {
+ int int1, int2, default_int;
+ template <const int& T = default_int>
+ struct S {};
+
+ typedef S<int1> T1;
+ typedef S<int2> T2;
+ typedef S<> TD;
+
+ void test() {
+ T1 t1;
+ T2 t2;
+ TD td;
+
+ t1 = t2;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'S<int2>' to 'S<int1>'
+
+ t2 = t1;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'S<int1>' to 'S<int2>'
+
+ td = t1;
+ // TODO: Find out why (default) isn't printed on second template.
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'S<int1>' to 'S<default_int>'
+
+ t2 = td;
+ // CHECK-ELIDE-NOTREE: no viable overloaded '='
+ // CHECK-ELIDE-NOTREE: no known conversion from 'S<(default) default_int>' to 'S<int2>'
+
+ }
+}
+
// CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
// CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.
// CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.
More information about the cfe-commits
mailing list