Handle PredefinedExpr with templates and lambdas
Summary:
- lambdas, blocks or captured statements in templates were not
handled which causes codegen crashes.
Differential Revision: http://llvm-reviews.chandlerc.com/D1628
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190784 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 4e2e24e..10d384b 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2745,22 +2745,10 @@
}
}
-ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
- PredefinedExpr::IdentType IT;
-
- switch (Kind) {
- default: llvm_unreachable("Unknown simple primary expr!");
- case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2]
- case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break;
- case tok::kw_L__FUNCTION__: IT = PredefinedExpr::LFunction; break;
- case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break;
- }
-
- // Pre-defined identifiers are of type char[x], where x is the length of the
- // string.
-
- // Pick the current block, lambda or function.
- Decl *currentDecl;
+ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
+ PredefinedExpr::IdentType IT) {
+ // Pick the current block, lambda, captured statement or function.
+ Decl *currentDecl = 0;
if (const BlockScopeInfo *BSI = getCurBlock())
currentDecl = BSI->TheDecl;
else if (const LambdaScopeInfo *LSI = getCurLambda())
@@ -2776,9 +2764,11 @@
}
QualType ResTy;
- if (cast<DeclContext>(currentDecl)->isDependentContext()) {
+ if (cast<DeclContext>(currentDecl)->isDependentContext())
ResTy = Context.DependentTy;
- } else {
+ else {
+ // Pre-defined identifiers are of type char[x], where x is the length of
+ // the string.
unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length();
llvm::APInt LengthI(32, Length + 1);
@@ -2788,9 +2778,24 @@
ResTy = Context.CharTy.withConst();
ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0);
}
+
return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT));
}
+ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
+ PredefinedExpr::IdentType IT;
+
+ switch (Kind) {
+ default: llvm_unreachable("Unknown simple primary expr!");
+ case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2]
+ case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break;
+ case tok::kw_L__FUNCTION__: IT = PredefinedExpr::LFunction; break;
+ case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break;
+ }
+
+ return BuildPredefinedExpr(Loc, IT);
+}
+
ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) {
SmallString<16> CharBuffer;
bool Invalid = false;
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 9b7b4a8..dd10cbe 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1149,25 +1149,7 @@
if (!E->isTypeDependent())
return SemaRef.Owned(E);
- FunctionDecl *currentDecl = getSema().getCurFunctionDecl();
- assert(currentDecl && "Must have current function declaration when "
- "instantiating.");
-
- PredefinedExpr::IdentType IT = E->getIdentType();
-
- unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length();
-
- llvm::APInt LengthI(32, Length + 1);
- QualType ResTy;
- if (IT == PredefinedExpr::LFunction)
- ResTy = getSema().Context.WideCharTy.withConst();
- else
- ResTy = getSema().Context.CharTy.withConst();
- ResTy = getSema().Context.getConstantArrayType(ResTy, LengthI,
- ArrayType::Normal, 0);
- PredefinedExpr *PE =
- new (getSema().Context) PredefinedExpr(E->getLocation(), ResTy, IT);
- return getSema().Owned(PE);
+ return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentType());
}
ExprResult