diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 79152a57c4e..1c26756c978 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -1,7 +1,7 @@
 //! FIXME: write short doc here
 
 use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId};
-use hir_expand::name::AsName;
+use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
 use ra_syntax::{
     ast::{self, AstNode, NameOwner},
     match_ast,
@@ -11,8 +11,8 @@ use crate::{
     db::{AstDatabase, DefDatabase, HirDatabase},
     ids::{AstItemDef, LocationCtx},
     Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, ImplBlock,
-    Local, Module, ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, Union,
-    VariantDef,
+    Local, MacroDef, Module, ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias,
+    Union, VariantDef,
 };
 
 pub trait FromSource: Sized {
@@ -77,7 +77,22 @@ impl FromSource for TypeAlias {
         Some(TypeAlias { id })
     }
 }
-// FIXME: add impl FromSource for MacroDef
+
+impl FromSource for MacroDef {
+    type Ast = ast::MacroCall;
+    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
+        let kind = MacroDefKind::Declarative;
+
+        let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
+        let module = Module::from_definition(db, Source::new(src.file_id, module_src))?;
+        let krate = module.krate().crate_id();
+
+        let ast_id = AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.ast));
+
+        let id: MacroDefId = MacroDefId { krate, ast_id, kind };
+        Some(MacroDef { id })
+    }
+}
 
 impl FromSource for ImplBlock {
     type Ast = ast::ImplBlock;
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs
index 9cb9433e7be..faa88d9882b 100644
--- a/crates/ra_ide_api/src/references.rs
+++ b/crates/ra_ide_api/src/references.rs
@@ -369,6 +369,21 @@ mod tests {
         assert_eq!(refs.len(), 2);
     }
 
+    #[test]
+    fn test_find_all_refs_macro_def() {
+        let code = r#"
+        #[macro_export]
+        macro_rules! m1<|> { () => (()) }
+
+        fn foo() {
+            m1();
+            m1();
+        }"#;
+
+        let refs = get_all_refs(code);
+        assert_eq!(refs.len(), 3);
+    }
+
     fn get_all_refs(text: &str) -> ReferenceSearchResult {
         let (analysis, position) = single_file_with_position(text);
         analysis.find_all_refs(position, None).unwrap().unwrap()
diff --git a/crates/ra_ide_api/src/references/classify.rs b/crates/ra_ide_api/src/references/classify.rs
index b5e35e29f2b..0eeaa7f384b 100644
--- a/crates/ra_ide_api/src/references/classify.rs
+++ b/crates/ra_ide_api/src/references/classify.rs
@@ -21,7 +21,6 @@ pub(crate) fn classify_name(
     let parent = name.syntax().parent()?;
     let file_id = file_id.into();
 
-    // FIXME: add ast::MacroCall(it)
     match_ast! {
         match parent {
             ast::BindPat(it) => {
@@ -104,6 +103,19 @@ pub(crate) fn classify_name(
                     Some(from_module_def(db, def.into(), None))
                 }
             },
+            ast::MacroCall(it) => {
+                let src = hir::Source { file_id, ast: it};
+                let def = hir::MacroDef::from_source(db, src.clone())?;
+
+                let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
+                let module = Module::from_definition(db, Source::new(file_id, module_src))?;
+
+                Some(NameDefinition {
+                    visibility: None,
+                    container: module,
+                    kind: NameKind::Macro(def),
+                })
+            },
             _ => None,
         }
     }