diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2014-06-30 02:55:54 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2014-06-30 02:55:54 +0000 |
commit | aca7fcf2766272483484b17b113aa0cc485311b0 (patch) | |
tree | aa12fd7adfc4fa0b3e65a2f1375f8b8e869dc1b1 /clang/lib/Sema/SemaExpr.cpp | |
parent | e5c4e9f3704f2f0198f4b880215fe03c321ec2ec (diff) | |
download | bcm5719-llvm-aca7fcf2766272483484b17b113aa0cc485311b0.tar.gz bcm5719-llvm-aca7fcf2766272483484b17b113aa0cc485311b0.zip |
Using of variable length arrays in captured statements and OpenMP constructs.
Differential Revision: http://reviews.llvm.org/D4067
llvm-svn: 212010
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 105 |
1 files changed, 102 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2f1d1a61729..864c2826f69 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -11668,7 +11668,7 @@ static bool isVariableCapturable(CapturingScopeInfo *CSI, VarDecl *Var, } // Prohibit variably-modified types; they're difficult to deal with. - if (Var->getType()->isVariablyModifiedType()) { + if (Var->getType()->isVariablyModifiedType() && (IsBlock || IsLambda)) { if (Diagnose) { if (IsBlock) S.Diag(Loc, diag::err_ref_vm_type); @@ -12155,8 +12155,107 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc, // certain types of variables (unnamed, variably modified types etc.) // so check for eligibility. if (!isVariableCapturable(CSI, Var, ExprLoc, BuildAndDiagnose, *this)) - return true; - + return true; + + // Try to capture variable-length arrays types. + if (Var->getType()->isVariablyModifiedType()) { + // We're going to walk down into the type and look for VLA + // expressions. + QualType QTy = Var->getType(); + if (ParmVarDecl *PVD = dyn_cast_or_null<ParmVarDecl>(Var)) + QTy = PVD->getOriginalType(); + do { + const Type *Ty = QTy.getTypePtr(); + switch (Ty->getTypeClass()) { +#define TYPE(Class, Base) +#define ABSTRACT_TYPE(Class, Base) +#define NON_CANONICAL_TYPE(Class, Base) +#define DEPENDENT_TYPE(Class, Base) case Type::Class: +#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) +#include "clang/AST/TypeNodes.def" + QTy = QualType(); + break; + // These types are never variably-modified. + case Type::Builtin: + case Type::Complex: + case Type::Vector: + case Type::ExtVector: + case Type::Record: + case Type::Enum: + case Type::Elaborated: + case Type::TemplateSpecialization: + case Type::ObjCObject: + case Type::ObjCInterface: + case Type::ObjCObjectPointer: + llvm_unreachable("type class is never variably-modified!"); + case Type::Adjusted: + QTy = cast<AdjustedType>(Ty)->getOriginalType(); + break; + case Type::Decayed: + QTy = cast<DecayedType>(Ty)->getPointeeType(); + break; + case Type::Pointer: + QTy = cast<PointerType>(Ty)->getPointeeType(); + break; + case Type::BlockPointer: + QTy = cast<BlockPointerType>(Ty)->getPointeeType(); + break; + case Type::LValueReference: + case Type::RValueReference: + QTy = cast<ReferenceType>(Ty)->getPointeeType(); + break; + case Type::MemberPointer: + QTy = cast<MemberPointerType>(Ty)->getPointeeType(); + break; + case Type::ConstantArray: + case Type::IncompleteArray: + // Losing element qualification here is fine. + QTy = cast<ArrayType>(Ty)->getElementType(); + break; + case Type::VariableArray: { + // Losing element qualification here is fine. + const VariableArrayType *Vat = cast<VariableArrayType>(Ty); + + // Unknown size indication requires no size computation. + // Otherwise, evaluate and record it. + if (Expr *Size = Vat->getSizeExpr()) { + MarkDeclarationsReferencedInExpr(Size); + } + QTy = Vat->getElementType(); + break; + } + case Type::FunctionProto: + case Type::FunctionNoProto: + QTy = cast<FunctionType>(Ty)->getReturnType(); + break; + case Type::Paren: + case Type::TypeOf: + case Type::UnaryTransform: + case Type::Attributed: + case Type::SubstTemplateTypeParm: + case Type::PackExpansion: + // Keep walking after single level desugaring. + QTy = QTy.getSingleStepDesugaredType(getASTContext()); + break; + case Type::Typedef: + QTy = cast<TypedefType>(Ty)->desugar(); + break; + case Type::Decltype: + QTy = cast<DecltypeType>(Ty)->desugar(); + break; + case Type::Auto: + QTy = cast<AutoType>(Ty)->getDeducedType(); + break; + case Type::TypeOfExpr: + QTy = cast<TypeOfExprType>(Ty)->getUnderlyingExpr()->getType(); + break; + case Type::Atomic: + QTy = cast<AtomicType>(Ty)->getValueType(); + break; + } + } while (!QTy.isNull() && QTy->isVariablyModifiedType()); + } + if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None && !Explicit) { // No capture-default, and this is not an explicit capture // so cannot capture this variable. |