Provide rewriting suppport for use of __typeof__

in a declaration statement. Fixes radar 7628153.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95788 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Fariborz Jahanian 2010-02-10 18:54:22 +00:00
Родитель b2987d159a
Коммит 4c863ef92c
2 изменённых файлов: 59 добавлений и 1 удалений

Просмотреть файл

@ -263,6 +263,7 @@ namespace {
void RewriteFunctionDecl(FunctionDecl *FD);
void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
void RewriteTypeOfDecl(VarDecl *VD);
void RewriteObjCQualifiedInterfaceTypes(Expr *E);
bool needToScanForQualifiers(QualType T);
ObjCInterfaceDecl *isSuperReceiver(Expr *recExpr);
@ -2143,6 +2144,44 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
}
}
void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) {
QualType QT = ND->getType();
const Type* TypePtr = QT->getAs<Type>();
if (!isa<TypeOfExprType>(TypePtr))
return;
while (isa<TypeOfExprType>(TypePtr)) {
const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
TypePtr = QT->getAs<Type>();
}
// FIXME. This will not work for multiple declarators; as in:
// __typeof__(a) b,c,d;
std::string TypeAsString(QT.getAsString());
SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
const char *startBuf = SM->getCharacterData(DeclLoc);
if (ND->getInit()) {
std::string Name(ND->getNameAsString());
TypeAsString += " " + Name + " = ";
Expr *E = ND->getInit();
SourceLocation startLoc;
if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
startLoc = ECE->getLParenLoc();
else
startLoc = E->getLocStart();
startLoc = SM->getInstantiationLoc(startLoc);
const char *endBuf = SM->getCharacterData(startLoc);
ReplaceText(DeclLoc, endBuf-startBuf-1,
TypeAsString.c_str(), TypeAsString.size());
}
else {
SourceLocation X = ND->getLocEnd();
X = SM->getInstantiationLoc(X);
const char *endBuf = SM->getCharacterData(X);
ReplaceText(DeclLoc, endBuf-startBuf-1,
TypeAsString.c_str(), TypeAsString.size());
}
}
// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
void RewriteObjC::SynthSelGetUidFunctionDecl() {
IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
@ -5059,7 +5098,7 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
RewriteBlockPointerDecl(ND);
else if (ND->getType()->isFunctionPointerType())
CheckFunctionPointerDecl(ND->getType(), ND);
if (VarDecl *VD = dyn_cast<VarDecl>(SD))
if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
if (VD->hasAttr<BlocksAttr>()) {
static unsigned uniqueByrefDeclCount = 0;
assert(!BlockByRefDeclNo.count(ND) &&
@ -5067,6 +5106,9 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
RewriteByRefVar(VD);
}
else
RewriteTypeOfDecl(VD);
}
}
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
if (isTopLevelBlockPointerType(TD->getUnderlyingType()))

Просмотреть файл

@ -21,3 +21,19 @@ int main() {
// CHECK-LP: ((void (^)(void))_Block_copy((const void *)(b)))
// radar 7628153
void f() {
int a;
__typeof__(a) aVal = a;
char *a1t = (char *)@encode(__typeof__(a));
__typeof__(aVal) bVal;
char *a2t = (char *)@encode(__typeof__(bVal));
__typeof__(bVal) cVal = bVal;
char *a3t = (char *)@encode(__typeof__(cVal));
}
// CHECK-LP: int aVal = a;
// CHECK-LP: int bVal;