bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member, unsigned &Offset, SourceLocation AsmLoc) { Offset = 0; SmallVector<StringRef, 2> Members; Member.split(Members, "."); LookupResult BaseResult(*this, &Context.Idents.get(Base), SourceLocation(), LookupOrdinaryName); if (!LookupName(BaseResult, getCurScope())) return true; if(!BaseResult.isSingleResult()) return true; NamedDecl *FoundDecl = BaseResult.getFoundDecl(); for (StringRef NextMember : Members) { const RecordType *RT = nullptr; if (VarDecl *VD = dyn_cast<VarDecl>(FoundDecl)) RT = VD->getType()->getAs<RecordType>(); else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(FoundDecl)) { MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false); RT = TD->getUnderlyingType()->getAs<RecordType>(); } else if (TypeDecl *TD = dyn_cast<TypeDecl>(FoundDecl)) RT = TD->getTypeForDecl()->getAs<RecordType>(); else if (FieldDecl *TD = dyn_cast<FieldDecl>(FoundDecl)) RT = TD->getType()->getAs<RecordType>(); if (!RT) return true; if (RequireCompleteType(AsmLoc, QualType(RT, 0), diag::err_asm_incomplete_type)) return true; LookupResult FieldResult(*this, &Context.Idents.get(NextMember), SourceLocation(), LookupMemberName); if (!LookupQualifiedName(FieldResult, RT->getDecl())) return true; if (!FieldResult.isSingleResult()) return true; FoundDecl = FieldResult.getFoundDecl(); // FIXME: Handle IndirectFieldDecl? FieldDecl *FD = dyn_cast<FieldDecl>(FoundDecl); if (!FD) return true; const ASTRecordLayout &RL = Context.getASTRecordLayout(RT->getDecl()); unsigned i = FD->getFieldIndex(); CharUnits Result = Context.toCharUnitsFromBits(RL.getFieldOffset(i)); Offset += (unsigned)Result.getQuantity(); } return false; }
bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member, unsigned &Offset, SourceLocation AsmLoc) { Offset = 0; LookupResult BaseResult(*this, &Context.Idents.get(Base), SourceLocation(), LookupOrdinaryName); if (!LookupName(BaseResult, getCurScope())) return true; if (!BaseResult.isSingleResult()) return true; const RecordType *RT = nullptr; NamedDecl *FoundDecl = BaseResult.getFoundDecl(); if (VarDecl *VD = dyn_cast<VarDecl>(FoundDecl)) RT = VD->getType()->getAs<RecordType>(); else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(FoundDecl)) RT = TD->getUnderlyingType()->getAs<RecordType>(); else if (TypeDecl *TD = dyn_cast<TypeDecl>(FoundDecl)) RT = TD->getTypeForDecl()->getAs<RecordType>(); if (!RT) return true; if (RequireCompleteType(AsmLoc, QualType(RT, 0), 0)) return true; LookupResult FieldResult(*this, &Context.Idents.get(Member), SourceLocation(), LookupMemberName); if (!LookupQualifiedName(FieldResult, RT->getDecl())) return true; // FIXME: Handle IndirectFieldDecl? FieldDecl *FD = dyn_cast<FieldDecl>(FieldResult.getFoundDecl()); if (!FD) return true; const ASTRecordLayout &RL = Context.getASTRecordLayout(RT->getDecl()); unsigned i = FD->getFieldIndex(); CharUnits Result = Context.toCharUnitsFromBits(RL.getFieldOffset(i)); Offset = (unsigned)Result.getQuantity(); return false; }