diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-04-13 21:20:57 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-04-13 21:20:57 +0000 |
commit | 183671e2d260930a8c43abc177f80f68cab041c0 (patch) | |
tree | 1e7ba3d7fad59387ee4d8072d8131c554a04e7e0 | |
parent | 4184ac847f91dc7a8644ad6c5a3e389923117eb3 (diff) | |
download | bcm5719-llvm-183671e2d260930a8c43abc177f80f68cab041c0.tar.gz bcm5719-llvm-183671e2d260930a8c43abc177f80f68cab041c0.zip |
PCH support for record decls/types and their fields. Now that we can
handle the definition of __builtin_va_list on x86-64, eliminate the
forced -triple in PCH tests to get better coverage.
llvm-svn: 68988
-rw-r--r-- | clang/include/clang/AST/Decl.h | 3 | ||||
-rw-r--r-- | clang/include/clang/Frontend/PCHBitCodes.h | 4 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHReader.cpp | 41 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHWriter.cpp | 19 | ||||
-rw-r--r-- | clang/test/PCH/enum.c | 6 | ||||
-rw-r--r-- | clang/test/PCH/line-directive.c | 6 | ||||
-rw-r--r-- | clang/test/PCH/struct.c | 24 | ||||
-rw-r--r-- | clang/test/PCH/struct.h | 25 | ||||
-rw-r--r-- | clang/test/PCH/types.c | 6 | ||||
-rw-r--r-- | clang/test/PCH/variables.c | 6 |
10 files changed, 122 insertions, 18 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index f1626890920..03ef88a0ec2 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -779,6 +779,9 @@ public: /// isMutable - Determines whether this field is mutable (C++ only). bool isMutable() const { return Mutable; } + /// \brief Set whether this field is mutable (C++ only). + void setMutable(bool M) { Mutable = M; } + /// isBitfield - Determines whether this field is a bitfield. bool isBitField() const { return BitWidth != NULL; } diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h index fe3d8ed86c1..14c59712ece 100644 --- a/clang/include/clang/Frontend/PCHBitCodes.h +++ b/clang/include/clang/Frontend/PCHBitCodes.h @@ -316,8 +316,12 @@ namespace clang { DECL_TYPEDEF, /// \brief An EnumDecl record. DECL_ENUM, + /// \brief A RecordDecl record. + DECL_RECORD, /// \brief An EnumConstantDecl record. DECL_ENUM_CONSTANT, + /// \brief A FieldDecl record. + DECL_FIELD, /// \brief A VarDecl record. DECL_VAR, /// \brief A record that stores the set of declarations that are diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index f735dd97ac1..adb4e5f6d77 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -50,8 +50,10 @@ namespace { void VisitTypedefDecl(TypedefDecl *TD); void VisitTagDecl(TagDecl *TD); void VisitEnumDecl(EnumDecl *ED); + void VisitRecordDecl(RecordDecl *RD); void VisitValueDecl(ValueDecl *VD); void VisitEnumConstantDecl(EnumConstantDecl *ECD); + void VisitFieldDecl(FieldDecl *FD); void VisitVarDecl(VarDecl *VD); std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC); @@ -106,6 +108,12 @@ void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) { ED->setIntegerType(Reader.GetType(Record[Idx++])); } +void PCHDeclReader::VisitRecordDecl(RecordDecl *RD) { + VisitTagDecl(RD); + RD->setHasFlexibleArrayMember(Record[Idx++]); + RD->setAnonymousStructOrUnion(Record[Idx++]); +} + void PCHDeclReader::VisitValueDecl(ValueDecl *VD) { VisitNamedDecl(VD); VD->setType(Reader.GetType(Record[Idx++])); @@ -113,10 +121,16 @@ void PCHDeclReader::VisitValueDecl(ValueDecl *VD) { void PCHDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) { VisitValueDecl(ECD); - // FIXME: initialization expression + // FIXME: read the initialization expression ECD->setInitVal(Reader.ReadAPSInt(Record, Idx)); } +void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) { + VisitValueDecl(FD); + FD->setMutable(Record[Idx++]); + // FIXME: Read the bit width. +} + void PCHDeclReader::VisitVarDecl(VarDecl *VD) { VisitValueDecl(VD); VD->setStorageClass((VarDecl::StorageClass)Record[Idx++]); @@ -911,9 +925,8 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { } case pch::TYPE_RECORD: - // FIXME: Deserialize RecordType - assert(false && "Cannot de-serialize record types yet"); - return QualType(); + assert(Record.size() == 1 && "Incorrect encoding of record type"); + return Context.getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0]))); case pch::TYPE_ENUM: assert(Record.size() == 1 && "Incorrect encoding of enum type"); @@ -989,6 +1002,15 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) { break; } + case pch::DECL_RECORD: { + RecordDecl *Record = RecordDecl::Create(Context, TagDecl::TK_struct, + 0, SourceLocation(), 0, 0); + LoadedDecl(Index, Record); + Reader.VisitRecordDecl(Record); + D = Record; + break; + } + case pch::DECL_ENUM_CONSTANT: { EnumConstantDecl *ECD = EnumConstantDecl::Create(Context, 0, SourceLocation(), 0, @@ -1000,6 +1022,15 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) { break; } + case pch::DECL_FIELD: { + FieldDecl *Field = FieldDecl::Create(Context, 0, SourceLocation(), 0, + QualType(), 0, false); + LoadedDecl(Index, Field); + Reader.VisitFieldDecl(Field); + D = Field; + break; + } + case pch::DECL_VAR: { VarDecl *Var = VarDecl::Create(Context, 0, SourceLocation(), 0, QualType(), VarDecl::None, SourceLocation()); @@ -1132,12 +1163,10 @@ bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC, Decls.clear(); unsigned Idx = 0; - // llvm::SmallVector<uintptr_t, 16> DeclIDs; while (Idx < Record.size()) { Decls.push_back(VisibleDeclaration()); Decls.back().Name = ReadDeclarationName(Record, Idx); - // FIXME: Don't actually read anything here! unsigned Size = Record[Idx++]; llvm::SmallVector<unsigned, 4> & LoadedDecls = Decls.back().Declarations; diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 2ba8e9eeb61..6758a506998 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -254,8 +254,10 @@ namespace { void VisitTypedefDecl(TypedefDecl *D); void VisitTagDecl(TagDecl *D); void VisitEnumDecl(EnumDecl *D); + void VisitRecordDecl(RecordDecl *D); void VisitValueDecl(ValueDecl *D); void VisitEnumConstantDecl(EnumConstantDecl *D); + void VisitFieldDecl(FieldDecl *D); void VisitVarDecl(VarDecl *D); void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, uint64_t VisibleOffset); @@ -306,6 +308,13 @@ void PCHDeclWriter::VisitEnumDecl(EnumDecl *D) { Code = pch::DECL_ENUM; } +void PCHDeclWriter::VisitRecordDecl(RecordDecl *D) { + VisitTagDecl(D); + Record.push_back(D->hasFlexibleArrayMember()); + Record.push_back(D->isAnonymousStructOrUnion()); + Code = pch::DECL_RECORD; +} + void PCHDeclWriter::VisitValueDecl(ValueDecl *D) { VisitNamedDecl(D); Writer.AddTypeRef(D->getType(), Record); @@ -318,6 +327,13 @@ void PCHDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) { Code = pch::DECL_ENUM_CONSTANT; } +void PCHDeclWriter::VisitFieldDecl(FieldDecl *D) { + VisitValueDecl(D); + Record.push_back(D->isMutable()); + // FIXME: Writer.AddExprRef(D->getBitWidth()); + Code = pch::DECL_FIELD; +} + void PCHDeclWriter::VisitVarDecl(VarDecl *D) { VisitValueDecl(D); Record.push_back(D->getStorageClass()); @@ -798,6 +814,9 @@ uint64_t PCHWriter::WriteDeclContextVisibleBlock(ASTContext &Context, uint64_t Offset = S.GetCurrentBitNo(); RecordData Record; StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); + if (!Map) + return 0; + for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); D != DEnd; ++D) { AddDeclarationName(D->first, Record); diff --git a/clang/test/PCH/enum.c b/clang/test/PCH/enum.c index 92869b6bc83..f3e8a09d93e 100644 --- a/clang/test/PCH/enum.c +++ b/clang/test/PCH/enum.c @@ -1,9 +1,9 @@ // Test this without pch. -// RUN: clang-cc -triple=i686-apple-darwin9 -include %S/enum.h -fsyntax-only -verify %s +// RUN: clang-cc -include %S/enum.h -fsyntax-only -verify %s // Test with pch. -// RUN: clang-cc -emit-pch -triple=i686-apple-darwin9 -o %t %S/enum.h && -// RUN: clang-cc -triple=i686-apple-darwin9 -include-pch %t -fsyntax-only -verify %s +// RUN: clang-cc -emit-pch -o %t %S/enum.h && +// RUN: clang-cc -include-pch %t -fsyntax-only -verify %s int i = Red; diff --git a/clang/test/PCH/line-directive.c b/clang/test/PCH/line-directive.c index 87aa4b0a528..ed54842aa74 100644 --- a/clang/test/PCH/line-directive.c +++ b/clang/test/PCH/line-directive.c @@ -1,9 +1,9 @@ // Test this without pch. -// RUN: clang-cc -triple=i686-apple-darwin9 -include %S/line-directive.h -fsyntax-only %s 2>&1|grep "25:5" +// RUN: clang-cc -include %S/line-directive.h -fsyntax-only %s 2>&1|grep "25:5" // Test with pch. -// RUN: clang-cc -emit-pch -triple=i686-apple-darwin9 -o %t %S/line-directive.h && -// RUN: clang-cc -triple=i686-apple-darwin9 -include-pch %t -fsyntax-only %s 2>&1|grep "25:5" +// RUN: clang-cc -emit-pch -o %t %S/line-directive.h && +// RUN: clang-cc -include-pch %t -fsyntax-only %s 2>&1|grep "25:5" double x; // expected-error{{redefinition of 'x' with a different type}} diff --git a/clang/test/PCH/struct.c b/clang/test/PCH/struct.c new file mode 100644 index 00000000000..c81ec469c58 --- /dev/null +++ b/clang/test/PCH/struct.c @@ -0,0 +1,24 @@ +// Test this without pch. +// RUN: clang-cc -include %S/struct.h -fsyntax-only -verify %s + +// Test with pch. +// RUN: clang-cc -emit-pch -o %t %S/struct.h && +// RUN: clang-cc -include-pch %t -fsyntax-only -verify %s + +struct Point *p1; + +float getX(struct Point *p1) { + return p1->x; +} + +void *get_fun_ptr() { + return fun->is_ptr? fun->ptr : 0; +} + +struct Fun2 { + int very_fun; +}; + +int get_very_fun() { + return fun2->very_fun; +} diff --git a/clang/test/PCH/struct.h b/clang/test/PCH/struct.h new file mode 100644 index 00000000000..e3d85abaaeb --- /dev/null +++ b/clang/test/PCH/struct.h @@ -0,0 +1,25 @@ +// Used with the struct.c test + +struct Point { + float x, y, z; +}; + +struct Point2 { + float xValue, yValue, zValue; +}; + +struct Fun; + +struct Fun *fun; + +struct Fun { + int is_ptr; + + union { + void *ptr; + int *integer; + }; +}; + +struct Fun2; +struct Fun2 *fun2; diff --git a/clang/test/PCH/types.c b/clang/test/PCH/types.c index 764efe77305..e62a4bbe3bf 100644 --- a/clang/test/PCH/types.c +++ b/clang/test/PCH/types.c @@ -1,9 +1,9 @@ // Test this without pch. -// RUN: clang-cc -triple=i686-apple-darwin9 -fblocks -include %S/types.h -fsyntax-only -verify %s +// RUN: clang-cc -fblocks -include %S/types.h -fsyntax-only -verify %s // Test with pch. -// RUN: clang-cc -emit-pch -triple=i686-apple-darwin9 -fblocks -o %t %S/types.h && -// RUN: clang-cc -triple=i686-apple-darwin9 -fblocks -include-pch %t -fsyntax-only -verify %s +// RUN: clang-cc -emit-pch -fblocks -o %t %S/types.h && +// RUN: clang-cc -fblocks -include-pch %t -fsyntax-only -verify %s // FIXME: TYPE_EXT_QUAL // FIXME: TYPE_FIXED_WIDTH_INT diff --git a/clang/test/PCH/variables.c b/clang/test/PCH/variables.c index ec1657617ea..4f42e504816 100644 --- a/clang/test/PCH/variables.c +++ b/clang/test/PCH/variables.c @@ -1,9 +1,9 @@ // Test this without pch. -// RUN: clang-cc -triple=i686-apple-darwin9 -include %S/variables.h -fsyntax-only -verify %s +// RUN: clang-cc -include %S/variables.h -fsyntax-only -verify %s // Test with pch. -// RUN: clang-cc -emit-pch -triple=i686-apple-darwin9 -o %t %S/variables.h && -// RUN: clang-cc -triple=i686-apple-darwin9 -include-pch %t -fsyntax-only -verify %s +// RUN: clang-cc -emit-pch -o %t %S/variables.h && +// RUN: clang-cc -include-pch %t -fsyntax-only -verify %s int *ip2 = &x; float *fp = &ip; // expected-warning{{incompatible pointer types}} |