summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaStmtAsm.cpp
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2012-10-25 21:49:22 +0000
committerChad Rosier <mcrosier@apple.com>2012-10-25 21:49:22 +0000
commit802f93736a9ae76ffcbd90dbaf1c0b185531bb30 (patch)
tree6c7c3fc22cdcadedeb91ec9fd02942c53d302984 /lib/Sema/SemaStmtAsm.cpp
parente11dba83d35b861e3a6c0d73ea84f89394cb9bad (diff)
[ms-inline asm] Add support for field lookup in the SemaCallback. Patch by Eli.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166723 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmtAsm.cpp')
-rw-r--r--lib/Sema/SemaStmtAsm.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp
index 3a5f40c74f..8e6b81472f 100644
--- a/lib/Sema/SemaStmtAsm.cpp
+++ b/lib/Sema/SemaStmtAsm.cpp
@@ -16,6 +16,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
+#include "clang/AST/RecordLayout.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/TargetInfo.h"
@@ -383,6 +384,11 @@ public:
return static_cast<void *>(OpDecl);
}
+ bool LookupInlineAsmField(StringRef Base, StringRef Member,
+ unsigned &Offset) {
+ return SemaRef.LookupInlineAsmField(Base, Member, Offset, AsmLoc);
+ }
+
static void MSAsmDiagHandlerCallback(const llvm::SMDiagnostic &D,
void *Context) {
((MCAsmParserSemaCallbackImpl*)Context)->MSAsmDiagHandler(D);
@@ -446,6 +452,50 @@ NamedDecl *Sema::LookupInlineAsmIdentifier(StringRef Name, SourceLocation Loc,
return 0;
}
+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;
+
+ NamedDecl *FoundDecl = BaseResult.getFoundDecl();
+ const RecordType *RT = 0;
+ if (VarDecl *VD = dyn_cast<VarDecl>(FoundDecl)) {
+ RT = VD->getType()->getAs<RecordType>();
+ } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(FoundDecl)) {
+ RT = TD->getUnderlyingType()->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;
+}
+
StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
ArrayRef<Token> AsmToks,SourceLocation EndLoc) {
SmallVector<IdentifierInfo*, 4> Names;