summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-04-13 21:20:57 +0000
committerDouglas Gregor <dgregor@apple.com>2009-04-13 21:20:57 +0000
commit183671e2d260930a8c43abc177f80f68cab041c0 (patch)
tree1e7ba3d7fad59387ee4d8072d8131c554a04e7e0
parent4184ac847f91dc7a8644ad6c5a3e389923117eb3 (diff)
downloadbcm5719-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.h3
-rw-r--r--clang/include/clang/Frontend/PCHBitCodes.h4
-rw-r--r--clang/lib/Frontend/PCHReader.cpp41
-rw-r--r--clang/lib/Frontend/PCHWriter.cpp19
-rw-r--r--clang/test/PCH/enum.c6
-rw-r--r--clang/test/PCH/line-directive.c6
-rw-r--r--clang/test/PCH/struct.c24
-rw-r--r--clang/test/PCH/struct.h25
-rw-r--r--clang/test/PCH/types.c6
-rw-r--r--clang/test/PCH/variables.c6
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}}
OpenPOWER on IntegriCloud