aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGDecl.cpp')
-rw-r--r--lib/CodeGen/CGDecl.cpp184
1 files changed, 107 insertions, 77 deletions
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 62c3a9791d0f..a6147ea7658b 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -14,6 +14,7 @@
#include "CGDebugInfo.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
+#include "CGOpenCLRuntime.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
@@ -46,7 +47,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
case Decl::Field:
case Decl::IndirectField:
case Decl::ObjCIvar:
- case Decl::ObjCAtDefsField:
+ case Decl::ObjCAtDefsField:
case Decl::ParmVar:
case Decl::ImplicitParam:
case Decl::ClassTemplate:
@@ -70,7 +71,8 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
case Decl::Friend:
case Decl::FriendTemplate:
case Decl::Block:
- assert(0 && "Declaration should not be in declstmts!");
+ case Decl::ClassScopeFunctionSpecialization:
+ llvm_unreachable("Declaration should not be in declstmts!");
case Decl::Function: // void X();
case Decl::Record: // struct/union/class X;
case Decl::Enum: // enum X;
@@ -112,7 +114,7 @@ void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
case SC_Register:
return EmitAutoVarDecl(D);
case SC_Static: {
- llvm::GlobalValue::LinkageTypes Linkage =
+ llvm::GlobalValue::LinkageTypes Linkage =
llvm::GlobalValue::InternalLinkage;
// If the function definition has some sort of weak linkage, its
@@ -123,26 +125,28 @@ void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
if (getContext().getLangOptions().CPlusPlus)
if (llvm::GlobalValue::isWeakForLinker(CurFn->getLinkage()))
Linkage = CurFn->getLinkage();
-
+
return EmitStaticVarDecl(D, Linkage);
}
case SC_Extern:
case SC_PrivateExtern:
// Don't emit it now, allow it to be emitted lazily on its first use.
return;
+ case SC_OpenCLWorkGroupLocal:
+ return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*this, D);
}
- assert(0 && "Unknown storage class");
+ llvm_unreachable("Unknown storage class");
}
static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D,
const char *Separator) {
CodeGenModule &CGM = CGF.CGM;
if (CGF.getContext().getLangOptions().CPlusPlus) {
- llvm::StringRef Name = CGM.getMangledName(&D);
+ StringRef Name = CGM.getMangledName(&D);
return Name.str();
}
-
+
std::string ContextName;
if (!CGF.CurFuncDecl) {
// Better be in a block declared in global scope.
@@ -154,15 +158,15 @@ static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D,
ContextName = Name.getString();
}
else
- assert(0 && "Unknown context for block static var decl");
+ llvm_unreachable("Unknown context for block static var decl");
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl)) {
- llvm::StringRef Name = CGM.getMangledName(FD);
+ StringRef Name = CGM.getMangledName(FD);
ContextName = Name.str();
} else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl))
ContextName = CGF.CurFn->getName();
else
- assert(0 && "Unknown context for static var decl");
-
+ llvm_unreachable("Unknown context for static var decl");
+
return ContextName + Separator + D.getNameAsString();
}
@@ -175,7 +179,7 @@ CodeGenFunction::CreateStaticVarDecl(const VarDecl &D,
std::string Name = GetStaticDeclName(*this, D, Separator);
- const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
+ llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(CGM.getModule(), LTy,
Ty.isConstant(getContext()), Linkage,
@@ -203,7 +207,7 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
if (!getContext().getLangOptions().CPlusPlus)
CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");
else if (Builder.GetInsertBlock()) {
- // Since we have a static initializer, this global variable can't
+ // Since we have a static initializer, this global variable can't
// be constant.
GV->setConstant(false);
@@ -218,7 +222,7 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
// in the LLVM type system.)
if (GV->getType()->getElementType() != Init->getType()) {
llvm::GlobalVariable *OldGV = GV;
-
+
GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
OldGV->isConstant(),
OldGV->getLinkage(), Init, "",
@@ -226,19 +230,19 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
D.isThreadSpecified(),
CGM.getContext().getTargetAddressSpace(D.getType()));
GV->setVisibility(OldGV->getVisibility());
-
+
// Steal the name of the old global
GV->takeName(OldGV);
-
+
// Replace all uses of the old global with the new global
llvm::Constant *NewPtrForOldDecl =
llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
OldGV->replaceAllUsesWith(NewPtrForOldDecl);
-
+
// Erase the old global, since it is no longer used.
OldGV->eraseFromParent();
}
-
+
GV->setInitializer(Init);
return GV;
}
@@ -259,7 +263,7 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
// Make sure to evaluate VLA bounds now so that we have them for later.
if (D.getType()->isVariablyModifiedType())
EmitVariablyModifiedType(D.getType());
-
+
// Local static block variables must be treated as globals as they may be
// referenced in their RHS initializer block-literal expresion.
CGM.setStaticLocalDeclAddress(&D, GV);
@@ -270,14 +274,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
- // FIXME: Merge attribute handling.
- if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>()) {
- SourceManager &SM = CGM.getContext().getSourceManager();
- llvm::Constant *Ann =
- CGM.EmitAnnotateAttr(GV, AA,
- SM.getInstantiationLineNumber(D.getLocation()));
- CGM.AddAnnotation(Ann);
- }
+ if (D.hasAttr<AnnotateAttr>())
+ CGM.AddGlobalAnnotations(&D, GV);
if (const SectionAttr *SA = D.getAttr<SectionAttr>())
GV->setSection(SA->getName());
@@ -290,8 +288,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
//
// FIXME: It is really dangerous to store this in the map; if anyone
// RAUW's the GV uses of this constant will be invalid.
- const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
- const llvm::Type *LPtrTy =
+ llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
+ llvm::Type *LPtrTy =
LTy->getPointerTo(CGM.getContext().getTargetAddressSpace(D.getType()));
DMEntry = llvm::ConstantExpr::getBitCast(GV, LPtrTy);
@@ -348,7 +346,7 @@ namespace {
CGF.Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB);
CGF.EmitBlock(RunDtorBB);
}
-
+
CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
/*ForVirtualBase=*/false, Loc);
@@ -360,7 +358,7 @@ namespace {
llvm::Value *Stack;
CallStackRestore(llvm::Value *Stack) : Stack(Stack) {}
void Emit(CodeGenFunction &CGF, Flags flags) {
- llvm::Value *V = CGF.Builder.CreateLoad(Stack, "tmp");
+ llvm::Value *V = CGF.Builder.CreateLoad(Stack);
llvm::Value *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
CGF.Builder.CreateCall(F, V);
}
@@ -384,7 +382,7 @@ namespace {
llvm::Constant *CleanupFn;
const CGFunctionInfo &FnInfo;
const VarDecl &Var;
-
+
CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info,
const VarDecl *Var)
: CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}
@@ -441,7 +439,7 @@ static void EmitAutoVarWithLifetime(CodeGenFunction &CGF, const VarDecl &var,
case Qualifiers::OCL_Autoreleasing:
// nothing to do
break;
-
+
case Qualifiers::OCL_Weak:
// __weak objects always get EH cleanups; otherwise, exceptions
// could cause really nasty crashes instead of mere leaks.
@@ -508,7 +506,7 @@ void CodeGenFunction::EmitScalarInit(const Expr *init,
// actually perform the initialization with an assign.
bool accessedByInit = false;
if (lifetime != Qualifiers::OCL_ExplicitNone)
- accessedByInit = isAccessedBy(D, init);
+ accessedByInit = (capturedByInit || isAccessedBy(D, init));
if (accessedByInit) {
LValue tempLV = lvalue;
// Drill down to the __block object if necessary.
@@ -519,12 +517,12 @@ void CodeGenFunction::EmitScalarInit(const Expr *init,
getByRefValueLLVMField(cast<VarDecl>(D))));
}
- const llvm::PointerType *ty
+ llvm::PointerType *ty
= cast<llvm::PointerType>(tempLV.getAddress()->getType());
ty = cast<llvm::PointerType>(ty->getElementType());
llvm::Value *zero = llvm::ConstantPointerNull::get(ty);
-
+
// If __weak, we want to use a barrier under certain conditions.
if (lifetime == Qualifiers::OCL_Weak)
EmitARCInitWeak(tempLV.getAddress(), zero);
@@ -613,7 +611,7 @@ void CodeGenFunction::EmitScalarInit(llvm::Value *init, LValue lvalue) {
break;
}
- EmitStoreOfScalar(init, lvalue);
+ EmitStoreOfScalar(init, lvalue);
}
/// canEmitInitWithFewStoresAfterMemset - Decide whether we can emit the
@@ -640,7 +638,7 @@ static bool canEmitInitWithFewStoresAfterMemset(llvm::Constant *Init,
}
return true;
}
-
+
// Anything else is hard and scary.
return false;
}
@@ -655,7 +653,7 @@ static void emitStoresForInitAfterMemset(llvm::Constant *Init, llvm::Value *Loc,
isa<llvm::ConstantPointerNull>(Init) ||
isa<llvm::UndefValue>(Init))
return;
-
+
if (isa<llvm::ConstantInt>(Init) || isa<llvm::ConstantFP>(Init) ||
isa<llvm::ConstantVector>(Init) || isa<llvm::BlockAddress>(Init) ||
isa<llvm::ConstantExpr>(Init)) {
@@ -663,14 +661,14 @@ static void emitStoresForInitAfterMemset(llvm::Constant *Init, llvm::Value *Loc,
Builder.CreateStore(Init, Loc, isVolatile);
return;
}
-
+
assert((isa<llvm::ConstantStruct>(Init) || isa<llvm::ConstantArray>(Init)) &&
"Unknown value type!");
-
+
for (unsigned i = 0, e = Init->getNumOperands(); i != e; ++i) {
llvm::Constant *Elt = cast<llvm::Constant>(Init->getOperand(i));
if (Elt->isNullValue()) continue;
-
+
// Otherwise, get a pointer to the element and emit it.
emitStoresForInitAfterMemset(Elt, Builder.CreateConstGEP2_32(Loc, 0, i),
isVolatile, Builder);
@@ -694,8 +692,8 @@ static bool shouldUseMemSetPlusStoresToInitialize(llvm::Constant *Init,
// plopping in more stores.
unsigned StoreBudget = 6;
uint64_t SizeLimit = 32;
-
- return GlobalSize > SizeLimit &&
+
+ return GlobalSize > SizeLimit &&
canEmitInitWithFewStoresAfterMemset(Init, StoreBudget);
}
@@ -730,7 +728,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
llvm::Value *DeclPtr;
if (Ty->isConstantSizeType()) {
if (!Target.useGlobalsForAutomaticVariables()) {
- bool NRVO = getContext().getLangOptions().ElideConstructors &&
+ bool NRVO = getContext().getLangOptions().ElideConstructors &&
D.isNRVOVariable();
// If this value is a POD array or struct with a statically
@@ -740,7 +738,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
// arrays as long as the initialization is trivial (e.g. if they
// have a non-trivial destructor, but not a non-trivial constructor).
if (D.getInit() &&
- (Ty->isArrayType() || Ty->isRecordType()) &&
+ (Ty->isArrayType() || Ty->isRecordType()) &&
(Ty.isPODType(getContext()) ||
getContext().getBaseElementType(Ty)->isObjCObjectPointerType()) &&
D.getInit()->isConstantInitializer(getContext(), false)) {
@@ -759,27 +757,27 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
// Otherwise, tell the initialization code that we're in this case.
emission.IsConstantAggregate = true;
}
-
+
// A normal fixed sized variable becomes an alloca in the entry block,
// unless it's an NRVO variable.
- const llvm::Type *LTy = ConvertTypeForMem(Ty);
-
+ llvm::Type *LTy = ConvertTypeForMem(Ty);
+
if (NRVO) {
// The named return value optimization: allocate this variable in the
// return slot, so that we can elide the copy when returning this
// variable (C++0x [class.copy]p34).
DeclPtr = ReturnValue;
-
+
if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
if (!cast<CXXRecordDecl>(RecordTy->getDecl())->hasTrivialDestructor()) {
// Create a flag that is used to indicate when the NRVO was applied
- // to this variable. Set it to zero to indicate that NRVO was not
+ // to this variable. Set it to zero to indicate that NRVO was not
// applied.
llvm::Value *Zero = Builder.getFalse();
llvm::Value *NRVOFlag = CreateTempAlloca(Zero->getType(), "nrvo");
EnsureInsertPoint();
Builder.CreateStore(Zero, NRVOFlag);
-
+
// Record the NRVO flag for this variable.
NRVOFlags[&D] = NRVOFlag;
emission.NRVOFlag = NRVOFlag;
@@ -788,13 +786,13 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
} else {
if (isByRef)
LTy = BuildByRefType(&D);
-
+
llvm::AllocaInst *Alloc = CreateTempAlloca(LTy);
Alloc->setName(D.getNameAsString());
CharUnits allocaAlignment = alignment;
if (isByRef)
- allocaAlignment = std::max(allocaAlignment,
+ allocaAlignment = std::max(allocaAlignment,
getContext().toCharUnitsFromBits(Target.getPointerAlign(0)));
Alloc->setAlignment(allocaAlignment.getQuantity());
DeclPtr = Alloc;
@@ -829,7 +827,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
QualType elementType;
llvm::tie(elementCount, elementType) = getVLASize(Ty);
- const llvm::Type *llvmTy = ConvertTypeForMem(elementType);
+ llvm::Type *llvmTy = ConvertTypeForMem(elementType);
// Allocate memory for the array.
llvm::AllocaInst *vla = Builder.CreateAlloca(llvmTy, elementCount, "vla");
@@ -853,6 +851,9 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
DI->EmitDeclareOfAutoVariable(&D, DeclPtr, Builder);
}
+ if (D.hasAttr<AnnotateAttr>())
+ EmitVarAnnotations(&D, emission.Address);
+
return emission;
}
@@ -875,6 +876,32 @@ static bool isCapturedBy(const VarDecl &var, const Expr *e) {
return false;
}
+ if (const StmtExpr *SE = dyn_cast<StmtExpr>(e)) {
+ const CompoundStmt *CS = SE->getSubStmt();
+ for (CompoundStmt::const_body_iterator BI = CS->body_begin(),
+ BE = CS->body_end(); BI != BE; ++BI)
+ if (Expr *E = dyn_cast<Expr>((*BI))) {
+ if (isCapturedBy(var, E))
+ return true;
+ }
+ else if (DeclStmt *DS = dyn_cast<DeclStmt>((*BI))) {
+ // special case declarations
+ for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end();
+ I != E; ++I) {
+ if (VarDecl *VD = dyn_cast<VarDecl>((*I))) {
+ Expr *Init = VD->getInit();
+ if (Init && isCapturedBy(var, Init))
+ return true;
+ }
+ }
+ }
+ else
+ // FIXME. Make safe assumption assuming arbitrary statements cause capturing.
+ // Later, provide code to poke into statements for capture analysis.
+ return true;
+ return false;
+ }
+
for (Stmt::const_child_range children = e->children(); children; ++children)
if (isCapturedBy(var, cast<Expr>(*children)))
return true;
@@ -887,14 +914,14 @@ static bool isCapturedBy(const VarDecl &var, const Expr *e) {
static bool isTrivialInitializer(const Expr *Init) {
if (!Init)
return true;
-
+
if (const CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init))
if (CXXConstructorDecl *Constructor = Construct->getConstructor())
if (Constructor->isTrivial() &&
Constructor->isDefaultConstructor() &&
!Construct->requiresZeroInitialization())
return true;
-
+
return false;
}
void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
@@ -922,7 +949,6 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
if (isTrivialInitializer(Init))
return;
-
CharUnits alignment = emission.Alignment;
@@ -950,16 +976,16 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
assert(constant != 0 && "Wasn't a simple constant init?");
llvm::Value *SizeVal =
- llvm::ConstantInt::get(IntPtrTy,
+ llvm::ConstantInt::get(IntPtrTy,
getContext().getTypeSizeInChars(type).getQuantity());
- const llvm::Type *BP = Int8PtrTy;
+ llvm::Type *BP = Int8PtrTy;
if (Loc->getType() != BP)
- Loc = Builder.CreateBitCast(Loc, BP, "tmp");
+ Loc = Builder.CreateBitCast(Loc, BP);
// If the initializer is all or mostly zeros, codegen with memset then do
// a few stores afterward.
- if (shouldUseMemSetPlusStoresToInitialize(constant,
+ if (shouldUseMemSetPlusStoresToInitialize(constant,
CGM.getTargetData().getTypeAllocSize(constant->getType()))) {
Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal,
alignment.getQuantity(), isVolatile);
@@ -968,19 +994,19 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
emitStoresForInitAfterMemset(constant, Loc, isVolatile, Builder);
}
} else {
- // Otherwise, create a temporary global with the initializer then
+ // Otherwise, create a temporary global with the initializer then
// memcpy from the global to the alloca.
std::string Name = GetStaticDeclName(*this, D, ".");
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(CGM.getModule(), constant->getType(), true,
- llvm::GlobalValue::InternalLinkage,
+ llvm::GlobalValue::PrivateLinkage,
constant, Name, 0, false, 0);
GV->setAlignment(alignment.getQuantity());
GV->setUnnamedAddr(true);
-
+
llvm::Value *SrcPtr = GV;
if (SrcPtr->getType() != BP)
- SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
+ SrcPtr = Builder.CreateBitCast(SrcPtr, BP);
Builder.CreateMemCpy(Loc, SrcPtr, SizeVal, alignment.getQuantity(),
isVolatile);
@@ -1007,7 +1033,7 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init,
if (type->isReferenceType()) {
RValue rvalue = EmitReferenceBindingToExpr(init, D);
- if (capturedByInit)
+ if (capturedByInit)
drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
EmitStoreThroughLValue(rvalue, lvalue);
} else if (!hasAggregateLLVMType(type)) {
@@ -1019,7 +1045,10 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init,
StoreComplexToAddr(complex, lvalue.getAddress(), lvalue.isVolatile());
} else {
// TODO: how can we delay here if D is captured by its initializer?
- EmitAggExpr(init, AggValueSlot::forLValue(lvalue, true, false));
+ EmitAggExpr(init, AggValueSlot::forLValue(lvalue,
+ AggValueSlot::IsDestructed,
+ AggValueSlot::DoesNotNeedGCBarriers,
+ AggValueSlot::IsNotAliased));
}
}
@@ -1058,7 +1087,7 @@ void CodeGenFunction::emitAutoVarTypeCleanup(
case QualType::DK_objc_strong_lifetime:
// Suppress cleanups for pseudo-strong variables.
if (var->isARCPseudoStrong()) return;
-
+
// Otherwise, consider whether to use an EH cleanup or not.
cleanupKind = getARCCleanupKind();
@@ -1094,7 +1123,7 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
emitAutoVarTypeCleanup(emission, dtorKind);
// In GC mode, honor objc_precise_lifetime.
- if (getLangOptions().getGCMode() != LangOptions::NonGC &&
+ if (getLangOptions().getGC() != LangOptions::NonGC &&
D.hasAttr<ObjCPreciseLifetimeAttr>()) {
EHStack.pushCleanup<ExtendGCLifetime>(NormalCleanup, &D);
}
@@ -1267,11 +1296,9 @@ static void emitPartialArrayDestroy(CodeGenFunction &CGF,
if (arrayDepth) {
llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, arrayDepth+1);
- llvm::SmallVector<llvm::Value*,4> gepIndices(arrayDepth, zero);
- begin = CGF.Builder.CreateInBoundsGEP(begin, gepIndices.begin(),
- gepIndices.end(), "pad.arraybegin");
- end = CGF.Builder.CreateInBoundsGEP(end, gepIndices.begin(),
- gepIndices.end(), "pad.arrayend");
+ SmallVector<llvm::Value*,4> gepIndices(arrayDepth, zero);
+ begin = CGF.Builder.CreateInBoundsGEP(begin, gepIndices, "pad.arraybegin");
+ end = CGF.Builder.CreateInBoundsGEP(end, gepIndices, "pad.arrayend");
}
// Destroy the array. We don't ever need an EH cleanup because we
@@ -1330,7 +1357,7 @@ namespace {
/// pushIrregularPartialArrayCleanup - Push an EH cleanup to destroy
/// already-constructed elements of the given array. The cleanup
/// may be popped with DeactivateCleanupBlock or PopCleanupBlock.
-///
+///
/// \param elementType - the immediate element type of the array;
/// possibly still an array type
/// \param array - a value of type elementType*
@@ -1349,7 +1376,7 @@ void CodeGenFunction::pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
/// pushRegularPartialArrayCleanup - Push an EH cleanup to destroy
/// already-constructed elements of the given array. The cleanup
/// may be popped with DeactivateCleanupBlock or PopCleanupBlock.
-///
+///
/// \param elementType - the immediate element type of the array;
/// possibly still an array type
/// \param array - a value of type elementType*
@@ -1476,4 +1503,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg,
// Emit debug info for param declaration.
if (CGDebugInfo *DI = getDebugInfo())
DI->EmitDeclareOfArgVariable(&D, DeclPtr, ArgNo, Builder);
+
+ if (D.hasAttr<AnnotateAttr>())
+ EmitVarAnnotations(&D, DeclPtr);
}