aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-05-21 01:17:40 +0000
committerJohn McCall <rjmccall@apple.com>2010-05-21 01:17:40 +0000
commitbc365c53606ab90537576cb48d93a54ce3fb0cb5 (patch)
tree37a60d72f3749b1ded3412294d2bc9b2c4f5d156 /lib
parent9901c57806f7e36736ed1616e6ab3eebcc99b78c (diff)
Introduce a method to get from an anonymous struct or union record declaration
to the associated object declaration. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104309 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Decl.cpp11
-rw-r--r--lib/Sema/SemaExpr.cpp31
2 files changed, 12 insertions, 30 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 695a8b8b51..ffdcb471d0 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1627,6 +1627,17 @@ void RecordDecl::completeDefinition() {
TagDecl::completeDefinition();
}
+ValueDecl *RecordDecl::getAnonymousStructOrUnionObject() {
+ // Force the decl chain to come into existence properly.
+ if (!getNextDeclInContext()) getParent()->decls_begin();
+
+ assert(isAnonymousStructOrUnion());
+ ValueDecl *D = cast<ValueDecl>(getNextDeclInContext());
+ assert(D->getType()->isRecordType());
+ assert(D->getType()->getAs<RecordType>()->getDecl() == this);
+ return D;
+}
+
//===----------------------------------------------------------------------===//
// BlockDecl Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 9d8fe9c85f..933a696bdc 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -496,35 +496,6 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
D, Loc, Ty));
}
-/// getObjectForAnonymousRecordDecl - Retrieve the (unnamed) field or
-/// variable corresponding to the anonymous union or struct whose type
-/// is Record.
-static Decl *getObjectForAnonymousRecordDecl(ASTContext &Context,
- RecordDecl *Record) {
- assert(Record->isAnonymousStructOrUnion() &&
- "Record must be an anonymous struct or union!");
-
- // FIXME: Once Decls are directly linked together, this will be an O(1)
- // operation rather than a slow walk through DeclContext's vector (which
- // itself will be eliminated). DeclGroups might make this even better.
- DeclContext *Ctx = Record->getDeclContext();
- for (DeclContext::decl_iterator D = Ctx->decls_begin(),
- DEnd = Ctx->decls_end();
- D != DEnd; ++D) {
- if (*D == Record) {
- // The object for the anonymous struct/union directly
- // follows its type in the list of declarations.
- ++D;
- assert(D != DEnd && "Missing object for anonymous record");
- assert(!cast<NamedDecl>(*D)->getDeclName() && "Decl should be unnamed");
- return *D;
- }
- }
-
- assert(false && "Missing object for anonymous record");
- return 0;
-}
-
/// \brief Given a field that represents a member of an anonymous
/// struct/union, build the path from that field's context to the
/// actual member.
@@ -549,7 +520,7 @@ VarDecl *Sema::BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
DeclContext *Ctx = Field->getDeclContext();
do {
RecordDecl *Record = cast<RecordDecl>(Ctx);
- Decl *AnonObject = getObjectForAnonymousRecordDecl(Context, Record);
+ ValueDecl *AnonObject = Record->getAnonymousStructOrUnionObject();
if (FieldDecl *AnonField = dyn_cast<FieldDecl>(AnonObject))
Path.push_back(AnonField);
else {