[cfe-commits] r104309 - in /cfe/trunk: include/clang/AST/Decl.h lib/AST/Decl.cpp lib/Sema/SemaExpr.cpp

John McCall rjmccall at apple.com
Thu May 20 18:17:40 PDT 2010


Author: rjmccall
Date: Thu May 20 20:17:40 2010
New Revision: 104309

URL: http://llvm.org/viewvc/llvm-project?rev=104309&view=rev
Log:
Introduce a method to get from an anonymous struct or union record declaration
to the associated object declaration.


Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=104309&r1=104308&r2=104309&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Thu May 20 20:17:40 2010
@@ -2021,6 +2021,11 @@
     AnonymousStructOrUnion = Anon;
   }
 
+  ValueDecl *getAnonymousStructOrUnionObject();
+  const ValueDecl *getAnonymousStructOrUnionObject() const {
+    return const_cast<RecordDecl*>(this)->getAnonymousStructOrUnionObject();
+  }
+
   bool hasObjectMember() const { return HasObjectMember; }
   void setHasObjectMember (bool val) { HasObjectMember = val; }
 

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=104309&r1=104308&r2=104309&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Thu May 20 20:17:40 2010
@@ -1627,6 +1627,17 @@
   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
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=104309&r1=104308&r2=104309&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu May 20 20:17:40 2010
@@ -496,35 +496,6 @@
                                    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 @@
   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 {





More information about the cfe-commits mailing list