summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2014-06-12 23:03:48 +0000
committerReid Kleckner <reid@kleckner.net>2014-06-12 23:03:48 +0000
commit32506ed8be375ed3226adea8b507ad260dc3e31d (patch)
treedd1f31a11de299a3c4fec438f4030acbce5a612d /clang/lib/Sema/SemaExpr.cpp
parent02ae6902fa42b6914815b1b6371de12cef3677fa (diff)
downloadbcm5719-llvm-32506ed8be375ed3226adea8b507ad260dc3e31d.tar.gz
bcm5719-llvm-32506ed8be375ed3226adea8b507ad260dc3e31d.zip
Recover from missing 'typename' in sizeof(T::InnerType)
Summary: 'sizeof' is a UnaryExprOrTypeTrait, and it can contain either a type or an expression. This change threads a RecoveryTSI parameter through the layers between TransformUnaryExprOrTypeTrait the point at which we look up the type. If lookup finds a single type result after instantiation, we now build TypeSourceInfo for it just like a normal transformation would. This fixes the last error in the hello world ATL app that I've been working with, and it now links and runs with clang. Please try it and file bugs! Reviewers: rsmith Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D4108 llvm-svn: 210855
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp45
1 files changed, 35 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 7c076f8e844..2ae8b27be93 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2185,7 +2185,8 @@ ExprResult Sema::ActOnIdExpression(Scope *S,
ExprResult
Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
const DeclarationNameInfo &NameInfo,
- bool IsAddressOfOperand) {
+ bool IsAddressOfOperand,
+ TypeSourceInfo **RecoveryTSI) {
DeclContext *DC = computeDeclContext(SS, false);
if (!DC)
return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
@@ -2210,15 +2211,39 @@ Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
return ExprError();
}
- if (R.isSingleResult() && R.getAsSingle<TypeDecl>()) {
- // Diagnose a missing typename if this resolved unambiguously to a type in a
- // dependent context.
- // FIXME: Issue a fixit and recover as though the user had written
- // 'typename'.
- Diag(SS.getBeginLoc(), diag::err_typename_missing)
- << SS.getScopeRep() << NameInfo.getName().getAsString()
- << SourceRange(SS.getBeginLoc(), NameInfo.getEndLoc());
- return ExprError();
+ if (const TypeDecl *TD = R.getAsSingle<TypeDecl>()) {
+ // Diagnose a missing typename if this resolved unambiguously to a type in
+ // a dependent context. If we can recover with a type, downgrade this to
+ // a warning in Microsoft compatibility mode.
+ unsigned DiagID = diag::err_typename_missing;
+ if (RecoveryTSI && getLangOpts().MSVCCompat)
+ DiagID = diag::ext_typename_missing;
+ SourceLocation Loc = SS.getBeginLoc();
+ auto D = Diag(Loc, DiagID);
+ D << SS.getScopeRep() << NameInfo.getName().getAsString()
+ << SourceRange(Loc, NameInfo.getEndLoc());
+
+ // Don't recover if the caller isn't expecting us to or if we're in a SFINAE
+ // context.
+ if (!RecoveryTSI)
+ return ExprError();
+
+ // Only issue the fixit if we're prepared to recover.
+ D << FixItHint::CreateInsertion(Loc, "typename ");
+
+ // Recover by pretending this was an elaborated type.
+ QualType Ty = Context.getTypeDeclType(TD);
+ TypeLocBuilder TLB;
+ TLB.pushTypeSpec(Ty).setNameLoc(NameInfo.getLoc());
+
+ QualType ET = getElaboratedType(ETK_None, SS, Ty);
+ ElaboratedTypeLoc QTL = TLB.push<ElaboratedTypeLoc>(ET);
+ QTL.setElaboratedKeywordLoc(SourceLocation());
+ QTL.setQualifierLoc(SS.getWithLocInContext(Context));
+
+ *RecoveryTSI = TLB.getTypeSourceInfo(Context, ET);
+
+ return ExprEmpty();
}
// Defend against this resolving to an implicit member access. We usually
OpenPOWER on IntegriCloud