[cfe-commits] r105478 - in /cfe/trunk: lib/AST/ASTContext.cpp lib/Sema/Sema.h lib/Sema/SemaChecking.cpp lib/Sema/SemaExpr.cpp test/CodeGen/blocks.c
John McCall
rjmccall at apple.com
Fri Jun 4 12:02:56 PDT 2010
Author: rjmccall
Date: Fri Jun 4 14:02:56 2010
New Revision: 105478
URL: http://llvm.org/viewvc/llvm-project?rev=105478&view=rev
Log:
Preserve more information from a block's original function declarator, if one
was given. Remove some unnecessary accounting from BlockScopeInfo. Handle
typedef'ed function types until such time as we decide not.
Modified:
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/CodeGen/blocks.c
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=105478&r1=105477&r2=105478&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Jun 4 14:02:56 2010
@@ -3147,7 +3147,7 @@
QualType BlockTy =
Expr->getType()->getAs<BlockPointerType>()->getPointeeType();
// Encode result type.
- getObjCEncodingForType(cast<FunctionType>(BlockTy)->getResultType(), S);
+ getObjCEncodingForType(BlockTy->getAs<FunctionType>()->getResultType(), S);
// Compute size of all parameters.
// Start with computing size of a pointer in number of bytes.
// FIXME: There might(should) be a better way of doing this computation!
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=105478&r1=105477&r2=105478&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Jun 4 14:02:56 2010
@@ -155,9 +155,6 @@
/// \brief Retains information about a block that is currently being parsed.
struct BlockScopeInfo : FunctionScopeInfo {
- llvm::SmallVector<ParmVarDecl*, 8> Params;
- bool hasPrototype;
- bool isVariadic;
bool hasBlockDeclRefExprs;
BlockDecl *TheDecl;
@@ -166,13 +163,17 @@
/// arguments etc.
Scope *TheScope;
- /// ReturnType - This will get set to block result type, by looking at
- /// return types, if any, in the block body.
+ /// ReturnType - The return type of the block, or null if the block
+ /// signature didn't provide an explicit return type.
QualType ReturnType;
+ /// BlockType - The function type of the block, if one was given.
+ /// Its return type may be BuiltinType::Dependent.
+ QualType FunctionType;
+
BlockScopeInfo(unsigned NumErrors, Scope *BlockScope, BlockDecl *Block)
- : FunctionScopeInfo(NumErrors), hasPrototype(false), isVariadic(false),
- hasBlockDeclRefExprs(false), TheDecl(Block), TheScope(BlockScope)
+ : FunctionScopeInfo(NumErrors), hasBlockDeclRefExprs(false),
+ TheDecl(Block), TheScope(BlockScope)
{
IsBlockInfo = true;
}
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=105478&r1=105477&r2=105478&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Jun 4 14:02:56 2010
@@ -511,7 +511,7 @@
BlockScopeInfo *CurBlock = getCurBlock();
bool isVariadic;
if (CurBlock)
- isVariadic = CurBlock->isVariadic;
+ isVariadic = CurBlock->TheDecl->isVariadic();
else if (FunctionDecl *FD = getCurFunctionDecl())
isVariadic = FD->isVariadic();
else
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=105478&r1=105477&r2=105478&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jun 4 14:02:56 2010
@@ -6980,19 +6980,19 @@
QualType T = GetTypeForDeclarator(ParamInfo, CurScope, &Sig);
CurBlock->TheDecl->setSignatureAsWritten(Sig);
+ bool isVariadic;
QualType RetTy;
if (const FunctionType *Fn = T->getAs<FunctionType>()) {
+ CurBlock->FunctionType = T;
RetTy = Fn->getResultType();
- CurBlock->hasPrototype = isa<FunctionProtoType>(Fn);
- CurBlock->isVariadic =
+ isVariadic =
!isa<FunctionProtoType>(Fn) || cast<FunctionProtoType>(Fn)->isVariadic();
} else {
RetTy = T;
- CurBlock->hasPrototype = true;
- CurBlock->isVariadic = false;
+ isVariadic = false;
}
- CurBlock->TheDecl->setIsVariadic(CurBlock->isVariadic);
+ CurBlock->TheDecl->setIsVariadic(isVariadic);
// Don't allow returning an array by value.
if (RetTy->isArrayType()) {
@@ -7008,11 +7008,14 @@
}
// Context.DependentTy is used as a placeholder for a missing block
- // return type.
+ // return type. TODO: what should we do with declarators like:
+ // ^ * { ... }
+ // If the answer is "apply template argument deduction"....
if (RetTy != Context.DependentTy)
CurBlock->ReturnType = RetTy;
// Push block parameters from the declarator if we had them.
+ llvm::SmallVector<ParmVarDecl*, 8> Params;
if (isa<FunctionProtoType>(T)) {
FunctionProtoTypeLoc TL = cast<FunctionProtoTypeLoc>(Sig->getTypeLoc());
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
@@ -7022,7 +7025,7 @@
!Param->isInvalidDecl() &&
!getLangOptions().CPlusPlus)
Diag(Param->getLocation(), diag::err_parameter_name_omitted);
- CurBlock->Params.push_back(Param);
+ Params.push_back(Param);
}
// Fake up parameter variables if we have a typedef, like
@@ -7034,19 +7037,18 @@
BuildParmVarDeclForTypedef(CurBlock->TheDecl,
ParamInfo.getSourceRange().getBegin(),
*I);
- CurBlock->Params.push_back(Param);
+ Params.push_back(Param);
}
}
- // Set the parmaeters on the block decl.
- if (!CurBlock->Params.empty())
- CurBlock->TheDecl->setParams(CurBlock->Params.data(),
- CurBlock->Params.size());
+ // Set the parameters on the block decl.
+ if (!Params.empty())
+ CurBlock->TheDecl->setParams(Params.data(), Params.size());
// Finally we can process decl attributes.
ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo);
- if (!CurBlock->isVariadic && CurBlock->TheDecl->getAttr<SentinelAttr>()) {
+ if (!isVariadic && CurBlock->TheDecl->getAttr<SentinelAttr>()) {
Diag(ParamInfo.getAttributes()->getLoc(),
diag::warn_attribute_sentinel_not_variadic) << 1;
// FIXME: remove the attribute.
@@ -7054,7 +7056,7 @@
// Put the parameter variables in scope. We can bail out immediately
// if we don't have any.
- if (CurBlock->Params.empty())
+ if (Params.empty())
return;
bool ShouldCheckShadow =
@@ -7099,22 +7101,52 @@
if (!BSI->ReturnType.isNull())
RetTy = BSI->ReturnType;
- llvm::SmallVector<QualType, 8> ArgTypes;
- for (unsigned i = 0, e = BSI->Params.size(); i != e; ++i)
- ArgTypes.push_back(BSI->Params[i]->getType());
-
bool NoReturn = BSI->TheDecl->getAttr<NoReturnAttr>();
QualType BlockTy;
- if (!BSI->hasPrototype)
- BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0, false, false, 0, 0,
- FunctionType::ExtInfo(NoReturn, 0, CC_Default));
- else
- BlockTy = Context.getFunctionType(RetTy, ArgTypes.data(), ArgTypes.size(),
- BSI->isVariadic, 0, false, false, 0, 0,
- FunctionType::ExtInfo(NoReturn, 0, CC_Default));
+
+ // If the user wrote a function type in some form, try to use that.
+ if (!BSI->FunctionType.isNull()) {
+ const FunctionType *FTy = BSI->FunctionType->getAs<FunctionType>();
+
+ FunctionType::ExtInfo Ext = FTy->getExtInfo();
+ if (NoReturn && !Ext.getNoReturn()) Ext = Ext.withNoReturn(true);
+
+ // Turn protoless block types into nullary block types.
+ if (isa<FunctionNoProtoType>(FTy)) {
+ BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0,
+ false, false, 0, 0, Ext);
+
+ // Otherwise, if we don't need to change anything about the function type,
+ // preserve its sugar structure.
+ } else if (FTy->getResultType() == RetTy &&
+ (!NoReturn || FTy->getNoReturnAttr())) {
+ BlockTy = BSI->FunctionType;
+
+ // Otherwise, make the minimal modifications to the function type.
+ } else {
+ const FunctionProtoType *FPT = cast<FunctionProtoType>(FTy);
+ BlockTy = Context.getFunctionType(RetTy,
+ FPT->arg_type_begin(),
+ FPT->getNumArgs(),
+ FPT->isVariadic(),
+ /*quals*/ 0,
+ FPT->hasExceptionSpec(),
+ FPT->hasAnyExceptionSpec(),
+ FPT->getNumExceptions(),
+ FPT->exception_begin(),
+ Ext);
+ }
+
+ // If we don't have a function type, just build one from nothing.
+ } else {
+ BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0,
+ false, false, 0, 0,
+ FunctionType::ExtInfo(NoReturn, 0, CC_Default));
+ }
// FIXME: Check that return/parameter types are complete/non-abstract
- DiagnoseUnusedParameters(BSI->Params.begin(), BSI->Params.end());
+ DiagnoseUnusedParameters(BSI->TheDecl->param_begin(),
+ BSI->TheDecl->param_end());
BlockTy = Context.getBlockPointerType(BlockTy);
// If needed, diagnose invalid gotos and switches in the block.
Modified: cfe/trunk/test/CodeGen/blocks.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/blocks.c?rev=105478&r1=105477&r2=105478&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/blocks.c (original)
+++ cfe/trunk/test/CodeGen/blocks.c Fri Jun 4 14:02:56 2010
@@ -27,3 +27,9 @@
^ { i = 1; }();
};
+typedef double ftype(double);
+// It's not clear that we *should* support this syntax, but until that decision
+// is made, we should support it properly and not crash.
+ftype ^test2 = ^ftype {
+ return 0;
+};
More information about the cfe-commits
mailing list