Author: cornedbee Date: Thu Apr 30 14:20:55 2009 New Revision: 70506 URL: http://llvm.org/viewvc/llvm-project?rev=70506&view=rev Log: Make a home for exception specs in the AST. Now Sema can hook them up.
Modified: cfe/trunk/include/clang/AST/ASTContext.h cfe/trunk/include/clang/AST/Type.h cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/AST/Type.cpp cfe/trunk/lib/Frontend/PCHReader.cpp cfe/trunk/lib/Frontend/PCHWriter.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp Modified: cfe/trunk/include/clang/AST/ASTContext.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=70506&r1=70505&r2=70506&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ASTContext.h (original) +++ cfe/trunk/include/clang/AST/ASTContext.h Thu Apr 30 14:20:55 2009 @@ -292,12 +292,14 @@ /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. /// QualType getFunctionNoProtoType(QualType ResultTy); - + /// getFunctionType - Return a normal function type with a typed argument /// list. isVariadic indicates whether the argument list includes '...'. QualType getFunctionType(QualType ResultTy, const QualType *ArgArray, unsigned NumArgs, bool isVariadic, - unsigned TypeQuals); + unsigned TypeQuals, bool hasExceptionSpec = false, + bool hasAnyExceptionSpec = false, + unsigned NumExs = 0, const QualType *ExArray = 0); /// getTypeDeclType - Return the unique reference to the type for /// the specified type declaration. Modified: cfe/trunk/include/clang/AST/Type.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=70506&r1=70505&r2=70506&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Type.h (original) +++ cfe/trunk/include/clang/AST/Type.h Thu Apr 30 14:20:55 2009 @@ -1152,23 +1152,42 @@ } FunctionProtoType(QualType Result, const QualType *ArgArray, unsigned numArgs, - bool isVariadic, unsigned typeQuals, QualType Canonical) + bool isVariadic, unsigned typeQuals, bool hasExs, + bool hasAnyExs, const QualType *ExArray, + unsigned numExs, QualType Canonical) : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical, (Result->isDependentType() || hasAnyDependentType(ArgArray, numArgs))), - NumArgs(numArgs) { + NumArgs(numArgs), NumExceptions(numExs), HasExceptionSpec(hasExs), + AnyExceptionSpec(hasAnyExs) { // Fill in the trailing argument array. - QualType *ArgInfo = reinterpret_cast<QualType *>(this+1);; + QualType *ArgInfo = reinterpret_cast<QualType*>(this+1); for (unsigned i = 0; i != numArgs; ++i) ArgInfo[i] = ArgArray[i]; + // Fill in the exception array. + QualType *Ex = ArgInfo + numArgs; + for (unsigned i = 0; i != numExs; ++i) + Ex[i] = ExArray[i]; } - + /// NumArgs - The number of arguments this function has, not counting '...'. - unsigned NumArgs; - + unsigned NumArgs : 20; + + /// NumExceptions - The number of types in the exception spec, if any. + unsigned NumExceptions : 10; + + /// HasExceptionSpec - Whether this function has an exception spec at all. + bool HasExceptionSpec : 1; + + /// AnyExceptionSpec - Whether this function has a throw(...) spec. + bool AnyExceptionSpec : 1; + /// ArgInfo - There is an variable size array after the class in memory that /// holds the argument types. - + + /// Exceptions - There is another variable size array after ArgInfo that + /// holds the exception types. + friend class ASTContext; // ASTContext creates these. public: @@ -1177,7 +1196,15 @@ assert(i < NumArgs && "Invalid argument number!"); return arg_type_begin()[i]; } - + + bool hasExceptionSpec() const { return HasExceptionSpec; } + bool hasAnyExceptionSpec() const { return AnyExceptionSpec; } + unsigned getNumExceptions() const { return NumExceptions; } + QualType getExceptionType(unsigned i) const { + assert(i < NumExceptions && "Invalid exception number!"); + return exception_begin()[i]; + } + bool isVariadic() const { return getSubClassData(); } unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); } @@ -1186,18 +1213,29 @@ return reinterpret_cast<const QualType *>(this+1); } arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; } - + + typedef const QualType *exception_iterator; + exception_iterator exception_begin() const { + // exceptions begin where arguments end + return arg_type_end(); + } + exception_iterator exception_end() const { + return exception_begin() + NumExceptions; + } + virtual void getAsStringInternal(std::string &InnerString) const; static bool classof(const Type *T) { return T->getTypeClass() == FunctionProto; } static bool classof(const FunctionProtoType *) { return true; } - + void Profile(llvm::FoldingSetNodeID &ID); static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, arg_type_iterator ArgTys, unsigned NumArgs, - bool isVariadic, unsigned TypeQuals); + bool isVariadic, unsigned TypeQuals, + bool hasExceptionSpec, bool anyExceptionSpec, + unsigned NumExceptions, exception_iterator Exs); }; Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=70506&r1=70505&r2=70506&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Thu Apr 30 14:20:55 2009 @@ -1321,12 +1321,15 @@ /// list. isVariadic indicates whether the argument list includes '...'. QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, unsigned NumArgs, bool isVariadic, - unsigned TypeQuals) { + unsigned TypeQuals, bool hasExceptionSpec, + bool hasAnyExceptionSpec, unsigned NumExs, + const QualType *ExArray) { // Unique functions, to guarantee there is only one function of a particular // structure. llvm::FoldingSetNodeID ID; FunctionProtoType::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic, - TypeQuals); + TypeQuals, hasExceptionSpec, hasAnyExceptionSpec, + NumExs, ExArray); void *InsertPos = 0; if (FunctionProtoType *FTP = @@ -1346,24 +1349,32 @@ CanonicalArgs.reserve(NumArgs); for (unsigned i = 0; i != NumArgs; ++i) CanonicalArgs.push_back(getCanonicalType(ArgArray[i])); - + llvm::SmallVector<QualType, 2> CanonicalExs; + CanonicalExs.reserve(NumExs); + for (unsigned i = 0; i != NumExs; ++i) + CanonicalExs.push_back(getCanonicalType(ExArray[i])); + Canonical = getFunctionType(getCanonicalType(ResultTy), &CanonicalArgs[0], NumArgs, - isVariadic, TypeQuals); - + isVariadic, TypeQuals, hasExceptionSpec, + hasAnyExceptionSpec, NumExs, &CanonicalExs[0]); + // Get the new insert position for the node we care about. FunctionProtoType *NewIP = FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos); assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } - + // FunctionProtoType objects are allocated with extra bytes after them - // for a variable size array (for parameter types) at the end of them. + // for two variable size arrays (for parameter and exception types) at the + // end of them. FunctionProtoType *FTP = - (FunctionProtoType*)Allocate(sizeof(FunctionProtoType) + - NumArgs*sizeof(QualType), 8); + (FunctionProtoType*)Allocate(sizeof(FunctionProtoType) + + NumArgs*sizeof(QualType) + + NumExs*sizeof(QualType), 8); new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, isVariadic, - TypeQuals, Canonical); + TypeQuals, hasExceptionSpec, hasAnyExceptionSpec, + ExArray, NumExs, Canonical); Types.push_back(FTP); FunctionProtoTypes.InsertNode(FTP, InsertPos); return QualType(FTP, 0); @@ -2930,6 +2941,8 @@ allRTypes = false; if (lproto && rproto) { // two C99 style function prototypes + assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() && + "C++ shouldn't be here"); unsigned lproto_nargs = lproto->getNumArgs(); unsigned rproto_nargs = rproto->getNumArgs(); @@ -2968,6 +2981,7 @@ const FunctionProtoType *proto = lproto ? lproto : rproto; if (proto) { + assert(!proto->hasExceptionSpec() && "C++ shouldn't be here"); if (proto->isVariadic()) return QualType(); // Check that the types are compatible with the types that // would result from default argument promotions (C99 6.7.5.3p15). Modified: cfe/trunk/lib/AST/Type.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=70506&r1=70505&r2=70506&view=diff ============================================================================== --- cfe/trunk/lib/AST/Type.cpp (original) +++ cfe/trunk/lib/AST/Type.cpp Thu Apr 30 14:20:55 2009 @@ -920,17 +920,26 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, arg_type_iterator ArgTys, unsigned NumArgs, bool isVariadic, - unsigned TypeQuals) { + unsigned TypeQuals, bool hasExceptionSpec, + bool anyExceptionSpec, unsigned NumExceptions, + exception_iterator Exs) { ID.AddPointer(Result.getAsOpaquePtr()); for (unsigned i = 0; i != NumArgs; ++i) ID.AddPointer(ArgTys[i].getAsOpaquePtr()); ID.AddInteger(isVariadic); ID.AddInteger(TypeQuals); + ID.AddInteger(hasExceptionSpec); + if (hasExceptionSpec) { + ID.AddInteger(anyExceptionSpec); + for(unsigned i = 0; i != NumExceptions; ++i) + ID.AddPointer(Exs[i].getAsOpaquePtr()); + } } void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic(), - getTypeQuals()); + getTypeQuals(), hasExceptionSpec(), hasAnyExceptionSpec(), + getNumExceptions(), exception_begin()); } void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID, Modified: cfe/trunk/lib/Frontend/PCHReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=70506&r1=70505&r2=70506&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/PCHReader.cpp (original) +++ cfe/trunk/lib/Frontend/PCHReader.cpp Thu Apr 30 14:20:55 2009 @@ -1584,8 +1584,16 @@ ParamTypes.push_back(GetType(Record[Idx++])); bool isVariadic = Record[Idx++]; unsigned Quals = Record[Idx++]; + bool hasExceptionSpec = Record[Idx++]; + bool hasAnyExceptionSpec = Record[Idx++]; + unsigned NumExceptions = Record[Idx++]; + llvm::SmallVector<QualType, 2> Exceptions; + for (unsigned I = 0; I != NumExceptions; ++I) + Exceptions.push_back(GetType(Record[Idx++])); return Context->getFunctionType(ResultType, &ParamTypes[0], NumParams, - isVariadic, Quals); + isVariadic, Quals, hasExceptionSpec, + hasAnyExceptionSpec, NumExceptions, + &Exceptions[0]); } case pch::TYPE_TYPEDEF: Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=70506&r1=70505&r2=70506&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/PCHWriter.cpp (original) +++ cfe/trunk/lib/Frontend/PCHWriter.cpp Thu Apr 30 14:20:55 2009 @@ -161,6 +161,11 @@ Writer.AddTypeRef(T->getArgType(I), Record); Record.push_back(T->isVariadic()); Record.push_back(T->getTypeQuals()); + Record.push_back(T->hasExceptionSpec()); + Record.push_back(T->hasAnyExceptionSpec()); + Record.push_back(T->getNumExceptions()); + for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) + Writer.AddTypeRef(T->getExceptionType(I), Record); Code = pch::TYPE_FUNCTION_PROTO; } Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=70506&r1=70505&r2=70506&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Apr 30 14:20:55 2009 @@ -714,6 +714,7 @@ (OldProto = dyn_cast<FunctionProtoType>(OldFuncType))) { // The old declaration provided a function prototype, but the // new declaration does not. Merge in the prototype. + assert(!OldProto->hasExceptionSpec() && "Exception spec in C"); llvm::SmallVector<QualType, 16> ParamTypes(OldProto->arg_type_begin(), OldProto->arg_type_end()); NewQType = Context.getFunctionType(NewFuncType->getResultType(), Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=70506&r1=70505&r2=70506&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Apr 30 14:20:55 2009 @@ -995,6 +995,9 @@ QualType ClassType = Context.getTypeDeclType(ClassDecl); ClassType = Context.getCanonicalType(ClassType); + // FIXME: Implicit declarations have exception specifications, which are + // the union of the specifications of the implicitly called functions. + if (!ClassDecl->hasUserDeclaredConstructor()) { // C++ [class.ctor]p5: // A default constructor for a class X is a constructor of class X _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits