[cfe-commits] r73821 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclBase.h lib/AST/Decl.cpp

Douglas Gregor dgregor at apple.com
Mon Jun 22 09:37:32 PDT 2009


On Jun 20, 2009, at 1:09 AM, Argiris Kirtzidis wrote:

> Author: akirtzidis
> Date: Sat Jun 20 03:09:14 2009
> New Revision: 73821
>
> URL: http://llvm.org/viewvc/llvm-project?rev=73821&view=rev
> Log:
> Introduce Decl::getSourceRange() which, like Stmt::getSourceRange(),  
> represents the range that the declaration covers.
>
> Add initial support for NamespaceDecl, VarDecl, and FunctionDecl:
> -NamespaceDecl range is from name to '}'
> -VarDecl is from name to possible init expression
> -FunctionDecl is from name to last parameter name or to end of its  
> function body.

Very cool.

> Modified:
>    cfe/trunk/include/clang/AST/Decl.h
>    cfe/trunk/include/clang/AST/DeclBase.h
>    cfe/trunk/lib/AST/Decl.cpp
>
> Modified: cfe/trunk/include/clang/AST/Decl.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=73821&r1=73820&r2=73821&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/include/clang/AST/Decl.h (original)
> +++ cfe/trunk/include/clang/AST/Decl.h Sat Jun 20 03:09:14 2009
> @@ -146,8 +146,8 @@
>   }
>   void setOriginalNamespace(NamespaceDecl *ND) { OrigNamespace = ND; }
>
> -  SourceRange getSourceRange() const {
> -    return SourceRange(LBracLoc, RBracLoc);
> +  virtual SourceRange getSourceRange() const {
> +    return SourceRange(getLocation(), RBracLoc);
>   }
>
>   SourceLocation getLBracLoc() const { return LBracLoc; }
> @@ -259,6 +259,8 @@
>
>   StorageClass getStorageClass() const { return  
> (StorageClass)SClass; }
>   void setStorageClass(StorageClass SC) { SClass = SC; }
> +
> +  virtual SourceRange getSourceRange() const;
>
>   SourceLocation getTypeSpecStartLoc() const { return  
> TypeSpecStartLoc; }
>   void setTypeSpecStartLoc(SourceLocation SL) {
> @@ -644,6 +646,8 @@
>
>   // Move to DeclGroup when it is implemented.
>   SourceLocation TypeSpecStartLoc;
> +
> +  SourceLocation EndRangeLoc;
>
>   /// \brief The template or declaration that this declaration
>   /// describes or was instantiated from, respectively.
> @@ -667,7 +671,7 @@
>       SClass(S), IsInline(isInline), C99InlineDefinition(false),
>       IsVirtualAsWritten(false), IsPure(false),  
> HasInheritedPrototype(false),
>       HasWrittenPrototype(true), IsDeleted(false),  
> TypeSpecStartLoc(TSSL),
> -      TemplateOrInstantiation() {}
> +      EndRangeLoc(L), TemplateOrInstantiation() {}
>
>   virtual ~FunctionDecl() {}
>   virtual void Destroy(ASTContext& C);
> @@ -677,7 +681,15 @@
>                               DeclarationName N, QualType T,
>                               StorageClass S = None, bool isInline =  
> false,
>                               bool hasWrittenPrototype = true,
> -                              SourceLocation TSStartLoc =  
> SourceLocation());
> +                              SourceLocation TSStartLoc =  
> SourceLocation());
> +
> +  virtual SourceRange getSourceRange() const {
> +    return SourceRange(getLocation(), EndRangeLoc);
> +  }
> +  void setLocEnd(SourceLocation E) {
> +    assert(getLocation() <= E && "Invalid end location");
> +    EndRangeLoc = E;
> +  }
>
>   SourceLocation getTypeSpecStartLoc() const { return  
> TypeSpecStartLoc; }
>   void setTypeSpecStartLoc(SourceLocation TS) { TypeSpecStartLoc =  
> TS; }
> @@ -706,7 +718,7 @@
>   /// CodeGenModule.cpp uses it, and I don't know if this would  
> break it.
>   bool isThisDeclarationADefinition() const { return Body; }
>
> -  void setBody(Stmt *B) { Body = B; }
> +  void setBody(Stmt *B);
>   void setLazyBody(uint64_t Offset) { Body = Offset; }
>
>   /// Whether this function is marked as virtual explicitly.
>
> Modified: cfe/trunk/include/clang/AST/DeclBase.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=73821&r1=73820&r2=73821&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/include/clang/AST/DeclBase.h (original)
> +++ cfe/trunk/include/clang/AST/DeclBase.h Sat Jun 20 03:09:14 2009
> @@ -188,6 +188,14 @@
>   virtual ~Decl();
>
> public:
> +
> +  /// \brief Source range that this declaration covers.
> +  virtual SourceRange getSourceRange() const {
> +    return SourceRange(getLocation(), getLocation());
> +  }
> +  SourceLocation getLocStart() const { return  
> getSourceRange().getBegin(); }
> +  SourceLocation getLocEnd() const { return  
> getSourceRange().getEnd(); }
> +
>   SourceLocation getLocation() const { return Loc; }
>   void setLocation(SourceLocation L) { Loc = L; }
>
>
> Modified: cfe/trunk/lib/AST/Decl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=73821&r1=73820&r2=73821&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/AST/Decl.cpp (original)
> +++ cfe/trunk/lib/AST/Decl.cpp Sat Jun 20 03:09:14 2009
> @@ -315,6 +315,12 @@
> VarDecl::~VarDecl() {
> }
>
> +SourceRange VarDecl::getSourceRange() const {
> +  if (getInit())
> +    return SourceRange(getLocation(), getInit()->getLocEnd());
> +  return SourceRange(getLocation(), getLocation());
> +}
> +
> bool VarDecl::isTentativeDefinition(ASTContext &Context) const {
>   if (!isFileVarDecl() || Context.getLangOptions().CPlusPlus)
>     return false;
> @@ -371,6 +377,12 @@
>   return 0;
> }
>
> +void FunctionDecl::setBody(Stmt *B) {
> +  Body = B;
> +  if (B && EndRangeLoc < B->getLocEnd())
> +    EndRangeLoc = B->getLocEnd();
> +}

Why do we need this < check? The body of the function definition will  
always have an end location later in the file than the last function  
parameter.

I was about to point out that EndRangeLoc is unnecessary, because we  
could compute the full range in getSourceRange(). However, when we're  
dealing with a function definition deserialized from a PCH/AST file,  
we can only compute the full range once the function body has been de- 
serialized... so it's far better to have the (sometimes-redundant)  
EndRangeLoc. Please add a comment to that effect.

> bool FunctionDecl::isMain() const {
>   return getDeclContext()->getLookupContext()->isTranslationUnit() &&
>     getIdentifier() && getIdentifier()->isStr("main");
> @@ -481,6 +493,10 @@
>     void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams);
>     ParamInfo = new (Mem) ParmVarDecl*[NumParams];
>     memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
> +
> +    // Update source range.
> +    if (EndRangeLoc < NewParamInfo[NumParams-1]->getLocEnd())
> +      EndRangeLoc = NewParamInfo[NumParams-1]->getLocEnd();
>   }
> }


I don't think we need to use the < here.

	- Doug



More information about the cfe-commits mailing list