forked from OSchip/llvm-project
Add PCH support for enumerations and enumerators.
llvm-svn: 68974
This commit is contained in:
parent
0431504fb2
commit
1daeb69f95
|
@ -992,6 +992,8 @@ public:
|
|||
return TagKind(TagDeclKind);
|
||||
}
|
||||
|
||||
void setTagKind(TagKind TK) { TagDeclKind = TK; }
|
||||
|
||||
bool isStruct() const { return getTagKind() == TK_struct; }
|
||||
bool isClass() const { return getTagKind() == TK_class; }
|
||||
bool isUnion() const { return getTagKind() == TK_union; }
|
||||
|
@ -1013,7 +1015,6 @@ public:
|
|||
return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
|
||||
}
|
||||
|
||||
protected:
|
||||
void setDefinition(bool V) { IsDefinition = V; }
|
||||
};
|
||||
|
||||
|
@ -1059,7 +1060,10 @@ public:
|
|||
/// getIntegerType - Return the integer type this enum decl corresponds to.
|
||||
/// This returns a null qualtype for an enum forward definition.
|
||||
QualType getIntegerType() const { return IntegerType; }
|
||||
|
||||
|
||||
/// \brief Set the underlying integer type.
|
||||
void setIntegerType(QualType T) { IntegerType = T; }
|
||||
|
||||
static bool classof(const Decl *D) { return D->getKind() == Enum; }
|
||||
static bool classof(const EnumDecl *D) { return true; }
|
||||
|
||||
|
|
|
@ -314,6 +314,10 @@ namespace clang {
|
|||
DECL_TRANSLATION_UNIT = 1,
|
||||
/// \brief A TypedefDecl record.
|
||||
DECL_TYPEDEF,
|
||||
/// \brief An EnumDecl record.
|
||||
DECL_ENUM,
|
||||
/// \brief An EnumConstantDecl record.
|
||||
DECL_ENUM_CONSTANT,
|
||||
/// \brief A VarDecl record.
|
||||
DECL_VAR,
|
||||
/// \brief A record that stores the set of declarations that are
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
@ -201,6 +203,12 @@ public:
|
|||
return DecodeIdentifierInfo(Record[Idx++]);
|
||||
}
|
||||
DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx);
|
||||
|
||||
/// \brief Read an integral value
|
||||
llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);
|
||||
|
||||
/// \brief Read a signed integral value
|
||||
llvm::APSInt ReadAPSInt(const RecordData &Record, unsigned &Idx);
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
|
|
@ -112,6 +112,9 @@ public:
|
|||
/// \brief Emit an integral value.
|
||||
void AddAPInt(const llvm::APInt &Value, RecordData &Record);
|
||||
|
||||
/// \brief Emit a signed integral value.
|
||||
void AddAPSInt(const llvm::APSInt &Value, RecordData &Record);
|
||||
|
||||
/// \brief Emit a reference to an identifier
|
||||
void AddIdentifierRef(const IdentifierInfo *II, RecordData &Record);
|
||||
|
||||
|
|
|
@ -48,7 +48,10 @@ namespace {
|
|||
void VisitNamedDecl(NamedDecl *ND);
|
||||
void VisitTypeDecl(TypeDecl *TD);
|
||||
void VisitTypedefDecl(TypedefDecl *TD);
|
||||
void VisitTagDecl(TagDecl *TD);
|
||||
void VisitEnumDecl(EnumDecl *ED);
|
||||
void VisitValueDecl(ValueDecl *VD);
|
||||
void VisitEnumConstantDecl(EnumConstantDecl *ECD);
|
||||
void VisitVarDecl(VarDecl *VD);
|
||||
|
||||
std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
|
||||
|
@ -86,11 +89,30 @@ void PCHDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
|
|||
TD->setUnderlyingType(Reader.GetType(Record[Idx++]));
|
||||
}
|
||||
|
||||
void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
|
||||
VisitTypeDecl(TD);
|
||||
TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
|
||||
TD->setDefinition(Record[Idx++]);
|
||||
TD->setTypedefForAnonDecl(
|
||||
cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
}
|
||||
|
||||
void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) {
|
||||
VisitTagDecl(ED);
|
||||
ED->setIntegerType(Reader.GetType(Record[Idx++]));
|
||||
}
|
||||
|
||||
void PCHDeclReader::VisitValueDecl(ValueDecl *VD) {
|
||||
VisitNamedDecl(VD);
|
||||
VD->setType(Reader.GetType(Record[Idx++]));
|
||||
}
|
||||
|
||||
void PCHDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
|
||||
VisitValueDecl(ECD);
|
||||
// FIXME: initialization expression
|
||||
ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
|
||||
}
|
||||
|
||||
void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
|
||||
VisitValueDecl(VD);
|
||||
VD->setStorageClass((VarDecl::StorageClass)Record[Idx++]);
|
||||
|
@ -795,6 +817,10 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
|
|||
return Context.getMemberPointerType(PointeeType, ClassType.getTypePtr());
|
||||
}
|
||||
|
||||
case pch::TYPE_ENUM:
|
||||
assert(Record.size() == 1 && "Incorrect encoding of enum type");
|
||||
return Context.getTypeDeclType(cast<EnumDecl>(GetDecl(Record[0])));
|
||||
|
||||
// FIXME: Several other kinds of types to deserialize here!
|
||||
default:
|
||||
assert(false && "Unable to deserialize this type");
|
||||
|
@ -842,6 +868,25 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
|
|||
break;
|
||||
}
|
||||
|
||||
case pch::DECL_ENUM: {
|
||||
EnumDecl *Enum = EnumDecl::Create(Context, 0, SourceLocation(), 0, 0);
|
||||
LoadedDecl(Index, Enum);
|
||||
Reader.VisitEnumDecl(Enum);
|
||||
D = Enum;
|
||||
break;
|
||||
}
|
||||
|
||||
case pch::DECL_ENUM_CONSTANT: {
|
||||
EnumConstantDecl *ECD = EnumConstantDecl::Create(Context, 0,
|
||||
SourceLocation(), 0,
|
||||
QualType(), 0,
|
||||
llvm::APSInt());
|
||||
LoadedDecl(Index, ECD);
|
||||
Reader.VisitEnumConstantDecl(ECD);
|
||||
D = ECD;
|
||||
break;
|
||||
}
|
||||
|
||||
case pch::DECL_VAR: {
|
||||
VarDecl *Var = VarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
|
||||
VarDecl::None, SourceLocation());
|
||||
|
@ -1064,6 +1109,21 @@ PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
|
|||
return DeclarationName();
|
||||
}
|
||||
|
||||
/// \brief Read an integral value
|
||||
llvm::APInt PCHReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
|
||||
unsigned BitWidth = Record[Idx++];
|
||||
unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
|
||||
llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
|
||||
Idx += NumWords;
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// \brief Read a signed integral value
|
||||
llvm::APSInt PCHReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
|
||||
bool isUnsigned = Record[Idx++];
|
||||
return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
|
||||
}
|
||||
|
||||
DiagnosticBuilder PCHReader::Diag(unsigned DiagID) {
|
||||
return Diag(SourceLocation(), DiagID);
|
||||
}
|
||||
|
|
|
@ -252,9 +252,11 @@ namespace {
|
|||
void VisitNamedDecl(NamedDecl *D);
|
||||
void VisitTypeDecl(TypeDecl *D);
|
||||
void VisitTypedefDecl(TypedefDecl *D);
|
||||
void VisitTagDecl(TagDecl *D);
|
||||
void VisitEnumDecl(EnumDecl *D);
|
||||
void VisitValueDecl(ValueDecl *D);
|
||||
void VisitEnumConstantDecl(EnumConstantDecl *D);
|
||||
void VisitVarDecl(VarDecl *D);
|
||||
|
||||
void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
|
||||
uint64_t VisibleOffset);
|
||||
};
|
||||
|
@ -291,11 +293,31 @@ void PCHDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
|
|||
Code = pch::DECL_TYPEDEF;
|
||||
}
|
||||
|
||||
void PCHDeclWriter::VisitTagDecl(TagDecl *D) {
|
||||
VisitTypeDecl(D);
|
||||
Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
|
||||
Record.push_back(D->isDefinition());
|
||||
Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record);
|
||||
}
|
||||
|
||||
void PCHDeclWriter::VisitEnumDecl(EnumDecl *D) {
|
||||
VisitTagDecl(D);
|
||||
Writer.AddTypeRef(D->getIntegerType(), Record);
|
||||
Code = pch::DECL_ENUM;
|
||||
}
|
||||
|
||||
void PCHDeclWriter::VisitValueDecl(ValueDecl *D) {
|
||||
VisitNamedDecl(D);
|
||||
Writer.AddTypeRef(D->getType(), Record);
|
||||
}
|
||||
|
||||
void PCHDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
|
||||
VisitValueDecl(D);
|
||||
// FIXME: Writer.AddExprRef(D->getInitExpr());
|
||||
Writer.AddAPSInt(D->getInitVal(), Record);
|
||||
Code = pch::DECL_ENUM_CONSTANT;
|
||||
}
|
||||
|
||||
void PCHDeclWriter::VisitVarDecl(VarDecl *D) {
|
||||
VisitValueDecl(D);
|
||||
Record.push_back(D->getStorageClass());
|
||||
|
@ -935,6 +957,11 @@ void PCHWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) {
|
|||
Record.push_back(Words[I]);
|
||||
}
|
||||
|
||||
void PCHWriter::AddAPSInt(const llvm::APSInt &Value, RecordData &Record) {
|
||||
Record.push_back(Value.isUnsigned());
|
||||
AddAPInt(Value, Record);
|
||||
}
|
||||
|
||||
void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) {
|
||||
if (II == 0) {
|
||||
Record.push_back(0);
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// Test this without pch.
|
||||
// RUN: clang-cc -triple=i686-apple-darwin9 -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
|
||||
|
||||
int i = Red;
|
||||
|
||||
int return_enum_constant() {
|
||||
int result = aRoundShape;
|
||||
return result;
|
||||
}
|
||||
|
||||
enum Shape s = Triangle;
|
|
@ -0,0 +1,16 @@
|
|||
/* Used in enum.c test */
|
||||
|
||||
enum Color {
|
||||
Red,
|
||||
Green,
|
||||
Blue
|
||||
};
|
||||
|
||||
enum Shape {
|
||||
Square,
|
||||
Triangle,
|
||||
Rhombus,
|
||||
Circle
|
||||
};
|
||||
|
||||
enum Shape aRoundShape = Circle;
|
Loading…
Reference in New Issue