From 2bd24ba6d10f8c811c8e2a57c8397e07082ba497 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 29 Oct 2007 23:37:31 +0000 Subject: [PATCH] VariableArrayTypes (VLAs) without a size expression are now uniqued and inserted into a FoldingSet owned by ASTContext. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43482 91177308-0d34-0410-b5e6-96231b3b80d8 --- AST/ASTContext.cpp | 48 ++++++++++++++++++++++++++++++---- include/clang/AST/ASTContext.h | 3 ++- include/clang/AST/Type.h | 14 +++++++++- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index 93d4232bf2..72511bd7b0 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -451,11 +451,49 @@ QualType ASTContext::getConstantArrayType(QualType EltTy, QualType ASTContext::getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned EltTypeQuals) { - // Since we don't unique expressions, it isn't possible to unique VLA's. - ArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts, - ASM, EltTypeQuals); - Types.push_back(New); - return QualType(New, 0); + if (NumElts) { + // Since we don't unique expressions, it isn't possible to unique VLA's + // that have an expression provided for their size. + + ArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts, + ASM, EltTypeQuals); + + // FIXME: Also add non-uniqued VLAs into a list of their own. + Types.push_back(New); + return QualType(New, 0); + } + else { + // No size is provided for the VLA. These we can unique. + llvm::FoldingSetNodeID ID; + VariableArrayType::Profile(ID, EltTy); + + void *InsertPos = 0; + if (VariableArrayType *ATP = + IncompleteVariableArrayTypes.FindNodeOrInsertPos(ID, InsertPos)) + return QualType(ATP, 0); + + // If the element type isn't canonical, this won't be a canonical type + // either, so fill in the canonical type field. + QualType Canonical; + + if (!EltTy->isCanonical()) { + Canonical = getVariableArrayType(EltTy.getCanonicalType(), NumElts, + ASM, EltTypeQuals); + + // Get the new insert position for the node we care about. + VariableArrayType *NewIP = + IncompleteVariableArrayTypes.FindNodeOrInsertPos(ID, InsertPos); + + assert(NewIP == 0 && "Shouldn't be in the map!"); + } + + VariableArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts, + ASM, EltTypeQuals); + + IncompleteVariableArrayTypes.InsertNode(New, InsertPos); + Types.push_back(New); + return QualType(New, 0); + } } /// getVectorType - Return the unique reference to a vector type of diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 3169726a76..48e7e13c90 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -29,12 +29,13 @@ namespace clang { /// ASTContext - This class holds long-lived AST nodes (such as types and /// decls) that can be referred to throughout the semantic analysis of a file. -class ASTContext { +class ASTContext { std::vector Types; llvm::FoldingSet ComplexTypes; llvm::FoldingSet PointerTypes; llvm::FoldingSet ReferenceTypes; llvm::FoldingSet ArrayTypes; + llvm::FoldingSet IncompleteVariableArrayTypes; llvm::FoldingSet VectorTypes; llvm::FoldingSet FunctionTypeNoProtos; llvm::FoldingSet FunctionTypeProtos; diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 59178b8d9b..052f5801c4 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -573,7 +573,7 @@ public: }; // FIXME: VariableArrayType's aren't uniqued (since expressions aren't). -class VariableArrayType : public ArrayType { +class VariableArrayType : public ArrayType, public llvm::FoldingSetNode { /// SizeExpr - An assignment expression. VLA's are only permitted within /// a function block. Expr *SizeExpr; @@ -593,6 +593,18 @@ public: static bool classof(const VariableArrayType *) { return true; } friend class StmtIteratorBase; + + void Profile(llvm::FoldingSetNodeID &ID) { + assert (SizeExpr == NULL + && "Can only unique VariableArrayTypes with no specified size."); + + Profile(ID, getElementType()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, QualType ET) { + ID.AddPointer(ET.getAsOpaquePtr()); + } + // FIXME: Who owns VariableArrayType's? What are the semantics // for serialization. }; -- 2.50.1