zcov: / lib/Sema/Sema.cpp


Files: 1 Branches Taken: 77.2% 88 / 114
Generated: 2010-02-10 01:31 Branches Executed: 77.2% 88 / 114
Line Coverage: 96.1% 124 / 129


Programs: 2 Runs 3018


       1                 : //===--- Sema.cpp - AST Builder and Semantic Analysis Implementation ------===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : // This file implements the actions class which performs semantic analysis and
      11                 : // builds an AST out of a parse stream.
      12                 : //
      13                 : //===----------------------------------------------------------------------===//
      14                 : 
      15                 : #include "Sema.h"
      16                 : #include "TargetAttributesSema.h"
      17                 : #include "llvm/ADT/DenseMap.h"
      18                 : #include "llvm/ADT/SmallSet.h"
      19                 : #include "llvm/ADT/APFloat.h"
      20                 : #include "clang/AST/ASTConsumer.h"
      21                 : #include "clang/AST/ASTContext.h"
      22                 : #include "clang/AST/ASTDiagnostic.h"
      23                 : #include "clang/AST/DeclObjC.h"
      24                 : #include "clang/AST/Expr.h"
      25                 : #include "clang/Lex/Preprocessor.h"
      26                 : #include "clang/Basic/PartialDiagnostic.h"
      27                 : #include "clang/Basic/TargetInfo.h"
      28                 : using namespace clang;
      29                 :                                        
      30                 : static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name) {
      31                 :   if (C.getLangOptions().CPlusPlus)
      32                 :     return CXXRecordDecl::Create(C, TagDecl::TK_struct,
      33                 :                                  C.getTranslationUnitDecl(),
      34                 :                                  SourceLocation(), &C.Idents.get(Name));
      35                 : 
      36                 :   return RecordDecl::Create(C, TagDecl::TK_struct,
      37                 :                             C.getTranslationUnitDecl(),
      38                 :                             SourceLocation(), &C.Idents.get(Name));
      39                 : }
      40                 : 
      41             2236: void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
      42             2236:   TUScope = S;
                     2236: branch 1 taken
                        0: branch 2 not taken
      43             2236:   PushDeclContext(S, Context.getTranslationUnitDecl());
      44                 : 
                      196: branch 2 taken
                     2040: branch 3 taken
      45             2236:   if (PP.getTargetInfo().getPointerWidth(0) >= 64) {
      46                 :     TypeSourceInfo *TInfo;
      47                 : 
      48                 :     // Install [u]int128_t for 64-bit targets.
      49              196:     TInfo = Context.getTrivialTypeSourceInfo(Context.Int128Ty);
      50                 :     PushOnScopeChains(TypedefDecl::Create(Context, CurContext,
      51                 :                                           SourceLocation(),
      52                 :                                           &Context.Idents.get("__int128_t"),
      53              196:                                           TInfo), TUScope);
      54                 : 
      55              196:     TInfo = Context.getTrivialTypeSourceInfo(Context.UnsignedInt128Ty);
      56                 :     PushOnScopeChains(TypedefDecl::Create(Context, CurContext,
      57                 :                                           SourceLocation(),
      58                 :                                           &Context.Idents.get("__uint128_t"),
      59              196:                                           TInfo), TUScope);
      60                 :   }
      61                 : 
      62                 : 
                      636: branch 1 taken
                     1600: branch 2 taken
      63             2236:   if (!PP.getLangOptions().ObjC1) return;
      64                 : 
      65                 :   // Built-in ObjC types may already be set by PCHReader (hence isNull checks).
                      630: branch 2 taken
                        6: branch 3 taken
      66              636:   if (Context.getObjCSelType().isNull()) {
      67                 :     // Create the built-in typedef for 'SEL'.
      68              630:     QualType SelT = Context.getPointerType(Context.ObjCBuiltinSelTy);
      69              630:     TypeSourceInfo *SelInfo = Context.getTrivialTypeSourceInfo(SelT);
      70                 :     TypedefDecl *SelTypedef
      71                 :       = TypedefDecl::Create(Context, CurContext, SourceLocation(),
      72              630:                             &Context.Idents.get("SEL"), SelInfo);
      73              630:     PushOnScopeChains(SelTypedef, TUScope);
      74              630:     Context.setObjCSelType(Context.getTypeDeclType(SelTypedef));
      75              630:     Context.ObjCSelRedefinitionType = Context.getObjCSelType();
      76                 :   }
      77                 : 
      78                 :   // Synthesize "@class Protocol;
                      630: branch 2 taken
                        6: branch 3 taken
      79              636:   if (Context.getObjCProtoType().isNull()) {
      80                 :     ObjCInterfaceDecl *ProtocolDecl =
      81                 :       ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
      82                 :                                 &Context.Idents.get("Protocol"),
      83              630:                                 SourceLocation(), true);
      84              630:     Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
      85              630:     PushOnScopeChains(ProtocolDecl, TUScope, false);
      86                 :   }
      87                 :   // Create the built-in typedef for 'id'.
                      630: branch 2 taken
                        6: branch 3 taken
      88              636:   if (Context.getObjCIdType().isNull()) {
      89              630:     QualType IdT = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy);
      90              630:     TypeSourceInfo *IdInfo = Context.getTrivialTypeSourceInfo(IdT);
      91                 :     TypedefDecl *IdTypedef
      92                 :       = TypedefDecl::Create(Context, CurContext, SourceLocation(),
      93              630:                             &Context.Idents.get("id"), IdInfo);
      94              630:     PushOnScopeChains(IdTypedef, TUScope);
      95              630:     Context.setObjCIdType(Context.getTypeDeclType(IdTypedef));
      96              630:     Context.ObjCIdRedefinitionType = Context.getObjCIdType();
      97                 :   }
      98                 :   // Create the built-in typedef for 'Class'.
                      630: branch 2 taken
                        6: branch 3 taken
      99              636:   if (Context.getObjCClassType().isNull()) {
     100                 :     QualType ClassType
     101              630:       = Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy);
     102              630:     TypeSourceInfo *ClassInfo = Context.getTrivialTypeSourceInfo(ClassType);
     103                 :     TypedefDecl *ClassTypedef
     104                 :       = TypedefDecl::Create(Context, CurContext, SourceLocation(),
     105              630:                             &Context.Idents.get("Class"), ClassInfo);
     106              630:     PushOnScopeChains(ClassTypedef, TUScope);
     107              630:     Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
     108              630:     Context.ObjCClassRedefinitionType = Context.getObjCClassType();
     109                 :   }
     110                 : }
     111                 : 
     112                 : Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
     113                 :            bool CompleteTranslationUnit,
     114             2236:            CodeCompleteConsumer *CodeCompleter)
     115                 :   : TheTargetAttributesSema(0),
     116                 :     LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
     117                 :     Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
     118                 :     ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0), 
     119                 :     CurBlock(0), PackContext(0), ParsingDeclDepth(0),
     120                 :     IdResolver(pp.getLangOptions()), StdNamespace(0), StdBadAlloc(0),
     121                 :     GlobalNewDeleteDeclared(false), 
     122                 :     CompleteTranslationUnit(CompleteTranslationUnit),
     123                 :     NumSFINAEErrors(0), NonInstantiationEntries(0), 
     124             2236:     CurrentInstantiationScope(0), TyposCorrected(0)
     125                 : {
     126             2236:   TUScope = 0;
                      848: branch 1 taken
                     1388: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
     127             2236:   if (getLangOptions().CPlusPlus)
     128              848:     FieldCollector.reset(new CXXFieldCollector());
     129                 : 
     130                 :   // Tell diagnostics how to render things from the AST library.
     131                 :   PP.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, 
     132             2236:                                        &Context);
     133                 : 
     134                 :   ExprEvalContexts.push_back(
     135             2236:                   ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));
     136             2236: }
     137                 : 
     138             2236: Sema::~Sema() {
                     2236: branch 0 taken
                     2236: branch 1 taken
                       10: branch 3 taken
                     2226: branch 4 taken
                       10: branch 6 taken
                       10: branch 7 taken
     139             2236:   if (PackContext) FreePackedContext();
                     2236: branch 0 taken
                     2236: branch 1 taken
                        1: branch 3 taken
                     2235: branch 4 taken
                        1: branch 6 taken
                        1: branch 7 taken
     140             2236:   delete TheTargetAttributesSema;
                        0: branch 22 not taken
                        0: branch 23 not taken
                        0: branch 47 not taken
                     2236: branch 48 taken
                        0: branch 72 not taken
                        0: branch 73 not taken
     141             2236: }
     142                 : 
     143                 : /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
     144                 : /// If there is already an implicit cast, merge into the existing one.
     145                 : /// If isLvalue, the result of the cast is an lvalue.
     146                 : void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
     147            26732:                              CastExpr::CastKind Kind, bool isLvalue) {
     148            26732:   QualType ExprTy = Context.getCanonicalType(Expr->getType());
     149            26732:   QualType TypeTy = Context.getCanonicalType(Ty);
     150                 : 
                     6511: branch 1 taken
                    20221: branch 2 taken
     151            26732:   if (ExprTy == TypeTy)
     152             6511:     return;
     153                 : 
                     1968: branch 3 taken
                    18253: branch 4 taken
                     1749: branch 7 taken
                      219: branch 8 taken
                     1749: branch 9 taken
                    18472: branch 10 taken
     154            20221:   if (Expr->getType()->isPointerType() && Ty->isPointerType()) {
     155             1749:     QualType ExprBaseType = cast<PointerType>(ExprTy)->getPointeeType();
     156             1749:     QualType BaseType = cast<PointerType>(TypeTy)->getPointeeType();
                        3: branch 2 taken
                     1746: branch 3 taken
     157             1749:     if (ExprBaseType.getAddressSpace() != BaseType.getAddressSpace()) {
     158                 :       Diag(Expr->getExprLoc(), diag::err_implicit_pointer_address_space_cast)
     159                3:         << Expr->getSourceRange();
     160                 :     }
     161                 :   }
     162                 : 
     163            20221:   CheckImplicitConversion(Expr, Ty);
     164                 : 
                      857: branch 1 taken
                    19364: branch 2 taken
     165            20221:   if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr)) {
                        0: branch 1 not taken
                      857: branch 2 taken
     166              857:     if (ImpCast->getCastKind() == Kind) {
     167                0:       ImpCast->setType(Ty);
     168                0:       ImpCast->setLvalueCast(isLvalue);
     169                0:       return;
     170                 :     }
     171                 :   }
     172                 : 
                    20221: branch 1 taken
                        0: branch 2 not taken
     173            20221:   Expr = new (Context) ImplicitCastExpr(Ty, Kind, Expr, isLvalue);
     174                 : }
     175                 : 
     176             2025: void Sema::DeleteExpr(ExprTy *E) {
                     2025: branch 0 taken
                        0: branch 1 not taken
     177             2025:   if (E) static_cast<Expr*>(E)->Destroy(Context);
     178             2025: }
     179              133: void Sema::DeleteStmt(StmtTy *S) {
                      133: branch 0 taken
                        0: branch 1 not taken
     180              133:   if (S) static_cast<Stmt*>(S)->Destroy(Context);
     181              133: }
     182                 : 
     183                 : /// ActOnEndOfTranslationUnit - This is called at the very end of the
     184                 : /// translation unit when EOF is reached and all but the top-level scope is
     185                 : /// popped.
     186             2325: void Sema::ActOnEndOfTranslationUnit() {
     187                 :   
     188               89:   while (1) {
     189                 :     // C++: Perform implicit template instantiations.
     190                 :     //
     191                 :     // FIXME: When we perform these implicit instantiations, we do not carefully
     192                 :     // keep track of the point of instantiation (C++ [temp.point]). This means
     193                 :     // that name lookup that occurs within the template instantiation will
     194                 :     // always happen at the end of the translation unit, so it will find
     195                 :     // some names that should not be found. Although this is common behavior
     196                 :     // for C++ compilers, it is technically wrong. In the future, we either need
     197                 :     // to be able to filter the results of name lookup or we need to perform
     198                 :     // template instantiations earlier.
     199             2325:     PerformPendingImplicitInstantiations();
     200                 :     
     201                 :     /// If ProcessPendingClassesWithUnmarkedVirtualMembers ends up marking 
     202                 :     /// any virtual member functions it might lead to more pending template
     203                 :     /// instantiations, which is why we need to loop here.
                       89: branch 1 taken
                     2236: branch 2 taken
     204             2325:     if (!ProcessPendingClassesWithUnmarkedVirtualMembers())
     205             2236:       break;
     206                 :   }
     207                 :   
     208                 :   // Check for #pragma weak identifiers that were never declared
     209                 :   // FIXME: This will cause diagnostics to be emitted in a non-determinstic
     210                 :   // order!  Iterating over a densemap like this is bad.
                       15: branch 3 taken
                     2236: branch 4 taken
     211             2251:   for (llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator
     212             2236:        I = WeakUndeclaredIdentifiers.begin(),
     213             2236:        E = WeakUndeclaredIdentifiers.end(); I != E; ++I) {
                        5: branch 2 taken
                       10: branch 3 taken
     214               15:     if (I->second.getUsed()) continue;
     215                 : 
     216                 :     Diag(I->second.getLocation(), diag::warn_weak_identifier_undeclared)
     217                5:       << I->first;
     218                 :   }
     219                 : 
                       44: branch 0 taken
                     2192: branch 1 taken
     220             2236:   if (!CompleteTranslationUnit)
     221               44:     return;
     222                 : 
     223                 :   // C99 6.9.2p2:
     224                 :   //   A declaration of an identifier for an object that has file
     225                 :   //   scope without an initializer, and without a storage-class
     226                 :   //   specifier or with the storage-class specifier static,
     227                 :   //   constitutes a tentative definition. If a translation unit
     228                 :   //   contains one or more tentative definitions for an identifier,
     229                 :   //   and the translation unit contains no external definition for
     230                 :   //   that identifier, then the behavior is exactly as if the
     231                 :   //   translation unit contains a file scope declaration of that
     232                 :   //   identifier, with the composite type as of the end of the
     233                 :   //   translation unit, with an initializer equal to 0.
     234             2192:   llvm::SmallSet<VarDecl *, 32> Seen;
                      855: branch 1 taken
                     2192: branch 2 taken
     235             3047:   for (unsigned i = 0, e = TentativeDefinitions.size(); i != e; ++i) {
     236              855:     VarDecl *VD = TentativeDefinitions[i]->getActingDefinition();
     237                 : 
     238                 :     // If the tentative definition was completed, getActingDefinition() returns
     239                 :     // null. If we've already seen this variable before, insert()'s second
     240                 :     // return value is false.
                      835: branch 0 taken
                       20: branch 1 taken
                      835: branch 3 taken
                        0: branch 4 not taken
                       63: branch 6 taken
                      772: branch 7 taken
                       83: branch 8 taken
                      772: branch 9 taken
     241              855:     if (VD == 0 || VD->isInvalidDecl() || !Seen.insert(VD))
     242               83:       continue;
     243                 : 
                        9: branch 0 taken
                      763: branch 1 taken
     244              772:     if (const IncompleteArrayType *ArrayT
     245              772:         = Context.getAsIncompleteArrayType(VD->getType())) {
                        0: branch 10 not taken
                        9: branch 11 taken
     246                9:       if (RequireCompleteType(VD->getLocation(),
     247                 :                               ArrayT->getElementType(),
     248                 :                               diag::err_tentative_def_incomplete_type_arr)) {
     249                0:         VD->setInvalidDecl();
     250                0:         continue;
     251                 :       }
     252                 : 
     253                 :       // Set the length of the array to 1 (C99 6.9.2p5).
     254                9:       Diag(VD->getLocation(), diag::warn_tentative_incomplete_array);
     255                9:       llvm::APInt One(Context.getTypeSize(Context.getSizeType()), true);
     256                 :       QualType T = Context.getConstantArrayType(ArrayT->getElementType(),
     257                9:                                                 One, ArrayType::Normal, 0);
     258                9:       VD->setType(T);
                        4: branch 10 taken
                      759: branch 11 taken
     259              763:     } else if (RequireCompleteType(VD->getLocation(), VD->getType(),
     260                 :                                    diag::err_tentative_def_incomplete_type))
     261                4:       VD->setInvalidDecl();
     262                 : 
     263                 :     // Notify the consumer that we've completed a tentative definition.
                      768: branch 1 taken
                        4: branch 2 taken
     264              772:     if (!VD->isInvalidDecl())
     265              768:       Consumer.CompleteTentativeDefinition(VD);
     266                 : 
     267             2192:   }
     268                 : }
     269                 : 
     270                 : 
     271                 : //===----------------------------------------------------------------------===//
     272                 : // Helper functions.
     273                 : //===----------------------------------------------------------------------===//
     274                 : 
     275            58605: DeclContext *Sema::getFunctionLevelDeclContext() {
     276            58605:   DeclContext *DC = CurContext;
     277                 : 
                      409: branch 1 taken
                    58605: branch 2 taken
     278           117619:   while (isa<BlockDecl>(DC))
     279              409:     DC = DC->getParent();
     280                 : 
     281            58605:   return DC;
     282                 : }
     283                 : 
     284                 : /// getCurFunctionDecl - If inside of a function body, this returns a pointer
     285                 : /// to the function decl for the function being parsed.  If we're currently
     286                 : /// in a 'block', this returns the containing context.
     287            20617: FunctionDecl *Sema::getCurFunctionDecl() {
     288            20617:   DeclContext *DC = getFunctionLevelDeclContext();
     289            20617:   return dyn_cast<FunctionDecl>(DC);
     290                 : }
     291                 : 
     292            37393: ObjCMethodDecl *Sema::getCurMethodDecl() {
     293            37393:   DeclContext *DC = getFunctionLevelDeclContext();
     294            37393:   return dyn_cast<ObjCMethodDecl>(DC);
     295                 : }
     296                 : 
     297              595: NamedDecl *Sema::getCurFunctionOrMethodDecl() {
     298              595:   DeclContext *DC = getFunctionLevelDeclContext();
                      547: branch 1 taken
                       48: branch 2 taken
                      508: branch 4 taken
                       39: branch 5 taken
                      556: branch 6 taken
                       39: branch 7 taken
     299              595:   if (isa<ObjCMethodDecl>(DC) || isa<FunctionDecl>(DC))
     300              556:     return cast<NamedDecl>(DC);
     301               39:   return 0;
     302                 : }
     303                 : 
     304            15680: Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
                     9455: branch 1 taken
                     6225: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
     305            15680:   if (!this->Emit())
     306             9455:     return;
     307                 : 
     308                 :   // If this is not a note, and we're in a template instantiation
     309                 :   // that is different from the last template instantiation where
     310                 :   // we emitted an error, print a template instantiation
     311                 :   // backtrace.
                     4535: branch 1 taken
                     1690: branch 2 taken
                      231: branch 4 taken
                     4304: branch 5 taken
                      217: branch 8 taken
                       14: branch 9 taken
                      217: branch 10 taken
                     6008: branch 11 taken
                        0: branch 13 not taken
                        0: branch 14 not taken
                        0: branch 16 not taken
                        0: branch 17 not taken
                        0: branch 20 not taken
                        0: branch 21 not taken
                        0: branch 22 not taken
                        0: branch 23 not taken
     312             6225:   if (!SemaRef.Diags.isBuiltinNote(DiagID) &&
     313                 :       !SemaRef.ActiveTemplateInstantiations.empty() &&
     314                 :       SemaRef.ActiveTemplateInstantiations.back()
     315                 :         != SemaRef.LastTemplateInstantiationErrorContext) {
     316              217:     SemaRef.PrintInstantiationStack();
     317                 :     SemaRef.LastTemplateInstantiationErrorContext
     318              217:       = SemaRef.ActiveTemplateInstantiations.back();
     319                 :   }
                     6225: branch 1 taken
                     9455: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
     320            31360: }
     321                 : 
     322                 : Sema::SemaDiagnosticBuilder
     323              367: Sema::Diag(SourceLocation Loc, const PartialDiagnostic& PD) {
     324              367:   SemaDiagnosticBuilder Builder(Diag(Loc, PD.getDiagID()));
     325              367:   PD.Emit(Builder);
     326                 : 
     327                 :   return Builder;
     328                 : }
     329                 : 
     330            28168: void Sema::ActOnComment(SourceRange Comment) {
     331            28168:   Context.Comments.push_back(Comment);
     332            28168: }
     333                 : 

Generated: 2010-02-10 01:31 by zcov