[cfe-commits] r96420 - in /cfe/trunk: include/clang/Basic/DiagnosticASTKinds.td lib/AST/ASTImporter.cpp test/ASTMerge/Inputs/interface1.m test/ASTMerge/Inputs/interface2.m test/ASTMerge/interface.m
Douglas Gregor
dgregor at apple.com
Tue Feb 16 16:34:30 PST 2010
Author: dgregor
Date: Tue Feb 16 18:34:30 2010
New Revision: 96420
URL: http://llvm.org/viewvc/llvm-project?rev=96420&view=rev
Log:
Implement AST importing of Objective-C instance variables.
Check superclasses when merging two Objective-C @interfaces.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/test/ASTMerge/Inputs/interface1.m
cfe/trunk/test/ASTMerge/Inputs/interface2.m
cfe/trunk/test/ASTMerge/interface.m
Modified: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td?rev=96420&r1=96419&r2=96420&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td Tue Feb 16 18:34:30 2010
@@ -53,6 +53,13 @@
"class has %0 base %plural{1:class|:classes}0">;
def note_odr_enumerator : Note<"enumerator %0 with value %1 here">;
def note_odr_missing_enumerator : Note<"no corresponding enumerator here">;
-
+def err_odr_ivar_type_inconsistent : Error<
+ "instance variable %0 declared with incompatible types in different "
+ "translation units (%1 vs. %2)">;
+def err_odr_objc_superclass_inconsistent : Error<
+ "class %0 has incompatible superclasses">;
+def note_odr_objc_superclass : Note<"inherits from superclass %0 here">;
+def note_odr_objc_missing_superclass : Note<"no corresponding superclass here">;
+
def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
}
Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=96420&r1=96419&r2=96420&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Feb 16 18:34:30 2010
@@ -90,6 +90,7 @@
Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
Decl *VisitFunctionDecl(FunctionDecl *D);
Decl *VisitFieldDecl(FieldDecl *D);
+ Decl *VisitObjCIvarDecl(ObjCIvarDecl *D);
Decl *VisitVarDecl(VarDecl *D);
Decl *VisitParmVarDecl(ParmVarDecl *D);
Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
@@ -1821,6 +1822,54 @@
return ToField;
}
+Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
+ // Import the major distinguishing characteristics of an ivar.
+ DeclContext *DC, *LexicalDC;
+ DeclarationName Name;
+ SourceLocation Loc;
+ if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+ return 0;
+
+ // Determine whether we've already imported this ivar
+ for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+ Lookup.first != Lookup.second;
+ ++Lookup.first) {
+ if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(*Lookup.first)) {
+ if (Importer.IsStructurallyEquivalent(D->getType(),
+ FoundIvar->getType())) {
+ Importer.Imported(D, FoundIvar);
+ return FoundIvar;
+ }
+
+ Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
+ << Name << D->getType() << FoundIvar->getType();
+ Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
+ << FoundIvar->getType();
+ return 0;
+ }
+ }
+
+ // Import the type.
+ QualType T = Importer.Import(D->getType());
+ if (T.isNull())
+ return 0;
+
+ TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
+ Expr *BitWidth = Importer.Import(D->getBitWidth());
+ if (!BitWidth && D->getBitWidth())
+ return 0;
+
+ ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(), DC,
+ Loc, Name.getAsIdentifierInfo(),
+ T, TInfo, D->getAccessControl(),
+ BitWidth);
+ ToIvar->setLexicalDeclContext(LexicalDC);
+ Importer.Imported(D, ToIvar);
+ LexicalDC->addDecl(ToIvar);
+ return ToIvar;
+
+}
+
Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
// Import the major distinguishing characteristics of a variable.
DeclContext *DC, *LexicalDC;
@@ -1997,9 +2046,6 @@
}
Importer.Imported(D, ToIface);
- // Import superclass
- // FIXME: If we're merging, make sure that both decls have the same
- // superclass.
if (D->getSuperClass()) {
ObjCInterfaceDecl *Super
= cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getSuperClass()));
@@ -2037,6 +2083,33 @@
ToIface->setAtEndRange(Importer.Import(D->getAtEndRange()));
} else {
Importer.Imported(D, ToIface);
+
+ // Check for consistency of superclasses.
+ DeclarationName FromSuperName, ToSuperName;
+ if (D->getSuperClass())
+ FromSuperName = Importer.Import(D->getSuperClass()->getDeclName());
+ if (ToIface->getSuperClass())
+ ToSuperName = ToIface->getSuperClass()->getDeclName();
+ if (FromSuperName != ToSuperName) {
+ Importer.ToDiag(ToIface->getLocation(),
+ diag::err_odr_objc_superclass_inconsistent)
+ << ToIface->getDeclName();
+ if (ToIface->getSuperClass())
+ Importer.ToDiag(ToIface->getSuperClassLoc(),
+ diag::note_odr_objc_superclass)
+ << ToIface->getSuperClass()->getDeclName();
+ else
+ Importer.ToDiag(ToIface->getLocation(),
+ diag::note_odr_objc_missing_superclass);
+ if (D->getSuperClass())
+ Importer.FromDiag(D->getSuperClassLoc(),
+ diag::note_odr_objc_superclass)
+ << D->getSuperClass()->getDeclName();
+ else
+ Importer.FromDiag(D->getLocation(),
+ diag::note_odr_objc_missing_superclass);
+ return 0;
+ }
}
// Import all of the members of this class.
Modified: cfe/trunk/test/ASTMerge/Inputs/interface1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/interface1.m?rev=96420&r1=96419&r2=96420&view=diff
==============================================================================
--- cfe/trunk/test/ASTMerge/Inputs/interface1.m (original)
+++ cfe/trunk/test/ASTMerge/Inputs/interface1.m Tue Feb 16 18:34:30 2010
@@ -1,7 +1,23 @@
// Matches
- at interface I1
+ at interface I1 {
+ int ivar1;
+}
@end
// Matches
- at interface I2 : I1
+ at interface I2 : I1 {
+ float ivar2;
+}
+ at end
+
+// Ivar mismatch
+ at interface I3 {
+ int ivar1;
+ int ivar2;
+}
+ at end
+
+// Superclass mismatch
+ at interface I4 : I2 {
+}
@end
Modified: cfe/trunk/test/ASTMerge/Inputs/interface2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/interface2.m?rev=96420&r1=96419&r2=96420&view=diff
==============================================================================
--- cfe/trunk/test/ASTMerge/Inputs/interface2.m (original)
+++ cfe/trunk/test/ASTMerge/Inputs/interface2.m Tue Feb 16 18:34:30 2010
@@ -1,7 +1,23 @@
// Matches
- at interface I1
+ at interface I1 {
+ int ivar1;
+}
@end
// Matches
- at interface I2 : I1
+ at interface I2 : I1 {
+ float ivar2;
+}
+ at end
+
+// Ivar mismatch
+ at interface I3 {
+ int ivar1;
+ float ivar2;
+}
+ at end
+
+// Superclass mismatch
+ at interface I4 : I1 {
+}
@end
Modified: cfe/trunk/test/ASTMerge/interface.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/interface.m?rev=96420&r1=96419&r2=96420&view=diff
==============================================================================
--- cfe/trunk/test/ASTMerge/interface.m (original)
+++ cfe/trunk/test/ASTMerge/interface.m Tue Feb 16 18:34:30 2010
@@ -1,6 +1,11 @@
// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/interface1.m
// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/interface2.m
-// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-// FIXME: FileCheck!
+// CHECK: interface2.m:16:9: error: instance variable 'ivar2' declared with incompatible types in different translation units ('float' vs. 'int')
+// CHECK: interface1.m:16:7: note: declared here with type 'int'
+// CHECK: interface1.m:21:1: error: class 'I4' has incompatible superclasses
+// CHECK: interface1.m:21:17: note: inherits from superclass 'I2' here
+// CHECK: interface2.m:21:17: note: inherits from superclass 'I1' here
+// CHECK: 5 diagnostics generated
More information about the cfe-commits
mailing list