[cfe-commits] r83098 - /cfe/trunk/lib/Index/ResolveLocation.cpp

Argiris Kirtzidis akyrtzi at gmail.com
Tue Sep 29 12:45:41 PDT 2009


Author: akirtzidis
Date: Tue Sep 29 14:45:41 2009
New Revision: 83098

URL: http://llvm.org/viewvc/llvm-project?rev=83098&view=rev
Log:
Resolve a source location that is inside a type declarator.

Modified:
    cfe/trunk/lib/Index/ResolveLocation.cpp

Modified: cfe/trunk/lib/Index/ResolveLocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/ResolveLocation.cpp?rev=83098&r1=83097&r2=83098&view=diff

==============================================================================
--- cfe/trunk/lib/Index/ResolveLocation.cpp (original)
+++ cfe/trunk/lib/Index/ResolveLocation.cpp Tue Sep 29 14:45:41 2009
@@ -14,6 +14,7 @@
 
 #include "clang/Index/Utils.h"
 #include "clang/Index/ASTLocation.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Lex/Lexer.h"
@@ -29,6 +30,8 @@
 protected:
   ASTContext &Ctx;
   SourceLocation Loc;
+  
+  ASTLocation ResolveInDeclarator(Decl *D, Stmt *Stm, DeclaratorInfo *DInfo);
 
   enum RangePos {
     BeforeLoc,
@@ -37,21 +40,29 @@
   };
 
   RangePos CheckRange(SourceRange Range);
-  RangePos CheckRange(Decl *D) { return CheckRange(D->getSourceRange()); }
+  RangePos CheckRange(DeclaratorInfo *DInfo);
+  RangePos CheckRange(Decl *D) {
+    if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
+      if (ContainsLocation(DD->getDeclaratorInfo()))
+        return ContainsLoc;
+
+    return CheckRange(D->getSourceRange());
+  }
   RangePos CheckRange(Stmt *Node) { return CheckRange(Node->getSourceRange()); }
+  RangePos CheckRange(TypeLoc TL) { return CheckRange(TL.getSourceRange()); }
 
   template <typename T>
-  bool isBeforeLocation(T *Node) {
+  bool isBeforeLocation(T Node) {
     return CheckRange(Node) == BeforeLoc;
   }
 
   template <typename T>
-  bool ContainsLocation(T *Node) {
+  bool ContainsLocation(T Node) {
     return CheckRange(Node) == ContainsLoc;
   }
 
   template <typename T>
-  bool isAfterLocation(T *Node) {
+  bool isAfterLocation(T Node) {
     return CheckRange(Node) == AfterLoc;
   }
 
@@ -94,12 +105,29 @@
 
   ASTLocation VisitDeclContext(DeclContext *DC);
   ASTLocation VisitTranslationUnitDecl(TranslationUnitDecl *TU);
+  ASTLocation VisitDeclaratorDecl(DeclaratorDecl *D);
   ASTLocation VisitVarDecl(VarDecl *D);
   ASTLocation VisitFunctionDecl(FunctionDecl *D);
   ASTLocation VisitObjCMethodDecl(ObjCMethodDecl *D);
   ASTLocation VisitDecl(Decl *D);
 };
 
+class TypeLocResolver : public LocResolverBase,
+                        public TypeLocVisitor<TypeLocResolver, ASTLocation> {
+  Decl * const ParentDecl;
+
+public:
+  TypeLocResolver(ASTContext &ctx, SourceLocation loc, Decl *pd)
+    : LocResolverBase(ctx, loc), ParentDecl(pd) { }
+
+  ASTLocation VisitTypedefLoc(TypedefLoc TL);
+  ASTLocation VisitFunctionLoc(FunctionLoc TL);
+  ASTLocation VisitArrayLoc(ArrayLoc TL);
+  ASTLocation VisitObjCInterfaceLoc(ObjCInterfaceLoc TL);
+  ASTLocation VisitObjCProtocolListLoc(ObjCProtocolListLoc TL);
+  ASTLocation VisitTypeLoc(TypeLoc TL);
+};
+
 } // anonymous namespace
 
 ASTLocation
@@ -237,6 +265,15 @@
   return StmtLocResolver(Ctx, Loc, D).Visit(Body);
 }
 
