зеркало из https://github.com/microsoft/clang.git
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:
Родитель
b2987d159a
Коммит
4c863ef92c
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче