diff options
-rw-r--r-- | clang/include/clang/AST/Decl.h | 22 | ||||
-rw-r--r-- | clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h | 2 | ||||
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 12 | ||||
-rw-r--r-- | clang/lib/AST/Decl.cpp | 9 | ||||
-rw-r--r-- | clang/lib/AST/DeclSerialization.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 22 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/encode-test.m | 15 |
7 files changed, 65 insertions, 20 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 8aaf5d6b6cd..aaae0921929 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -472,10 +472,10 @@ class ParmVarDecl : public VarDecl { /// Default argument, if any. [C++ Only] Expr *DefaultArg; protected: - ParmVarDecl(DeclContext *DC, SourceLocation L, + ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, Expr *DefArg, ScopedDecl *PrevDecl) - : VarDecl(ParmVar, DC, L, Id, T, S, PrevDecl), + : VarDecl(DK, DC, L, Id, T, S, PrevDecl), objcDeclQualifier(OBJC_TQ_None), DefaultArg(DefArg) {} public: @@ -495,8 +495,13 @@ public: Expr *getDefaultArg() { return DefaultArg; } void setDefaultArg(Expr *defarg) { DefaultArg = defarg; } + QualType getOriginalType() const; + // Implement isa/cast/dyncast/etc. - static bool classof(const Decl *D) { return D->getKind() == ParmVar; } + static bool classof(const Decl *D) { + return (D->getKind() == ParmVar || + D->getKind() == OriginalParmVar); + } static bool classof(const ParmVarDecl *D) { return true; } protected: @@ -514,22 +519,23 @@ protected: /// parameter to the function with its original type. /// class ParmVarWithOriginalTypeDecl : public ParmVarDecl { -private: + friend class ParmVarDecl; +protected: QualType OriginalType; - +private: ParmVarWithOriginalTypeDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, QualType OT, StorageClass S, Expr *DefArg, ScopedDecl *PrevDecl) - : ParmVarDecl(DC, L, Id, T, S, DefArg, PrevDecl), OriginalType(OT) {} + : ParmVarDecl(OriginalParmVar, + DC, L, Id, T, S, DefArg, PrevDecl), OriginalType(OT) {} public: static ParmVarWithOriginalTypeDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,IdentifierInfo *Id, QualType T, QualType OT, StorageClass S, Expr *DefArg, ScopedDecl *PrevDecl); - QualType getQualType() const { return OriginalType; } - + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == OriginalParmVar; } static bool classof(const ParmVarWithOriginalTypeDecl *D) { return true; } diff --git a/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h index 322070b380a..e9228b69ce4 100644 --- a/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h +++ b/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h @@ -59,6 +59,7 @@ public: DISPATCH_CASE(Function,FunctionDecl) DISPATCH_CASE(Var,VarDecl) DISPATCH_CASE(ParmVar,ParmVarDecl) // FIXME: (same) + DISPATCH_CASE(OriginalParmVar,ParmVarWithOriginalTypeDecl) // FIXME: (same) DISPATCH_CASE(ImplicitParam,ImplicitParamDecl) DISPATCH_CASE(EnumConstant,EnumConstantDecl) DISPATCH_CASE(Typedef,TypedefDecl) @@ -71,6 +72,7 @@ public: DEFAULT_DISPATCH(VarDecl) DEFAULT_DISPATCH(FunctionDecl) + DEFAULT_DISPATCH_VARDECL(ParmVarWithOriginalTypeDecl) DEFAULT_DISPATCH_VARDECL(ParmVarDecl) DEFAULT_DISPATCH(ImplicitParamDecl) DEFAULT_DISPATCH(EnumConstantDecl) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index d03ed41a152..791e38633b4 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1638,11 +1638,17 @@ void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, // Argument types. ParmOffset = 2 * PtrSize; for (int i = 0; i < NumOfParams; i++) { - QualType PType = Decl->getParamDecl(i)->getType(); + ParmVarDecl *PVDecl = Decl->getParamDecl(i); + QualType PType = PVDecl->getOriginalType(); + if (const ArrayType *AT = + dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) + // Use array's original type only if it has known number of + // elements. + if (!dyn_cast<ConstantArrayType>(AT)) + PType = PVDecl->getType(); // Process argument qualifiers for user supplied arguments; such as, // 'in', 'inout', etc. - getObjCEncodingForTypeQualifier( - Decl->getParamDecl(i)->getObjCDeclQualifier(), S); + getObjCEncodingForTypeQualifier(PVDecl->getObjCDeclQualifier(), S); getObjCEncodingForType(PType, S); S += llvm::utostr(ParmOffset); ParmOffset += getObjCEncodingTypeSize(PType); diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 021becc85a2..3edf8a02efb 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -54,7 +54,14 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, QualType T, StorageClass S, Expr *DefArg, ScopedDecl *PrevDecl) { void *Mem = C.getAllocator().Allocate<ParmVarDecl>(); - return new (Mem) ParmVarDecl(DC, L, Id, T, S, DefArg, PrevDecl); + return new (Mem) ParmVarDecl(ParmVar, DC, L, Id, T, S, DefArg, PrevDecl); +} + +QualType ParmVarDecl::getOriginalType() const { + if (const ParmVarWithOriginalTypeDecl *PVD = + dyn_cast<ParmVarWithOriginalTypeDecl>(this)) + return PVD->OriginalType; + return getType(); } ParmVarWithOriginalTypeDecl *ParmVarWithOriginalTypeDecl::Create( diff --git a/clang/lib/AST/DeclSerialization.cpp b/clang/lib/AST/DeclSerialization.cpp index c09b0edca7b..7f6b50420d9 100644 --- a/clang/lib/AST/DeclSerialization.cpp +++ b/clang/lib/AST/DeclSerialization.cpp @@ -399,7 +399,8 @@ void ParmVarDecl::EmitImpl(llvm::Serializer& S) const { ParmVarDecl* ParmVarDecl::CreateImpl(Deserializer& D, ASTContext& C) { void *Mem = C.getAllocator().Allocate<ParmVarDecl>(); ParmVarDecl* decl = new (Mem) - ParmVarDecl(0, SourceLocation(), NULL, QualType(), None, NULL, NULL); + ParmVarDecl(ParmVar, + 0, SourceLocation(), NULL, QualType(), None, NULL, NULL); decl->VarDecl::ReadImpl(D, C); decl->objcDeclQualifier = static_cast<ObjCDeclQualifier>(D.ReadInt()); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index d4cef9b0de1..7759bac681f 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1236,21 +1236,31 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( for (unsigned i = 0; i < Sel.getNumArgs(); i++) { // FIXME: arg->AttrList must be stored too! - QualType argType; + QualType argType, originalArgType; if (ArgTypes[i]) { argType = QualType::getFromOpaquePtr(ArgTypes[i]); // Perform the default array/function conversions (C99 6.7.5.3p[7,8]). - if (argType->isArrayType()) // (char *[]) -> (char **) + if (argType->isArrayType()) { // (char *[]) -> (char **) + originalArgType = argType; argType = Context.getArrayDecayedType(argType); + } else if (argType->isFunctionType()) argType = Context.getPointerType(argType); } else argType = Context.getObjCIdType(); - ParmVarDecl* Param = ParmVarDecl::Create(Context, ObjCMethod, - SourceLocation(/*FIXME*/), - ArgNames[i], argType, - VarDecl::None, 0, 0); + ParmVarDecl* Param; + if (originalArgType.isNull()) + Param = ParmVarDecl::Create(Context, ObjCMethod, + SourceLocation(/*FIXME*/), + ArgNames[i], argType, + VarDecl::None, 0, 0); + else + Param = ParmVarWithOriginalTypeDecl::Create(Context, ObjCMethod, + SourceLocation(/*FIXME*/), + ArgNames[i], argType, originalArgType, + VarDecl::None, 0, 0); + Param->setObjCDeclQualifier( CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier())); Params.push_back(Param); diff --git a/clang/test/CodeGenObjC/encode-test.m b/clang/test/CodeGenObjC/encode-test.m index 109f0573e52..b07503d5346 100644 --- a/clang/test/CodeGenObjC/encode-test.m +++ b/clang/test/CodeGenObjC/encode-test.m @@ -1,7 +1,8 @@ // RUN: clang -fnext-runtime -emit-llvm -o %t %s && // RUN: grep -e "\^{Innermost=CC}" %t | count 1 && // RUN: grep -e "{Derived=#ib32b8b3b8sb16b8b8b2b8ccb6}" %t | count 1 && -// RUN: grep -e "{B1=#@c}" %t | count 1 +// RUN: grep -e "{B1=#@c}" %t | count 1 && +// RUN: grep -e "v12@0:4\[3\[4{Test=i}]]8" %t | count 1 @class Int1; @@ -60,6 +61,18 @@ struct Innermost { @implementation B1 @end +@interface Test +{ + int ivar; +} +-(void) test3: (Test [3] [4])b ; +@end + +@implementation Test +-(void) test3: (Test [3] [4])b {} +@end + + int main() { const char *en = @encode(Derived); |