+ASTLocation DeclLocResolver::VisitDeclaratorDecl(DeclaratorDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+  if (ContainsLocation(D->getDeclaratorInfo()))
+    return ResolveInDeclarator(D, /*Stmt=*/0, D->getDeclaratorInfo());
+
+  return ASTLocation(D);
+}
+
 ASTLocation DeclLocResolver::VisitVarDecl(VarDecl *D) {
   assert(ContainsLocation(D) &&
          "Should visit only after verifying that loc is in range");
@@ -245,6 +282,9 @@
   Expr *Init = D->getInit();
   if (Init && ContainsLocation(Init))
     return StmtLocResolver(Ctx, Loc, D).Visit(Init);
+  
+  if (ContainsLocation(D->getDeclaratorInfo()))
+    return ResolveInDeclarator(D, 0, D->getDeclaratorInfo());
 
   return ASTLocation(D);
 }
@@ -306,6 +346,96 @@
   return ASTLocation(D);
 }
 
+ASTLocation TypeLocResolver::VisitTypedefLoc(TypedefLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+  if (ContainsLocation(TL.getNameLoc()))
+    return ASTLocation(ParentDecl, TL.getTypedefDecl(), TL.getNameLoc());
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitFunctionLoc(FunctionLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+
+  for (unsigned i = 0; i != TL.getNumArgs(); ++i) {
+    ParmVarDecl *Parm = TL.getArg(i);
+    RangePos RP = CheckRange(Parm);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return DeclLocResolver(Ctx, Loc).Visit(Parm);
+  }
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitArrayLoc(ArrayLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+
+  Expr *E = TL.getSizeExpr();
+  if (E && ContainsLocation(E))
+    return StmtLocResolver(Ctx, Loc, ParentDecl).Visit(E);
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitObjCInterfaceLoc(ObjCInterfaceLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+  if (ContainsLocation(TL.getNameLoc()))
+    return ASTLocation(ParentDecl, TL.getIFaceDecl(), TL.getNameLoc());
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitObjCProtocolListLoc(ObjCProtocolListLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+
+  for (unsigned i = 0; i != TL.getNumProtocols(); ++i) {
+    SourceLocation L = TL.getProtocolLoc(i);
+    RangePos RP = CheckRange(L);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return ASTLocation(ParentDecl, TL.getProtocol(i), L);
+  }
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitTypeLoc(TypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation LocResolverBase::ResolveInDeclarator(Decl *D, Stmt *Stm,
+                                                 DeclaratorInfo *DInfo) {
+  assert(ContainsLocation(DInfo) &&
+         "Should visit only after verifying that loc is in range");
+  
+  TypeLocResolver(Ctx, Loc, D);
+  for (TypeLoc TL = DInfo->getTypeLoc(); TL; TL = TL.getNextTypeLoc())
+    if (ContainsLocation(TL))
+      return TypeLocResolver(Ctx, Loc, D).Visit(TL);
+  
+  assert(0 && "Should have found the loc in a typeloc");
+  return ASTLocation(D, Stm);
+}
+
+LocResolverBase::RangePos LocResolverBase::CheckRange(DeclaratorInfo *DInfo) {
+  if (!DInfo)
+    return BeforeLoc; // Keep looking.
+
+  for (TypeLoc TL = DInfo->getTypeLoc(); TL; TL = TL.getNextTypeLoc())
+    if (ContainsLocation(TL))
+      return ContainsLoc;
+
+  return BeforeLoc; // Keep looking.
+}
+
 LocResolverBase::RangePos LocResolverBase::CheckRange(SourceRange Range) {
   if (!Range.isValid())
     return BeforeLoc; // Keep looking.





More information about the cfe-commits mailing list