зеркало из https://github.com/microsoft/clang-1.git
PCH support for all of the predefined Objective-C types, such as id,
SEL, Class, Protocol, CFConstantString, and __objcFastEnumerationState. With this, we can now run the Objective-C methods and properties PCH tests. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69932 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
97d095f4e5
Коммит
319ac896a0
|
@ -370,6 +370,15 @@ public:
|
|||
// constant CFStrings.
|
||||
QualType getCFConstantStringType();
|
||||
|
||||
/// Get the structure type used to representation CFStrings, or NULL
|
||||
/// if it hasn't yet been built.
|
||||
QualType getRawCFConstantStringType() {
|
||||
if (CFConstantStringTypeDecl)
|
||||
return getTagDeclType(CFConstantStringTypeDecl);
|
||||
return QualType();
|
||||
}
|
||||
void setCFConstantStringType(QualType T);
|
||||
|
||||
// This setter/getter represents the ObjC type for an NSConstantString.
|
||||
void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl);
|
||||
QualType getObjCConstantStringInterface() const {
|
||||
|
@ -379,6 +388,16 @@ public:
|
|||
//// This gets the struct used to keep track of fast enumerations.
|
||||
QualType getObjCFastEnumerationStateType();
|
||||
|
||||
/// Get the ObjCFastEnumerationState type, or NULL if it hasn't yet
|
||||
/// been built.
|
||||
QualType getRawObjCFastEnumerationStateType() {
|
||||
if (ObjCFastEnumerationStateTypeDecl)
|
||||
return getTagDeclType(ObjCFastEnumerationStateTypeDecl);
|
||||
return QualType();
|
||||
}
|
||||
|
||||
void setObjCFastEnumerationStateType(QualType T);
|
||||
|
||||
/// getObjCEncodingForType - Emit the ObjC type encoding for the
|
||||
/// given type into \arg S. If \arg NameFields is specified then
|
||||
/// record field names are also encoded.
|
||||
|
@ -410,9 +429,9 @@ public:
|
|||
/// This setter/getter represents the ObjC 'id' type. It is setup lazily, by
|
||||
/// Sema. id is always a (typedef for a) pointer type, a pointer to a struct.
|
||||
QualType getObjCIdType() const { return ObjCIdType; }
|
||||
void setObjCIdType(TypedefDecl *Decl);
|
||||
void setObjCIdType(QualType T);
|
||||
|
||||
void setObjCSelType(TypedefDecl *Decl);
|
||||
void setObjCSelType(QualType T);
|
||||
QualType getObjCSelType() const { return ObjCSelType; }
|
||||
|
||||
void setObjCProtoType(QualType QT);
|
||||
|
@ -422,7 +441,7 @@ public:
|
|||
/// Sema. 'Class' is always a (typedef for a) pointer type, a pointer to a
|
||||
/// struct.
|
||||
QualType getObjCClassType() const { return ObjCClassType; }
|
||||
void setObjCClassType(TypedefDecl *Decl);
|
||||
void setObjCClassType(QualType T);
|
||||
|
||||
void setBuiltinVaListType(QualType T);
|
||||
QualType getBuiltinVaListType() const { return BuiltinVaListType; }
|
||||
|
|
|
@ -342,7 +342,19 @@ namespace clang {
|
|||
/// SPECIAL_TYPES record.
|
||||
enum SpecialTypeIDs {
|
||||
/// \brief __builtin_va_list
|
||||
SPECIAL_TYPE_BUILTIN_VA_LIST = 0
|
||||
SPECIAL_TYPE_BUILTIN_VA_LIST = 0,
|
||||
/// \brief Objective-C "id" type
|
||||
SPECIAL_TYPE_OBJC_ID = 1,
|
||||
/// \brief Objective-C selector type
|
||||
SPECIAL_TYPE_OBJC_SELECTOR = 2,
|
||||
/// \brief Objective-C Protocol type
|
||||
SPECIAL_TYPE_OBJC_PROTOCOL = 3,
|
||||
/// \brief Objective-C Class type
|
||||
SPECIAL_TYPE_OBJC_CLASS = 4,
|
||||
/// \brief CFConstantString type
|
||||
SPECIAL_TYPE_CF_CONSTANT_STRING = 5,
|
||||
/// \brief Objective-C fast enumeration state type
|
||||
SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE = 6
|
||||
};
|
||||
|
||||
/// \brief Record codes for each kind of declaration.
|
||||
|
|
|
@ -2000,6 +2000,12 @@ QualType ASTContext::getCFConstantStringType() {
|
|||
return getTagDeclType(CFConstantStringTypeDecl);
|
||||
}
|
||||
|
||||
void ASTContext::setCFConstantStringType(QualType T) {
|
||||
const RecordType *Rec = T->getAsRecordType();
|
||||
assert(Rec && "Invalid CFConstantStringType");
|
||||
CFConstantStringTypeDecl = Rec->getDecl();
|
||||
}
|
||||
|
||||
QualType ASTContext::getObjCFastEnumerationStateType()
|
||||
{
|
||||
if (!ObjCFastEnumerationStateTypeDecl) {
|
||||
|
@ -2030,6 +2036,12 @@ QualType ASTContext::getObjCFastEnumerationStateType()
|
|||
return getTagDeclType(ObjCFastEnumerationStateTypeDecl);
|
||||
}
|
||||
|
||||
void ASTContext::setObjCFastEnumerationStateType(QualType T) {
|
||||
const RecordType *Rec = T->getAsRecordType();
|
||||
assert(Rec && "Invalid ObjCFAstEnumerationStateType");
|
||||
ObjCFastEnumerationStateTypeDecl = Rec->getDecl();
|
||||
}
|
||||
|
||||
// This returns true if a type has been typedefed to BOOL:
|
||||
// typedef <type> BOOL;
|
||||
static bool isTypeTypedefedAsBOOL(QualType T) {
|
||||
|
@ -2520,9 +2532,15 @@ void ASTContext::setBuiltinVaListType(QualType T)
|
|||
BuiltinVaListType = T;
|
||||
}
|
||||
|
||||
void ASTContext::setObjCIdType(TypedefDecl *TD)
|
||||
void ASTContext::setObjCIdType(QualType T)
|
||||
{
|
||||
ObjCIdType = getTypedefType(TD);
|
||||
ObjCIdType = T;
|
||||
|
||||
const TypedefType *TT = T->getAsTypedefType();
|
||||
if (!TT)
|
||||
return;
|
||||
|
||||
TypedefDecl *TD = TT->getDecl();
|
||||
|
||||
// typedef struct objc_object *id;
|
||||
const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
|
||||
|
@ -2536,9 +2554,14 @@ void ASTContext::setObjCIdType(TypedefDecl *TD)
|
|||
IdStructType = rec;
|
||||
}
|
||||
|
||||
void ASTContext::setObjCSelType(TypedefDecl *TD)
|
||||
void ASTContext::setObjCSelType(QualType T)
|
||||
{
|
||||
ObjCSelType = getTypedefType(TD);
|
||||
ObjCSelType = T;
|
||||
|
||||
const TypedefType *TT = T->getAsTypedefType();
|
||||
if (!TT)
|
||||
return;
|
||||
TypedefDecl *TD = TT->getDecl();
|
||||
|
||||
// typedef struct objc_selector *SEL;
|
||||
const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
|
||||
|
@ -2555,9 +2578,14 @@ void ASTContext::setObjCProtoType(QualType QT)
|
|||
ObjCProtoType = QT;
|
||||
}
|
||||
|
||||
void ASTContext::setObjCClassType(TypedefDecl *TD)
|
||||
void ASTContext::setObjCClassType(QualType T)
|
||||
{
|
||||
ObjCClassType = getTypedefType(TD);
|
||||
ObjCClassType = T;
|
||||
|
||||
const TypedefType *TT = T->getAsTypedefType();
|
||||
if (!TT)
|
||||
return;
|
||||
TypedefDecl *TD = TT->getDecl();
|
||||
|
||||
// typedef struct objc_class *Class;
|
||||
const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
|
||||
|
|
|
@ -59,6 +59,11 @@ bool operator<(DeclarationName LHS, DeclarationName RHS) {
|
|||
} // end namespace clang
|
||||
|
||||
DeclarationName::DeclarationName(Selector Sel) {
|
||||
if (!Sel.getAsOpaquePtr()) {
|
||||
Ptr = StoredObjCZeroArgSelector;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Sel.getNumArgs()) {
|
||||
case 0:
|
||||
Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
|
||||
|
|
|
@ -1948,7 +1948,19 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
|
|||
// Load the special types.
|
||||
Context.setBuiltinVaListType(
|
||||
GetType(SpecialTypes[pch::SPECIAL_TYPE_BUILTIN_VA_LIST]));
|
||||
|
||||
if (unsigned Id = SpecialTypes[pch::SPECIAL_TYPE_OBJC_ID])
|
||||
Context.setObjCIdType(GetType(Id));
|
||||
if (unsigned Sel = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SELECTOR])
|
||||
Context.setObjCSelType(GetType(Sel));
|
||||
if (unsigned Proto = SpecialTypes[pch::SPECIAL_TYPE_OBJC_PROTOCOL])
|
||||
Context.setObjCProtoType(GetType(Proto));
|
||||
if (unsigned Class = SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS])
|
||||
Context.setObjCClassType(GetType(Class));
|
||||
if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_CF_CONSTANT_STRING])
|
||||
Context.setCFConstantStringType(GetType(String));
|
||||
if (unsigned FastEnum
|
||||
= SpecialTypes[pch::SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
|
||||
Context.setObjCFastEnumerationStateType(GetType(FastEnum));
|
||||
// If we saw the preprocessor block, read it now.
|
||||
if (PreprocessorBlockOffset) {
|
||||
SavedStreamPosition SavedPos(Stream);
|
||||
|
|
|
@ -2105,6 +2105,12 @@ void PCHWriter::WritePCH(Sema &SemaRef) {
|
|||
// Write the record of special types.
|
||||
Record.clear();
|
||||
AddTypeRef(Context.getBuiltinVaListType(), Record);
|
||||
AddTypeRef(Context.getObjCIdType(), Record);
|
||||
AddTypeRef(Context.getObjCSelType(), Record);
|
||||
AddTypeRef(Context.getObjCProtoType(), Record);
|
||||
AddTypeRef(Context.getObjCClassType(), Record);
|
||||
AddTypeRef(Context.getRawCFConstantStringType(), Record);
|
||||
AddTypeRef(Context.getRawObjCFastEnumerationStateType(), Record);
|
||||
Stream.EmitRecord(pch::SPECIAL_TYPES, Record);
|
||||
|
||||
// Write the record containing external, unnamed definitions.
|
||||
|
|
|
@ -110,46 +110,54 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
|
|||
PushDeclContext(S, Context.getTranslationUnitDecl());
|
||||
if (!PP.getLangOptions().ObjC1) return;
|
||||
|
||||
// Synthesize "typedef struct objc_selector *SEL;"
|
||||
RecordDecl *SelTag = CreateStructDecl(Context, "objc_selector");
|
||||
PushOnScopeChains(SelTag, TUScope);
|
||||
if (Context.getObjCSelType().isNull()) {
|
||||
// Synthesize "typedef struct objc_selector *SEL;"
|
||||
RecordDecl *SelTag = CreateStructDecl(Context, "objc_selector");
|
||||
PushOnScopeChains(SelTag, TUScope);
|
||||
|
||||
QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag));
|
||||
TypedefDecl *SelTypedef = TypedefDecl::Create(Context, CurContext,
|
||||
SourceLocation(),
|
||||
&Context.Idents.get("SEL"),
|
||||
SelT);
|
||||
PushOnScopeChains(SelTypedef, TUScope);
|
||||
Context.setObjCSelType(SelTypedef);
|
||||
QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag));
|
||||
TypedefDecl *SelTypedef = TypedefDecl::Create(Context, CurContext,
|
||||
SourceLocation(),
|
||||
&Context.Idents.get("SEL"),
|
||||
SelT);
|
||||
PushOnScopeChains(SelTypedef, TUScope);
|
||||
Context.setObjCSelType(Context.getTypeDeclType(SelTypedef));
|
||||
}
|
||||
|
||||
if (Context.getObjCClassType().isNull()) {
|
||||
RecordDecl *ClassTag = CreateStructDecl(Context, "objc_class");
|
||||
QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
|
||||
TypedefDecl *ClassTypedef =
|
||||
TypedefDecl::Create(Context, CurContext, SourceLocation(),
|
||||
&Context.Idents.get("Class"), ClassT);
|
||||
PushOnScopeChains(ClassTag, TUScope);
|
||||
PushOnScopeChains(ClassTypedef, TUScope);
|
||||
Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
|
||||
}
|
||||
|
||||
// FIXME: Make sure these don't leak!
|
||||
RecordDecl *ClassTag = CreateStructDecl(Context, "objc_class");
|
||||
QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
|
||||
TypedefDecl *ClassTypedef =
|
||||
TypedefDecl::Create(Context, CurContext, SourceLocation(),
|
||||
&Context.Idents.get("Class"), ClassT);
|
||||
PushOnScopeChains(ClassTag, TUScope);
|
||||
PushOnScopeChains(ClassTypedef, TUScope);
|
||||
Context.setObjCClassType(ClassTypedef);
|
||||
// Synthesize "@class Protocol;
|
||||
ObjCInterfaceDecl *ProtocolDecl =
|
||||
ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
|
||||
&Context.Idents.get("Protocol"),
|
||||
SourceLocation(), true);
|
||||
Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
|
||||
PushOnScopeChains(ProtocolDecl, TUScope);
|
||||
|
||||
// Synthesize "typedef struct objc_object { Class isa; } *id;"
|
||||
RecordDecl *ObjectTag = CreateStructDecl(Context, "objc_object");
|
||||
if (Context.getObjCProtoType().isNull()) {
|
||||
ObjCInterfaceDecl *ProtocolDecl =
|
||||
ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
|
||||
&Context.Idents.get("Protocol"),
|
||||
SourceLocation(), true);
|
||||
Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
|
||||
PushOnScopeChains(ProtocolDecl, TUScope);
|
||||
}
|
||||
|
||||
QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
|
||||
PushOnScopeChains(ObjectTag, TUScope);
|
||||
TypedefDecl *IdTypedef = TypedefDecl::Create(Context, CurContext,
|
||||
SourceLocation(),
|
||||
&Context.Idents.get("id"),
|
||||
ObjT);
|
||||
PushOnScopeChains(IdTypedef, TUScope);
|
||||
Context.setObjCIdType(IdTypedef);
|
||||
// Synthesize "typedef struct objc_object { Class isa; } *id;"
|
||||
if (Context.getObjCIdType().isNull()) {
|
||||
RecordDecl *ObjectTag = CreateStructDecl(Context, "objc_object");
|
||||
|
||||
QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
|
||||
PushOnScopeChains(ObjectTag, TUScope);
|
||||
TypedefDecl *IdTypedef = TypedefDecl::Create(Context, CurContext,
|
||||
SourceLocation(),
|
||||
&Context.Idents.get("id"),
|
||||
ObjT);
|
||||
PushOnScopeChains(IdTypedef, TUScope);
|
||||
Context.setObjCIdType(Context.getTypeDeclType(IdTypedef));
|
||||
}
|
||||
}
|
||||
|
||||
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
|
||||
|
|
|
@ -473,19 +473,19 @@ bool Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
|
|||
case 2:
|
||||
if (!TypeID->isStr("id"))
|
||||
break;
|
||||
Context.setObjCIdType(New);
|
||||
Context.setObjCIdType(Context.getTypeDeclType(New));
|
||||
objc_types = true;
|
||||
break;
|
||||
case 5:
|
||||
if (!TypeID->isStr("Class"))
|
||||
break;
|
||||
Context.setObjCClassType(New);
|
||||
Context.setObjCClassType(Context.getTypeDeclType(New));
|
||||
objc_types = true;
|
||||
return false;
|
||||
case 3:
|
||||
if (!TypeID->isStr("SEL"))
|
||||
break;
|
||||
Context.setObjCSelType(New);
|
||||
Context.setObjCSelType(Context.getTypeDeclType(New));
|
||||
objc_types = true;
|
||||
return false;
|
||||
case 8:
|
||||
|
|
|
@ -11,8 +11,6 @@ void func() {
|
|||
// FIXME:
|
||||
// AliasForTestPCH *zz;
|
||||
|
||||
#if 0
|
||||
xx = [TestPCH alloc];
|
||||
[xx instMethod];
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Test this without pch.
|
||||
// FIXME: clang-cc -include %S/objc_property.h -fsyntax-only -verify %s &&
|
||||
// RUN: clang-cc -include %S/objc_property.h -fsyntax-only -verify %s &&
|
||||
|
||||
// Test with pch.
|
||||
// FIXME: clang-cc -x=objective-c -emit-pch -o %t %S/objc_property.h &&
|
||||
// FIXME: clang-cc -include-pch %t -fsyntax-only -verify %s
|
||||
// RUN: clang-cc -x=objective-c -emit-pch -o %t %S/objc_property.h &&
|
||||
// RUN: clang-cc -include-pch %t -fsyntax-only -verify %s
|
||||
|
||||
void func() {
|
||||
TestProperties *xx = [TestProperties alloc];
|
||||
|
|
Загрузка…
Ссылка в новой задаче